这里是我的枚举:
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;
}
}
不幸的是这不起作用:单元格显示为空时,他们有价值观和组合框下拉菜单包含原始枚举值,而不是描述。
你工作太辛苦要做到这一点,因为枚举不是一个多变的项目,虚拟机在施工期间枚举枚举,并提取描述成一个列表,然后将控件绑定到该列表。
例
就拿我们的枚举
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 EnumDescriptions
或Binding Path=EnumDescriptions
。
文章来源: Description attribute on enum values in WPF DataGrid with AutoGenerateColumns