这是我的枚举:
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;
}
}
不幸的是,这不起作用:当单元格有值时,单元格显示为空,组合框下拉列表包含原始枚举值而不是描述。
答案 0 :(得分: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<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;
}
然后在我的页面上,我将直接绑定它,因为Listbox会检测页面的 EnumDescriptions
的datacontext。
<ListBox ItemsSource="{Binding}" Width="100" Height="200"/>
结果是:
请注意,在MVVM实现中,整个VM实例很可能是页面的数据上下文,因此绑定需要知道数据上下文的属性名称(其绑定path
) / VM实例,因此请使用Binding EnumDescriptions
或Binding Path=EnumDescriptions
。