2016-07-17 10 views
1

DataGrid hat AutoGeneratedColumns = true. Einige der Eigenschaften sind enum, so dass die entsprechenden Spalten DatagridComboBoxColumn sind. Enum-Definitionen haben eine Beschreibung Attribut wie folgt:WPF DatagridComboBoxColumn displaymemberpath Beschreibungsattribut

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

    [Description("second")] 
    SecondEnum 
} 

ich bereits ein Dienstprogramm Methode haben Beschreibung angezeigt werden Attribute in einem ComboBox:

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"; 
     } 
    } 
} 

Und ich es in XAML verwenden wie folgt:

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

Jetzt ist meine Frage, wie kann ich dies auf eine automatisch generierte Spalte anwenden?

EDIT Zuerst versuchen

Ich versuche, habe eine erste Lösung, indem sie es in den AutoGeneratingColumn Event-Handler zu tun:

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); 
     } 
    } 

Dafür habe ich eine neue Helfer statische Methode schreiben musste bereitzustellen die Liste für die Combobox-Elemente Quelle:

Es funktioniert für die Anzeige der Beschreibung. Das Programm kann SelectedValue jedoch nicht in die gebundene Eigenschaft konvertieren. Es gibt stille Ausnahmen und die Combobox ist rot umrandet.

Ich versuche, die Fehlermeldung in Englisch zu übersetzen:

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]]. 

Ich verstehe nicht, warum es Zieleigenschaft geschrieben ist ‚SelectedItem‘ weil die SelectedValuePath ein Objekt Enum enthält und das SelectedValueBinding bindet es an Eine Eigenschaft vom Typ "MyEnum", die eine Aufzählung ist.

Antwort

1

Die Antwort: Ich hatte nur die Linie 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; 
    } 
} 
hinzufügen