示例:将枚举特性绑定到 DataGridComboBoxColumn
一、定义描述特性
[AttributeUsage(AttributeTargets.All)]
public class DescriptionAttribute : Attribute
{
public string description;
public DescriptionAttribute(string desc)
{
description = desc;
}
}
二、定义枚举
//定义活动类型
public enum ActivityType
{
[Description("日常")]
Daily,
[Description("限时")]
TimeLimit,
[Description("福利")]
Welfare,
[Description("运营")]
Business
}
三、xaml代码片段
<!-- 活动类型 -->
<DataGridComboBoxColumn MinWidth="80" Width="80" Header="类型" >
<!-- 非编辑模式下显示的元素 -->
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="Text" Value="{Binding Path=ActType, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, Converter={StaticResource enumTextConverter}}" />
<Setter Property="DisplayMemberPath" Value="Text" />
<Setter Property="SelectedItem" Value="{Binding ActType, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Converter={StaticResource activityTypeConverter}}" />
<Setter Property="ItemsSource" Value="{Binding Source={StaticResource ActivityTypeKey}}" />
</Style>
</DataGridComboBoxColumn.ElementStyle>
<!-- 编辑模式下显示的元素 -->
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="Text" Value="{Binding Path=ActType, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, Converter={StaticResource enumTextConverter}}" />
<Setter Property="DisplayMemberPath" Value="Text" />
<Setter Property="SelectedItem" Value="{Binding ActType, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Converter={StaticResource activityTypeConverter}}" />
<Setter Property="ItemsSource" Value="{Binding Source={StaticResource ActivityTypeKey}}" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
另一种等效的写法
<!-- 活动类型 (另一种等效的写法)-->
<DataGridTemplateColumn MinWidth="80" Width="80" Header="类型">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox IsEditable="False" DisplayMemberPath="Text" Text="{Binding Path=ActType, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, Converter={StaticResource enumTextConverter}}" ItemsSource="{Binding Source={StaticResource ActivityTypeKey}}" SelectedItem="{Binding ActType, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Converter={StaticResource activityTypeConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox IsEditable="False" DisplayMemberPath="Text" Text="{Binding Path=ActType, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, Converter={StaticResource enumTextConverter}}" ItemsSource="{Binding Source={StaticResource ActivityTypeKey}}" SelectedItem="{Binding ActType, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Converter={StaticResource activityTypeConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
ActType: 要绑定的枚举变量
enumTextConverter: 枚举类型与String类型转换器
activityTypeConverter: 枚举类型与ComoBox选项数据结构之间的转换器
四、定义转换器
需要 using System.Windows.Data;
1、Enum 与 String 类型转换器
/// <summary>
/// 将枚举显示到文本框时需要用到此转换器
/// </summary>
public class EnumTextConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Enum srcType = value as Enum;
string text = srcType.GetDescription();
return text;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
2、ActivityType 与 ComboBoxOption 类型转换器
public class ActivityTypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
ActivityType srcType = (ActivityType)value;
ComboBoxOption option = srcType.GetComboBoxOption();
return option;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
ComboBoxOption dstType = (ComboBoxOption)value;
ActivityType srcType = (ActivityType)dstType.value;
return srcType;
}
}
五、ComoBox下拉选项数据结构
public class ComboBoxOption
{
public string Text { get; set; }
public string Name { get; set; }
public int value { get; set; }
public new string ToString()
{
return Text;
}
public static ComboBoxOption[] GetEnumDescriptions(Type enumType)
{
var obj = Enum.ToObject(enumType, 0) as Enum;
return obj.GetComboBoxOptions();
}
}
六、添加枚举扩展方法
/// <summary>
/// Enum扩展方法
/// </summary>
internal static class EnumExtensions
{
internal static ComboBoxOption GetComboBoxOption(this Enum e)
{
Type t = e.GetType();
FieldInfo fi = t.GetField(e.ToString());
ComboBoxOption option = new ComboBoxOption();
option.Name = fi.Name;
option.value = (int)fi.GetValue(null);
object[] attributes = fi.GetCustomAttributes(true);
if (attributes == null || attributes.Length == 0)
return option;
var des = attributes[0] as DescriptionAttribute;
option.Text = des.description;
return option;
}
internal static ComboBoxOption[] GetComboBoxOptions(this Enum e)
{
List<ComboBoxOption> optList = new List<ComboBoxOption>();
Type t = e.GetType();
//举中的常量都是静态的字段
var fields = t.GetFields(BindingFlags.Static | BindingFlags.Public);
foreach(var fi in fields)
{
object[] attributes = fi.GetCustomAttributes(true);
if (attributes == null || attributes.Length == 0)
continue;
var des = attributes[0] as DescriptionAttribute;
Console.WriteLine(des.description);
ComboBoxOption option = new ComboBoxOption();
option.Text = des.description;
option.Name = fi.Name;
option.value = (int)fi.GetValue(null);
optList.Add(option);
}
return optList.ToArray();
}
internal static string GetDescription(this Enum e)
{
Type t = e.GetType();
FieldInfo fi = t.GetField(e.ToString());
object[] attributes = fi.GetCustomAttributes(true);
if (attributes == null || attributes.Length == 0)
return string.Empty;
var des = attributes[0] as DescriptionAttribute;
return des.description;
}
internal static string[] GetDescriptions(this Enum e)
{
List<string> optList = new List<string>();
Type t = e.GetType();
//举中的常量都是静态的字段
var fields = t.GetFields(BindingFlags.Static | BindingFlags.Public);
foreach (var fi in fields)
{
object[] attributes = fi.GetCustomAttributes(true);
if (attributes == null || attributes.Length == 0)
continue;
var des = attributes[0] as DescriptionAttribute;
Console.WriteLine(des.description);
optList.Add(des.description);
}
return optList.ToArray();
}
}
七、定义静态资源
<Application x:Class="DataEditor.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:v4="http://schemas.microsoft.com/netfx/2009/xaml/presentation"
xmlns:core="clr-namespace:System;assembly=mscorlib"
xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"
xmlns:local="clr-namespace:DataEditor"
xmlns:data="clr-namespace:DataEditor.DataObject"
xmlns:converter="clr-namespace:DataEditor.Converter"
StartupUri="View\Windows\MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<!-- 枚举 ComoBox 静态资源 -->
<ObjectDataProvider x:Key="ActivityTypeKey" MethodName="GetEnumDescriptions" ObjectType="{x:Type local:ComboBoxOption}">
<ObjectDataProvider.MethodParameters>
<x:Type Type="data:ActivityType" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<!-- 转换器 静态资源 -->
<data:ActivityTypeConverter x:Key="activityTypeConverter" />
<converter:EnumTextConverter x:Key="enumTextConverter" />
</ResourceDictionary>
</Application.Resources>
</Application>
注意:静态资源中的代码保留了类在项目中所在的命令空间。
运行效果