私は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
}
お見せすることができます。私はValueConvertが私の場合に有効かどうかはわかりません。実装には列挙型のduzendが含まれており、valueconverterは単一の型に固有のように見えます。ジェネリック版を定義することは可能ですか? –
@c__k型変換器を保持し、正しい型変換器を得るために反射を使用する一般的な値変換器を記述することができます。 XAMLがバインディングソースとして型指定されたプロパティを持っていたときに、以前は型コンバータを使用していたXAMLの本質です。 –
私はそれを数時間働かそうとしましたが、結局はあきらめました。問題は、列挙型が発生する可能性のある列とその名前がコンパイル時にわからないため、コンバータをすべての列にバインドしなければならないということでした。私は実行時に型を作成し、ExpandoObjectの代わりにこの型を使用しました。 –