在WPF DataGrid中的枚举值说明属性与的AutoGenerateColumns(Descri

2019-10-23 01:54发布

这里是我的枚举:

enum Foo 
{
    [Description("the quick")]
    Bar,
    [Description("brown fox")]
    Baz,
    [Description("jumped over")]
    Qux
}

这里是我的视图模型的一部分:

class MainWindowViewModel : ViewModelBase
{
    public ObservableCollection<RowViewModel> Rows { get { ... } }
}

class RowViewModel : ViewModelBase 
{
    public String Name { get { ... } set { ... } }
    public Foo Foo { get { ... } set { ... } }
}

这是我的XAML:

<DataGrid AutoGeneratingColumn="OnAutoGeneratingColumn" ItemsSource="{Binding Path=Rows}" />

因为MainWindowViewModel.Rows[n].Foo是一个枚举,WPF会自动生成一个DataGridComboBoxColumn用enum成员组合框下拉值,到目前为止好。

我想组合框以使用[Description("")]的值在组合框下拉和显示。 所以,我实现了一个IValueConverter 。 然后,我增加了一个处理程序OnAutoGeneratingColumn

private void OnAutoGeneratingColumn(Object sender, DataGridAutoGeneratingColumnEventArgs e)
{
    DataGridComboBoxColumn dgCol = e.Column as DataGridComboBoxColumn;
    if( dgCol != null && e.PropertyType.IsEnum ) {

        Binding binding = new Binding( e.PropertyName );
        binding.Converter = EnumDescriptionValueConverter.Instance;

        dgCol.TextBinding = binding;
        dgCol.SelectedItemBinding = binding;
    }
}

不幸的是这不起作用:单元格显示为空时,他们有价值观和组合框下拉菜单包含原始枚举值,而不是描述。

Answer 1:

你工作太辛苦要做到这一点,因为枚举不是一个多变的项目,虚拟机在施工期间枚举枚举,并提取描述成一个列表,然后将控件绑定到该列表。


就拿我们的枚举

public enum TheNums
{
    [Description("One")]
    Alpha,
    [Description("Two")]
    Beta,
    [Description("Three")]
    Gamma
}

扩展方法,以提取描述

public static class AttributeExtension
{

/// <summary>If an attribute on an enumeration exists, this will return that 
/// information</summary> 
/// <param name="value">The object which has the attribute.</param> 
/// <returns>The description string of the attribute or string.empty</returns> 
public static string GetAttributeDescription(this object value)
{
    string retVal = string.Empty;
    try
    {
        retVal = value.GetType()
                      .GetField(value.ToString())
                      .GetCustomAttributes(typeof(DescriptionAttribute), false)
                      .OfType<DescriptionAttribute>()
                      .First()
                      .Description;

    }
    catch (NullReferenceException)
    {
        //Occurs when we attempt to get description of an enum value that does not exist 
    }
    finally
    {
        if (string.IsNullOrEmpty(retVal))
            retVal = "Unknown";
    }

    return retVal;
}

}

我们的字符串列表的创建List<string> EnumDescriptions { get; set; } List<string> EnumDescriptions { get; set; } List<string> EnumDescriptions { get; set; }

EnumDescriptions = new List<string>()
{
    TheNums.Alpha.GetAttributeDescription(),
    TheNums.Beta.GetAttributeDescription(),
    TheNums.Gamma.GetAttributeDescription()
};

为了简便起见,我将它添加到页面的DataContext的,所以我没有路径进入名单所列EnumDescriptions

public List<string> EnumDescriptions { get; set; }
public MainWindow()
{
    InitializeComponent();
    EnumDescriptions = new List<string>()
    {
        TheNums.Alpha.GetAttributeDescription(),
        TheNums.Beta.GetAttributeDescription(),
        TheNums.Gamma.GetAttributeDescription()
    };

    DataContext = EnumDescriptions;
}

然后我的网页上,我会绑定到它直接,因为列表框inheirits页面的的datacontext这 EnumDescriptions

<ListBox ItemsSource="{Binding}" Width="100" Height="200"/>

其结果是:

需要注意的是在MVVM实施,极有可能是整个虚拟机实例将是页面的数据上下文,所以绑定需要知道属性名(其结合path )关闭数据上下文/虚拟机实例的,所以使用Binding EnumDescriptionsBinding Path=EnumDescriptions



文章来源: Description attribute on enum values in WPF DataGrid with AutoGenerateColumns