我正在使用WPF DataGrid
控件的列自动生成功能。它的一个列是一个选择列 - 基于一些枚举。
枚举看起来像这样:
public enum MyTypes {
Integer = 1,
Float = 2
IntegerArray = 3,
FloatArray = 4
}
我想将array
类型显示为不是IntegerArray,FloatArray,而是显示为Integer [],
在自动生成的下拉列表中浮动[]。
换句话说 - 单元格将包含一个下拉列表,其值为Integer,Float,IntegerArray,FloatArray,我希望它们是Integer,Float,Integer [],Float []。显然,我无法在MyTypes声明中将IntegerArray更改为Integer []。
我该怎么做?
修改
下面的Pushpray的答案只能部分起作用 - 我得到枚举字段描述(所以不是在ComboBox
中使用FloatArr我得到Float [],而是在保持{{{ 1}}失去焦点,然后我得到ComboBox
。
答案 0 :(得分:4)
以下是我提供解决问题的方法
结果
我们首先将所需的值定义为枚举值
的Description
属性
public enum MyTypes
{
Integer = 1,
Float = 2,
[Description("Integer[]")]
IntegerArray = 3,
[Description("Float[]")]
FloatArray = 4
}
然后使用一种方法创建一个类,该方法枚举枚举类型中的列表,如果应用了将描述属性考虑在内
namespace CSharpWPF
{
public class EnumHelper
{
public static IEnumerable<string> GetEnumDescriptions(Type enumType)
{
foreach (var item in Enum.GetNames(enumType))
{
FieldInfo fi = enumType.GetField(item);
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
yield return attributes[0].Description;
else
yield return item;
}
}
}
}
最后使用ObjectDataProvider
在类GetEnumDescriptions
中使用枚举器方法EnumHelper
,并使用与DataGridComboBoxColumn
的ItemsSource
示例xaml
<DataGrid xmlns:l="clr-namespace:CSharpWPF">
<DataGrid.Columns>
<DataGridComboBoxColumn Header="EnumValues" >
<DataGridComboBoxColumn.ItemsSource>
<Binding>
<Binding.Source>
<ObjectDataProvider MethodName="GetEnumDescriptions"
ObjectType="{x:Type l:EnumHelper}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="l:MyTypes" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Binding.Source>
</Binding>
</DataGridComboBoxColumn.ItemsSource>
</DataGridComboBoxColumn>
</DataGrid.Columns>
</DataGrid>
使用自动生成列
<DataGrid x:Name="dGrid"
AutoGenerateColumns="True"
AutoGeneratingColumn="DataGrid_OnAutoGeneratingColumn"
xmlns:l="clr-namespace:CSharpWPF">
<DataGrid.Resources>
<l:EnumHelper x:Key="EnumHelper" />
<ObjectDataProvider x:Key="EnumValues"
MethodName="GetEnumDescriptions"
ObjectType="{x:Type l:EnumHelper}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="l:MyTypes" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<DataTemplate x:Key="MyTypesCellTemplate">
<TextBlock Text="{Binding EnumValue, Converter={StaticResource EnumHelper}}"/>
</DataTemplate>
<DataTemplate x:Key="MyTypesCellEditingTemplate">
<ComboBox SelectedItem="{Binding EnumValue, Converter={StaticResource EnumHelper}}"
ItemsSource="{Binding Source={StaticResource EnumValues}}" />
</DataTemplate>
</DataGrid.Resources>
</DataGrid>
事件处理程序
private void DataGrid_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyType == typeof(MyTypes))
{
DataGridTemplateColumn templateColumn = new DataGridTemplateColumn();
templateColumn.Header = e.Column.Header;
templateColumn.CellTemplate = (DataTemplate)dGrid.Resources["MyTypesCellTemplate"];
templateColumn.CellEditingTemplate = (DataTemplate)dGrid.Resources["MyTypesCellEditingTemplate"];
e.Column = templateColumn;
}
}
EnumHelper类
public class EnumHelper : IValueConverter
{
public static IEnumerable<string> GetEnumDescriptions(Type enumType)
{
foreach (var item in Enum.GetNames(enumType))
{
FieldInfo fi = enumType.GetField(item);
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
yield return attributes[0].Description;
else
yield return item;
}
}
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return string.Empty;
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return MyTypes.Float;
Type enumType = typeof(MyTypes);
foreach (var item in Enum.GetNames(enumType))
{
FieldInfo fi = enumType.GetField(item);
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0 && string.Equals(attributes[0].Description, value))
return Enum.Parse(enumType, item);
}
return Enum.Parse(enumType, value.ToString());
}
}
<强>演示强>
以下是基于上述答案的工作示例代码
DataGridEnumsSample.zip(VS 2013)
MD5校验和:9C34BB81857C78375582FAC0E1C8A95D
答案 1 :(得分:0)
我有另一个解决方案,允许您使用自动生成的列在DataGrid
中显示枚举。这适用于使用反射创建的枚举类型。
首先,创建一个继承自EnumTemplateColumn
:
DataGridBoundColumn
public class EnumTemplateColumn : DataGridBoundColumn
{
private readonly Type enumType;
public EnumTemplateColumn(Type enumType)
{
this.enumType = enumType;
}
protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
string columnHeader = cell.Column.Header.ToString();
TextBlock textBlock = new TextBlock();
var dataRowView = (DataRowView) dataItem;
var enumValue = dataRowView[columnHeader];
textBlock.Text = Enum.GetName(this.enumType, enumValue);
return textBlock;
}
protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
{
throw new NotImplementedException();
}
}
接下来,使用OnAutoGeneratingColumn
的{{1}}事件来使用DataGrid
:
EnumTemplateColumn
WPF组件:
private void DataGrid_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyType.IsEnum)
{
e.Column = new EnumTemplateColumn(e.PropertyType)
{
Header = e.Column.Header,
};
}
}
答案 2 :(得分:0)
我是这样做的:在 AutoGeneratingColumn
的 DataGrid
事件中,将默认的 DataGridComboBoxColumn
替换为 DataGridTextColumn
,并手动添加绑定和转换器。< /p>
private void dataGrid1_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyType.IsEnum)
{
//(e.Column as DataGridComboBoxColumn)
var col = new DataGridTextColumn
{
Header = e.PropertyName
};
col.Binding = new Binding(e.PropertyName)
{
Converter = new WPFCommon.BindingConverters.EnumConverter()
};
// Replace the auto-generated column with the new one.
e.Column = col;
}
}
转换器类,
namespace WPFCommon.BindingConverters
{
public class EnumConverter:IValueConverter
{
//** this does not work for enum value in DataTable
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null || string.IsNullOrEmpty(value.ToString()))
return DependencyProperty.UnsetValue;
return ((Enum)value).GetDescription();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
}
}
枚举扩展类,
public static class EnumExtensions
{
public static string GetDisplayName(this Enum enu)
{
DisplayAttribute attr = GetDisplayAttribute(enu);
return attr != null ? attr.Name : enu.ToString();
}
public static string GetDescription(this Enum enu)
{
DescriptionAttribute attr = GetDescriptionAttribute(enu);
return attr != null ? attr.Description : enu.ToString();
}
private static DescriptionAttribute GetDescriptionAttribute(object value)
{
Type type = value.GetType();
if (!type.IsEnum)
{
throw new ArgumentException(string.Format("Type {0} is not an enum", type));
}
// Get the enum field.
var field = type.GetField(value.ToString());
return field == null ? null : field.GetCustomAttribute<DescriptionAttribute>();
}
private static DisplayAttribute GetDisplayAttribute(object value)
{
Type type = value.GetType();
if (!type.IsEnum)
{
throw new ArgumentException(string.Format("Type {0} is not an enum", type));
}
// Get the enum field.
var field = type.GetField(value.ToString());
return field == null ? null : field.GetCustomAttribute<DisplayAttribute>();
}
}