第一种方法:
后台:
internal static class EnumCache<T> where T : struct, IConvertible { private static Dictionary<int, Tuple<T, string>> collectionCache; public static Dictionary<int, Tuple<T, string>> CollectionCache { get { if (collectionCache == null) { collectionCache = CreateCache(); } return collectionCache; } } private static Dictionary<int, Tuple<T, string>> CreateCache() { Dictionary<int, Tuple<T, string>> collectionCache = new Dictionary<int, Tuple<T, string>>(); var fields = typeof(T).GetFields().Where(x => x.IsLiteral); foreach (var field in fields) { var intValue = (int)field.GetValue(null); var displayText = ((DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute), false))[0].Description; T operatorEnum = (T)(object)field.GetValue(null); var tuple = Tuple.Create(operatorEnum, displayText); collectionCache.Add(intValue, tuple); } return collectionCache; } } public class LogicalOperatorEnumConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { //this is a hack, binding is unbinding to text i think??? if (value is string) { value = LogicalOperator.Where; } return EnumCache<LogicalOperator>.CollectionCache[(int)value].Item2; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { var displayText = (String)value; var key = EnumCache<LogicalOperator>.CollectionCache.Single(x => x.Value.Item2 == displayText).Key; return (object)EnumCache<LogicalOperator>.CollectionCache[key].Item1; } }
前台:
<templates:LogicalOperatorEnumConverter x:Key="LogicalOperatorEnumConverter" />
<ComboBox ToolTip="The logical operator" Grid.Column="1" Margin="2 0 0 0" ItemsSource="{Binding LogicalOperators}" SelectedItem="{Binding LogicalOperator, Mode=TwoWay}" > <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Path=. , Converter={StaticResource LogicalOperatorEnumConverter}}" /> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox>
此方法为泛型方法封装,每次用时,都要写一个转换器,如:LogicalOperatorEnumConverter 。
第二种方法:
写一个固定的类:
public class ComboBoxDataModel : BaseEntity { private Guid _id; public Guid ID { get => _id; set => SetProperty(ref _id, value); } private string value; public string Value { get { return value; } set { this.value = value; OnPropertyChanged("Value"); } } private string text; public string Text { get { return text; } set { this.text = value; OnPropertyChanged("Text"); } } private bool isChecked; public bool IsChecked { get { return isChecked; } set { this.isChecked = value; OnPropertyChanged("IsChecked"); } } }
将Enum转成ObservableCollection<ComboBoxDataModel>
/// <summary>
/// 枚举转换为List,显示名称为summary
/// </summary>
/// <param name="pEnum"></param>
/// <param name="pShowEnumValue">True:返回的是0,1,2等值;False:返回的是值对于的枚举项目名称</param>
/// <returns></returns>
public static ObservableCollection<ComboBoxDataModel> GetEnumList(Type pEnumType, bool pShowEnumValue = true) { ObservableCollection<ComboBoxDataModel> list = new ObservableCollection<ComboBoxDataModel>(); Type typeDescription = typeof(DescriptionAttribute); System.Reflection.FieldInfo[] fields = pEnumType.GetFields(); string strText = string.Empty; string strValue = string.Empty; foreach (FieldInfo field in fields) { if (field.FieldType.IsEnum) { if (pShowEnumValue) { strValue = ((int)pEnumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString(); } else { strValue = pEnumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null).ToString(); } object[] arr = field.GetCustomAttributes(typeDescription, true); if (arr.Length > 0) { DescriptionAttribute aa = (DescriptionAttribute)arr[0]; strText = aa.Description; } else { strText = field.Name; } list.Add(new ComboBoxDataModel() { Text = strText, Value = strValue }); } } return list; }
ViewModel:
private ObservableCollection<ComboBoxDataModel> _enumBusinessPartDiscountTypeList; //数量范围列表 public ObservableCollection<ComboBoxDataModel> EnumBusinessPartDiscountTypeList { get => _enumBusinessPartDiscountTypeList; set { SetProperty(ref _enumBusinessPartDiscountTypeList, value); } } ctor中 EnumBusinessPartDiscountTypeList = ComboBoxListHelper.GetEnumList(typeof(EnumBusinessPartDiscountType), true);
前台:
<ComboBox x:Name="cmbQuantitativeRange" Grid.Row="0" Grid.Column="3" DisplayMemberPath="Text" SelectedValuePath="Value" Margin="5" Height="25" ItemsSource="{Binding EnumBusinessPartDiscountTypeList}" SelectedItem="{Binding SelectedEnumBusinessPartDiscountType,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> </ComboBox>
这种方式也可以,但需要写更多的代码,项目一开始用的是第二种。后来发现第一种,感觉第一种更比较好理解点。主要还是看项目需求,来选择。