2016-07-17 8 views
1

DataGridにはAutoGeneratedColumns = trueがあります。 プロパティの一部がenumであるため、対応する列はDatagridComboBoxColumnです。次のように 列挙型の定義は、説明属性を持っている:WPF DatagridComboBoxColumn displaymemberpath description属性

public class EnumToItemsSource : MarkupExtension 
{ 
    private readonly Type _type; 

    public EnumToItemsSource(Type type) 
    { 
     _type = type; 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return Enum.GetValues(_type).Cast<object>().Select(e => new { Value = e, 
      Description = GetEnumDescription((Enum)e) }); 
    } 

    public static string GetEnumDescription(Enum enumObj) 
    { 
     FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString()); 
     object[] attributes = fieldInfo.GetCustomAttributes(false); 
     if (attributes.Length == 0) 
      return enumObj.ToString(); 
     else 
     { 
      DescriptionAttribute attrib = attributes.OfType<DescriptionAttribute>().FirstOrDefault(); 
      if (attrib != null) 
       return attrib.Description; 
      else 
       return "No description"; 
     } 
    } 
} 

そして、次のように私は、XAMLでそれを使用します:

public enum MyEnum 
{ 
    [Description("first")] 
    FirstEnum, 

    [Description("second")] 
    SecondEnum 
} 

は、私はすでに説明を表示するためのユーティリティメソッドがコンボボックスに属性を持っている

<ComboBox ItemsSource="{utils:EnumToItemsSource {x:Type myenums:MyEnum}}" 
           DisplayMemberPath="Description" 
           SelectedValuePath="Value" 
           SelectedValue="{Binding SomeProperty}"/> 

私の質問は、これを自動生成列にどのように適用できますか?そのために

private void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
    { 
     DataGridComboBoxColumn col = e.Column as DataGridComboBoxColumn; 
     if (col != null) 
     { 
      col.ItemsSource = EnumToIEnumerable.GetIEnumerable(e.PropertyType); 
      col.DisplayMemberPath = "Value"; 
      col.SelectedValuePath = "Key"; 
      col.SelectedValueBinding = new Binding(e.PropertyName); 
     } 
    } 

、私が提供する新しいヘルパーの静的メソッドを記述する必要がありました:

EDITまず私はAutoGeneratingColumnイベントハンドラでそれを実行して最初のソリューションを試してきました

をしてみてくださいコンボボックスのソースのリスト:

public static class EnumToIEnumerable 
{ 
    public static IEnumerable<KeyValuePair<Enum, string>> GetIEnumrable(Type type) 
    { 
     return Enum.GetValues(type).Cast<Enum>().Select((e) => new KeyValuePair<Enum, string>(e, 
      EnumDescriptionConverter.GetEnumDescription((Enum)e))); 
    } 
} 

説明を表示するために機能しています。しかし、プログラムはSelectedValueをバウンドプロパティに変換できません。サイレント例外がスローされ、コンボボックスは赤色になっています。私は英語でエラーメッセージを翻訳してみてください

:SelectedValuePathは、列挙型のオブジェクトが含まれており、SelectedValueBindingはそれを結合するので

Conversion of EnumConverter is not possible from System.Collections.Generic.KeyValuePair 
System.Windows.Data Error: 7 : ConvertBack cannot convert value '[Surface, m²]' (type 'KeyValuePair`2'). BindingExpression:Path=TypeQuantite; DataItem='MscaGridLineViewModel' (HashCode=39414053); target element is 'TextBlockComboBox' (Name=''); target property is 'SelectedItem' (type 'Object') NotSupportedException:'System.NotSupportedException: Conversion de EnumConverter impossible à partir de System.Collections.Generic.KeyValuePair`2[[System.Enum, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]. 

それはtargetプロパティを書かれている理由を私は理解していないが「のSelectedItem」です列挙型である "MyEnum"型のプロパティ。

答えて

1

答え:私だけの行を追加する必要がありましたcol.SelectedItemBinding = null;

private void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
{ 
    DataGridComboBoxColumn col = e.Column as DataGridComboBoxColumn; 
    if (col != null) 
    { 
     col.ItemsSource = EnumToIEnumerable.GetIEnumerable(e.PropertyType); 
     col.DisplayMemberPath = "Value"; 
     col.SelectedValuePath = "Key"; 
     col.SelectedValueBinding = new Binding(e.PropertyName); 
     col.SelectedItemBinding = null; 
    } 
} 
関連する問題