WPF 数据网格组合框列显示成员路径说明属性

本文关键字:成员 显示 路径 说明 属性 数据 数据网 网格 组合 WPF | 更新日期: 2023-09-27 17:57:12

DataGrid 具有自动生成的列 = true。某些属性是枚举,因此相应的列是 DatagridComboBoxColumn。枚举定义具有如下描述属性:

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

我已经有一个实用程序方法来在组合框中显示描述属性:

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 中使用它如下:

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

为此,我必须编写一个新的帮助程序静态方法来提供组合框项源的列表:

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 转换为绑定属性。它抛出静默异常,组合框是红线。

我尝试将错误消息翻译成英文:

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

我不明白为什么它写入的目标属性是"SelectedItem",因为 SelectedValuePath 包含一个枚举对象,并且 SelectedValueBinding 将其绑定到类型为"MyEnum"的属性,这是一个枚举。

WPF 数据网格组合框列显示成员路径说明属性

答案:我只需要添加行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;
    }
}