我有一个Poco
类,其中一个属性是枚举类型
为了使枚举属性可以在UI层(WPF)上进行本地化,我为枚举类型创建了一个TypeConverter
,它查找了本地化的枚举值。
此POCO类的实例列表绑定到WPF DataGrid:
// in the ViewModel:
public Pocos = CollectionViewSource.GetDefaultView( DataLayer.GetPocos() );
这非常有效。
稍后我重构了代码,以便数据层不再返回List<Poco>
但List<ExpandoObject>
:
public Pocos = CollectionViewSource.GetDefaultView( DataLayer.GetExpandos() );
这些ExpandoObjects
是数据库查询的结果,仅包含原始Poco's
属性的子集,具体取决于select语句。
一切正常,但枚举属性的TypeConverter
除外,它不再被调用。
TypeConverter仍然是公开的,因此可行:
dynamic eo = new ExpandoObject();
eo.EnumProperty = MyEnum.SomeValue;
var converter = TypeConverter.GetConverter( (eo.EnumProperty).GetType() );
var result = converter.ConvertTo( eo.EnumProperty, typeof( string ) );
我不知道WPF的DataGrid内部发生了什么。我的印象是,无论出于何种原因,它只是在枚举类型属性上调用ToString()
而不是调用TypeConverter
。
有什么方法可以让它发挥作用吗?
实施细则:
XAML:
<DataGrid x:Name="PocoGrid" x:FieldModifier="public"
Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2"
ItemsSource="{Binding Pocos}"
SelectedItem="{Binding SelectedPoco}"
bh:DataGridColumnsBehavior.BindableColumns="{Binding PocoColumns}"
IsSynchronizedWithCurrentItem="True" IsReadOnly="True" AutoGenerateColumns="False">
<DataGrid.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding PocoDoubleClick}" CommandParameter="{Binding Pocos/}"/>
</DataGrid.InputBindings>
</DataGrid>
TYPE CONVERTER:
public abstract class EnumTypeConverterBase : TypeConverter
{
public static ILocalizedResourceProvider ResourceProvider { get; set; } = null;
}
public class EnumTypeConverter<T> : EnumTypeConverterBase where T : struct, IConvertible, IComparable
{
private static string typeParameterName = typeof(T).Name;
public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType )
{
if( sourceType == typeof( string ) )
return true;
return base.CanConvertFrom( context, sourceType );
}
public override object ConvertFrom( ITypeDescriptorContext context, CultureInfo culture, object value )
{
throw new NotImplementedException();
}
public override object ConvertTo( ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType )
{
string val = value.ToString();
if( ResourceProvider == null )
return val;
else
return ResourceProvider.GetEnum( typeParameterName, val );
}
}
评论定义:
[TypeConverter( typeof( EnumTypeConverter<MyEnum> ) )]
public enum MyEnum
{
Unknown = 0,
SomeValue = 1,
SomeOtherValue = 2
}
答案 0 :(得分:0)
Use a value converter。无论如何,这是一种更常规的方法,并且它不依赖于在运行时调用的反射。
public class MyEnumLocalizationConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var e = (MyEnum)value;
var converted = "";
// Do whatever the type converter now does
return converted;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
XAML:
<Window.Resources>
<!-- ... -->
<local:MyEnumLocalizationConverter x:Key="MyEnumLocalizer" />
<!-- ... -->
</Window.Resources>
<!-- ... -->
<DataGridTextColumn
Binding="{Binding EnumProperty, Converter={StaticResource MyEnumLocalizer}}"
/>
如果你分享一些XAML,我可以告诉你