2017-06-07 8 views
1

私はPocoクラスを持っていますが、1つのプロパティは列挙型です。
UIレイヤー(WPF)で列挙プロパティをローカライズ可能にするために、ローカライズされた列挙値を参照する列挙型のためにTypeConverterを作成しました。TypeConverterはExpandoObjectとDataGridで動作しません

// in the ViewModel: 
public Pocos = CollectionViewSource.GetDefaultView(DataLayer.GetPocos()); 

完全によく働いた:このPOCOクラスのインスタンスの リストは、WPFのデータグリッドにバインドされています。

public Pocos = CollectionViewSource.GetDefaultView(DataLayer.GetExpandos()); 

これらExpandoObjectsは、データベースクエリの結果であるとに応じて、オリジナルPoco's特性のサブセットのみを含む:データ層がもはやList<Poco>しかしList<ExpandoObject>返すよう

後、私は、コードリファクタリングありません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のデータグリッド内で何が起こっているのか分かりません。私はそれが何らかの理由でTypeConverterを呼び出すのではなく、単に列挙型プロパティのToString()を呼び出しているという印象を受けています。

これを行うにはどんな方法がありますか?

実装の詳細:

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> 

型コンバータ:

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

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を共有している場合、私はXAMLを含め、いくつかの実装の詳細を追加

+0

お見せすることができます。私はValueConvertが私の場合に有効かどうかはわかりません。実装には列挙型のduzendが含まれており、valueconverterは単一の型に固有のように見えます。ジェネリック版を定義することは可能ですか? –

+0

@c__k型変換器を保持し、正しい型変換器を得るために反射を使用する一般的な値変換器を記述することができます。 XAMLがバインディングソースとして型指定されたプロパティを持っていたときに、以前は型コンバータを使用していたXAMLの本質です。 –

+1

私はそれを数時間働かそうとしましたが、結局はあきらめました。問題は、列挙型が発生する可能性のある列とその名前がコンパイル時にわからないため、コンバータをすべての列にバインドしなければならないということでした。私は実行時に型を作成し、ExpandoObjectの代わりにこの型を使用しました。 –

関連する問題