前言:
在ComboBox绑定ItemsSource时候,在绑定枚举时候,我们通常是采用定义一个列表,然后一个显示和值进行分开,这样显得比较麻烦,下面进行对这部分进行封装。
C#
private List<Tuple<string, FruitsEnum>> fruitList = new()
{
new Tuple<string, FruitsEnum> ("苹果",FruitsEnum.Apple ),
new Tuple<string, FruitsEnum> ("香蕉",FruitsEnum.Banana ),
new Tuple<string, FruitsEnum> ("橙子",FruitsEnum.Orange ),
new Tuple<string, FruitsEnum> ("芒果",FruitsEnum.Mango ),
new Tuple<string, FruitsEnum> ("葡萄",FruitsEnum.Grapes ),
new Tuple<string, FruitsEnum> ("西瓜",FruitsEnum.Watermelon )
};
public List<Tuple<string, FruitsEnum>> FruitList
{
get => fruitList;
}
封装代码
1.EnumerationMember.cs
C#
public class EnumerationMember
{
public string Description { get; set; }
public object Value { get; set; }
}
2.EnumerationExtension.cs
C#
[MarkupExtensionReturnType(typeof(EnumerationMember[]))]
public class EnumerationExtension : MarkupExtension
{
private Type enumType;
public Type EnumType
{
get=> enumType;
set
{
if (enumType == value) return;
var enumTypeTemp = Nullable.GetUnderlyingType(value) ?? value;
if (enumTypeTemp.IsEnum == false) throw new ArgumentException("Type must be an Enum.");
enumType = enumTypeTemp;
}
}
private static ConcurrentDictionary<Type, EnumerationMember[]> Enums { get; } = new ConcurrentDictionary<Type, EnumerationMember[]>();
public static EnumerationMember[] GetEnums(Type typez)
{
return Enums.GetOrAdd(typez, (type) =>
{
var enumValues = Enum.GetValues(type);
return (
from object enumValue in enumValues
select new EnumerationMember
{
Value = enumValue,
Description = GetDescription(type, enumValue)
}).ToArray();
});
}
private static string GetDescription(Type enum_type, object enumValue)
{
var descriptionAttribute = enum_type
.GetField(enumValue.ToString())
.GetCustomAttributes(typeof(DescriptionAttribute), false)
.FirstOrDefault() as DescriptionAttribute;
return descriptionAttribute != null
? descriptionAttribute.Description
: enumValue.ToString();
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return GetEnums(EnumType);
}
}
使用:
1.FruitsEnum.cs
C#
public enum FruitsEnum
{
[Description("苹果")]
Apple,
[Description("香蕉")]
Banana,
[Description("橙子")]
Orange,
[Description("芒果")]
Mango,
[Description("葡萄")]
Grapes,
[Description("西瓜")]
Watermelon,
[Description("菠萝")]
Pineapple,
[Description("草莓")]
Strawberry,
[Description("蓝莓")]
Blueberry,
[Description("覆盆子")]
Raspberry
}
2.MainWindow.xaml
C#
<Window
x:Class="WPFApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<StackPanel>
<ComboBox
DisplayMemberPath="Description"
ItemsSource="{local:Enumeration EnumType={x:Type local:FruitsEnum}}"
SelectedValue="{Binding Fruits, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Value" />
</StackPanel>
</Grid>
</Window>
3.MainWindowViewModel.cs
C#
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WPFApp
{
public class MainWindowViewModel : BindableBase
{
private FruitsEnum fruits;
public FruitsEnum Fruits
{
get => fruits;
set => SetProperty(ref fruits, value);
}
}
}