>您不能使用接受类型参数的通用EnumDisplayer
样式IValueConverter,因为Silverlight不支持x:Type。
>您不能使用ObjectDataProvider,如在this approach,因为它不存在于Silverlight中。
>您不能使用自定义标记扩展,如#2中的链接的注释,因为在Silverlight中不存在标记扩展。
>你不能做一个版本的#1使用泛型而不是对象的类型属性,因为XAML不支持泛型(和使它们工作的所有依赖于标记扩展,不支持在Silverlight)。
大规模失败!
正如我看到的,使这项工作的唯一方法是
>欺骗并绑定到我的viewmodel中的字符串属性,其setter / getter执行转换,使用代码隐藏在View中将值加载到ComboBox中。
>为要绑定的每个枚举创建一个自定义IValueConverter。
有没有更通用的替代方法,即不涉及为每个我想要的枚举重复编写相同的代码?我想我可以做解决方案#2使用一个类接受枚举作为一个类型参数,然后为我想要的每个枚举创建新类,只是
class MyEnumConverter : GenericEnumConverter<MyEnum> {}
你的想法是什么,伙计们?
解决方法
基本上,你需要一个单一的转换器为ItemsSource属性,但它可以是完全通用的,而不使用任何禁止的方法,只要你传递一个类型为MyEnum的属性的名称。和SelectedItem的数据绑定是完全无痛的;无需转换器!好吧,至少它只要你不想要自定义字符串为每个枚举值通过例如。 DescriptionAttribute,hmm …可能需要另一个转换器;希望我可以使它泛型。
更新:我做了一个转换器,它的工作原理!我现在必须绑定到Selectedindex,可惜,但它的确定。使用这些家伙:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Windows.Data; namespace DomenicDenicola.Wpf { public class EnumToIntConverter : IValueConverter { public object Convert(object value,Type targettype,object parameter,System.Globalization.CultureInfo culture) { // Note: as pointed out by Martin in the comments on this answer,this line // depends on the enum values being sequentially ordered from 0 onward,// since comboBox indices are done that way. A more general solution would // probably look up where in the GetValues array our value variable // appears,then return that index. return (int)value; } public object ConvertBack(object value,System.Globalization.CultureInfo culture) { return Enum.Parse(targettype,value.ToString(),true); } } public class EnumToIEnumerableConverter : IValueConverter { private Dictionary<Type,List<object>> cache = new Dictionary<Type,List<object>>(); public object Convert(object value,System.Globalization.CultureInfo culture) { var type = value.GetType(); if (!this.cache.ContainsKey(type)) { var fields = type.GetFields().Where(field => field.IsLiteral); var values = new List<object>(); foreach (var field in fields) { DescriptionAttribute[] a = (DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute),false); if (a != null && a.Length > 0) { values.Add(a[0].Description); } else { values.Add(field.GetValue(value)); } } this.cache[type] = values; } return this.cache[type]; } public object ConvertBack(object value,System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } }
有了这种绑定XAML:
<ComboBox x:Name="MonsterGroupRole" ItemsSource="{Binding MonsterGroupRole,Mode=OneTime,Converter={StaticResource EnumToIEnumerableConverter}}" Selectedindex="{Binding MonsterGroupRole,Mode=TwoWay,Converter={StaticResource EnumToIntConverter}}" />
而这种资源声明XAML:
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ddwpf="clr-namespace:DomenicDenicola.Wpf"> <Application.Resources> <ddwpf:EnumToIEnumerableConverter x:Key="EnumToIEnumerableConverter" /> <ddwpf:EnumToIntConverter x:Key="EnumToIntConverter" /> </Application.Resources> </Application>
任何意见将不胜感激,因为我有点像XAML / Silverlight / WPF / etc。新手。例如,EnumToIntConverter.ConvertBack会变慢,那么我应该考虑使用缓存吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。