【问题标题】:Description attribute on enum values in WPF DataGrid with AutoGenerateColumns带有 AutoGenerateColumns 的 WPF DataGrid 中枚举值的描述​​属性
【发布时间】:2015-07-20 17:48:15
【问题描述】:

这是我的枚举:

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

这是我的 ViewModel 的一部分:

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,其中枚举成员作为组合框下拉值,到目前为止一切顺利。

我希望组合框使用组合框下拉列表中的[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;
    }
}

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

【问题讨论】:

    标签: wpf mvvm binding datagrid combobox


    【解决方案1】:

    由于枚举不是可更改的项目,因此您太努力了,因此在 VM 构建期间枚举枚举并将描述提取到列表中,然后将控件绑定到该列表。


    示例

    获取我们的枚举

    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&lt;string&gt; EnumDescriptions { get; set; }

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

    为了简单起见,我将把它添加到页面的数据上下文中,这样我就不必将 path 放入名为 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;
    }
    

    然后在我的页面上我将直接绑定到它,因为 Listbox 继承了页面的数据上下文,EnumDescriptions

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

    结果是:

    请注意,在 MVVM 实现中,整个 VM 实例很可能是页面的数据上下文,因此绑定需要知道数据上下文/ VM 实例之外的属性名称(其绑定 path),所以使用Binding EnumDescriptionsBinding Path=EnumDescriptions

    【讨论】:

    • 那么如何将控件绑定到列表呢?
    • @Dai 正常绑定它。请参阅提供的快速示例。
    • 感谢您的示例 - 您可以使用动态创建的 CheckBox DataGrid 列针对我的原始场景进行修改吗?
    • @Dai 我有自己的最后期限,必须先完成,但是,我没有看到你正在做的事情的设计,所以我给你的机会 wrong 事情是相当高的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多