概述
本文讲述下拉框和枚举类型进行绑定的一些操作。
下拉框的基本操作
设计部分:
<ComboBox ItemsSource="{Binding Fruits}"
SelectedItem="{Binding SelectedFruit}"
SelectedIndex="{Binding SelectedIndex}"/>
代码部分:
public List<string> Fruits { get; set; } = new List<string> { "Apple","Bonana", "Strawberry" };
public string SelectedFruit { get; set; }
public int SelectedIndex { get; set; }
以上是最简单的一种绑定形式,采用字符串列表作为数据源。虽然SelectedItem和SelectedIndex都可以用来控制或获取选择项,但建议还是使用SelectedItem比较合适,因为下拉框的数据是可以绑定任意对象列表的,通过SelectedItem就可以直接获取到对象。注意用于绑定的对象应重写ToString()方法。
下拉框绑定枚举类型
首先我们定义一个枚举类型
public enum AlarmLevel
{
Normal = 0,
Warring = 1,
Error = 2,
}
然后定义要绑定的源:
public List<AlarmLevel> Fruits { get; set; } = new List<AlarmLevel> { AlarmLevel.Normal, AlarmLevel.Warring, AlarmLevel.Error };
public AlarmLevel SelectedFruit { get; set; }
设计端代码:
<ComboBox ItemsSource="{Binding Fruits}"
SelectedItem="{Binding SelectedFruit}"/>
这样就实现绑定了。但初始化枚举对象列表的代码有点麻烦,我们需要优化一下。
新建一个辅助类
public class EnumHelper<T>
{
public static List<T> ToList()
{
return Enum.GetValues(typeof(T)).Cast<T>().ToList();
}
}
初始化代码就可以简化为下面形式:
public List<AlarmLevel> Fruits = EnumHelper<AlarmLevel>.ToList();
这个代码对所有枚举类型都适用。
下拉框中文字显示枚举的描述信息
有时候我们希望下拉框显示的内容和枚举项的定义名称并不一致,比如定义项为“Normal”,界面显示“正常”,这个要求也是可以实现的。下面代码实现界面显示枚举项的Description值。
定义枚举类对象,如下:
public enum AlarmLevel
{
[Description("正常")]
Normal = 0,
[Description("警报")]
Warring = 1,
[Description("故障")]
Error = 2,
}
ViewModel中代码不变,我们要增加一个转换器来实现这个功能
public class EnumDescriptionConverter : IValueConverter
{
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Enum myEnum = (Enum)value;
string description = GetEnumDescription(myEnum);
return description;
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Empty;
}
private string GetEnumDescription(Enum enumObj)
{
FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
object[] attribArray = fieldInfo.GetCustomAttributes(false);
if (attribArray.Length == 0)
{
return enumObj.ToString();
}
else
{
DescriptionAttribute attrib = attribArray[0] as DescriptionAttribute;
return attrib.Description;
}
}
}
View Code前端代码修改如下:
<UserControl x:Class="LearnWPF.Pages.PageComboBoxView"
xmlns:util="clr-namespace:LearnWPF.Utils">
<UserControl.Resources>
<util:EnumDescriptionConverter x:Key="enumDescriptionConverter" />
</UserControl.Resources>
<Canvas>
<ComboBox ItemsSource="{Binding AlarmLevelList}"
SelectedItem="{Binding SelectedAlarmLevel}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource enumDescriptionConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Canvas>
</UserControl>
这里稍微分析一下转换器。
这里的转换器必须继承于IValueConverter接口,它有Convert和ConvertBack两个方法。以Convert为例,其输入是一个object,来源是ItemTemplate模板的当前对象,输出也是一个对象,ItemTemplate会用输出的对象代替原来的对象。
自定义的输出的对象应重写ToString()方法。
以上转换器的设计是将枚举对象转换为其Description特性,实际应用时可能需要考虑国际化的需求,其转换数据的来源也不一定要从Description取值,完全可以根据需要另行设计。
资源
系列目录:WPF开发快速入门【0】前言与目录
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD