C# 将Combobox绑定到枚举(一个枚举元素除外)
实际上,我可以使用C# 将Combobox绑定到枚举(一个枚举元素除外),c#,wpf,binding,combobox,enums,C#,Wpf,Binding,Combobox,Enums,实际上,我可以使用描述属性将我的组合框绑定到枚举: <ComboBox ItemsSource="{Binding Source={extension:Enumeration {x:Type model:MyEnum}}}" DisplayMemberPath="Description" SelectedValue="{Binding Path=DataContextEnumProp}" SelectedValuePath="Value"/>
描述属性将我的组合框
绑定到枚举
:
<ComboBox ItemsSource="{Binding Source={extension:Enumeration {x:Type model:MyEnum}}}"
DisplayMemberPath="Description"
SelectedValue="{Binding Path=DataContextEnumProp}"
SelectedValuePath="Value"/>
我需要隐藏AlternativeToSecondEnumMember
,因为在组合框中查看它与此无关
要做到这一点,最好的解决方案是什么?也许是一个转换器
或者在代码隐藏中设置项资源
?我建议使用一个简单的解决方案,让你的生活更轻松。假设您使用的是MVVM,只需创建一个新属性来保存合适的值列表
private ObservableCollection<string> _myEnumList;
public ObservableCollection<string> MyEnumList
{
get
{
if (this._myEnumList == null)
{
string[] myList = Enum.GetNames(typeof(MyEnum));
// You can also use your own logic to generate your list
this._myEnumList = new ObservableCollection<string>(myList);
}
return this._myEnumList;
}
}
private observedcollection\u myeumlist;
公共可观测收集脊髓学家
{
得到
{
if(this.\u myEnumList==null)
{
字符串[]myList=Enum.GetNames(typeof(MyEnum));
//您还可以使用自己的逻辑生成列表
这._myEnumList=新的可观察集合(myList);
}
把这个还给我;
}
}
就我个人而言,当Enum
中的值并非全部有效时,试图找到一种将Enum
类型自动转换为字符串值列表的方法是没有意义的。我能够找到一种方法,使用转换器和数据触发器来实现我想要的功能。由于链接是关于IsEnabled
,而不是IsVisible
,为了可读性,我把对我有用的东西放在这里
首先,我必须在我的组合框中添加一个DataTrigger
:
<ComboBox ItemsSource="{Binding Source={extension:Enumeration {x:Type model:MyEnum}}}"
DisplayMemberPath="Description"
SelectedValue="{Binding Path=DataContextEnumProp}"
SelectedValuePath="Value">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=Content, RelativeSource={RelativeSource Self},
Converter={StaticResource ComboBoxVisibleConverter}}" Value="true">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
EnumerationExtension
是以下是一些使用ObjectDataProvider特殊实现的基于属性的解决方案。因此,如果一个枚举字段由ShouldBeHiddenAttribute修饰并且其值为true,那么该枚举字段将隐藏在UI(组合框)中
应避免属性代码
/// <summary>
/// helps to hide the enum value
/// </summary>
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public class ShouldBeHiddenAttribute : Attribute
{
public ShouldBeHiddenAttribute(bool isHiddenInUi)
{
HiddenInUi = isHiddenInUi;
}
public bool HiddenInUi { get; set; }
}
public enum MyEnum
{
[XmlEnum("first")]
[Description("first")]
FirstEnumMember,
[XmlEnum("second")]
[Description("second")]
SecondEnumMember,
//[XmlIgnore]
[Description("second")]
[ShouldBeHiddenAttribute(true)]
AlternativeToSecondEnumMember
//I don't want this one to be in the combobox
}
特殊对象数据提供程序实现
/// <summary>
/// helps to display value according to decorating attributes
/// </summary>
public class AttributeBasedObjectDataProvider : ObjectDataProvider
{
/// <summary>
/// returns value of enum according its two attributes
/// 1. DescriptionAttribute - provide a dispaly name of the enum value
/// 2. ShouldBeHiddenAttribute - provide a dispaly state of the enum
/// </summary>
/// <param name="enumObj">enum field value</param>
/// <returns>if ShouldBeHiddenAttribute.HiddenInUi value is true return null else enum Description if defined(or enum actual value id Description is not defined)</returns>
public object GetEnumValues(Enum enumObj)
{
//get the ShouldBeHiddenAttribute value
var isHidden = enumObj.GetType().GetRuntimeField(enumObj.ToString()).
GetCustomAttributes(typeof (ShouldBeHiddenAttribute), false).
SingleOrDefault() as ShouldBeHiddenAttribute;
if (isHidden != null && isHidden.HiddenInUi) return null;
//get the DescriptionAttribute value
var attribute = enumObj.GetType().GetRuntimeField(enumObj.ToString()).
GetCustomAttributes(typeof (DescriptionAttribute), false).
SingleOrDefault() as DescriptionAttribute;
return attribute == null ? enumObj.ToString() : attribute.Description;
}
/// <summary>
/// returns collection of enum values
/// </summary>
/// <param name="type">enum type</param>
/// <returns>collection of enum values</returns>
public List<object> GetShortListOfApplicationGestures(Type type)
{
var shortListOfApplicationGestures =
Enum.GetValues(type).OfType<Enum>().Select(GetEnumValues).Where(o => o != null).ToList();
return
shortListOfApplicationGestures;
}
}
<ObjectDataProvider x:Key="MyEnumMembers" MethodName="GetShortListOfApplicationGestures" ObjectType="{x:Type pageBasedApp:AttributeBasedObjectDataProvider}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="pageBasedApp:MyEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
//
///帮助根据装饰属性显示值
///
公共类AttributeBaseObjectDataProvider:ObjectDataProvider
{
///
///根据枚举的两个属性返回枚举的值
///1.DescriptionAttribute-提供枚举值的显示名称
///2.ShouldBeHiddenAttribute-提供枚举的dispaly状态
///
///枚举字段值
///如果ShouldBeHiddenAttribute.HiddenInUi值为true,则如果已定义,则返回null,否则返回枚举说明(或未定义枚举实际值id说明)
公共对象GetEnumValues(枚举enumObj)
{
//获取ShouldBeHiddenAttribute值
var isHidden=enumObj.GetType().GetRuntimeField(enumObj.ToString())。
GetCustomAttributes(typeof(ShouldBeHiddenAttribute),false)。
SingleOrDefault()作为应指定的属性;
if(isHidden!=null&&isHidden.HiddenInUi)返回null;
//获取DescriptionAttribute值
var attribute=enumObj.GetType().GetRuntimeField(enumObj.ToString())。
GetCustomAttributes(typeof(DescriptionAttribute),false)。
SingleOrDefault()作为DescriptionAttribute;
return attribute==null?enumObj.ToString():attribute.Description;
}
///
///返回枚举值的集合
///
///枚举类型
///枚举值的集合
public List GetShortListofApplication测试(类型)
{
var应用程序测试短列表=
GetValues(type).OfType().Select(GetEnumValues).Where(o=>o!=null).ToList();
返回
应用测试的短名单;
}
}
Xaml ObjectDataProvider定义
/// <summary>
/// helps to display value according to decorating attributes
/// </summary>
public class AttributeBasedObjectDataProvider : ObjectDataProvider
{
/// <summary>
/// returns value of enum according its two attributes
/// 1. DescriptionAttribute - provide a dispaly name of the enum value
/// 2. ShouldBeHiddenAttribute - provide a dispaly state of the enum
/// </summary>
/// <param name="enumObj">enum field value</param>
/// <returns>if ShouldBeHiddenAttribute.HiddenInUi value is true return null else enum Description if defined(or enum actual value id Description is not defined)</returns>
public object GetEnumValues(Enum enumObj)
{
//get the ShouldBeHiddenAttribute value
var isHidden = enumObj.GetType().GetRuntimeField(enumObj.ToString()).
GetCustomAttributes(typeof (ShouldBeHiddenAttribute), false).
SingleOrDefault() as ShouldBeHiddenAttribute;
if (isHidden != null && isHidden.HiddenInUi) return null;
//get the DescriptionAttribute value
var attribute = enumObj.GetType().GetRuntimeField(enumObj.ToString()).
GetCustomAttributes(typeof (DescriptionAttribute), false).
SingleOrDefault() as DescriptionAttribute;
return attribute == null ? enumObj.ToString() : attribute.Description;
}
/// <summary>
/// returns collection of enum values
/// </summary>
/// <param name="type">enum type</param>
/// <returns>collection of enum values</returns>
public List<object> GetShortListOfApplicationGestures(Type type)
{
var shortListOfApplicationGestures =
Enum.GetValues(type).OfType<Enum>().Select(GetEnumValues).Where(o => o != null).ToList();
return
shortListOfApplicationGestures;
}
}
<ObjectDataProvider x:Key="MyEnumMembers" MethodName="GetShortListOfApplicationGestures" ObjectType="{x:Type pageBasedApp:AttributeBasedObjectDataProvider}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="pageBasedApp:MyEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
组合绑定
<ComboBox ItemsSource="{Binding Source={StaticResource MyEnumMembers}}" Width="150"/>
注意。既然您编写了要避免在VM中将string
转换为MyEnum
,下面是一个没有string
的解决方案:
public ObservableCollection<MyEnum> MyEnumList { get; } = new ObservableCollection<MyEnum>(
Enum.GetValues(typeof(MyEnum)).
Cast<MyEnum>().
Where(myEnum => myEnum != MyEnum.AlternativeToSecondEnumMember));
public observetecollection MyEnumList{get;}=new observetecollection(
GetValues(typeof(MyEnum))。
Cast()。
其中(myEnum=>myEnum!=myEnum.AlternativeToSecondEnumMember));
通过这种方式,您可以继续使用MyEnum,无需进行字符串转换。这就是我找到的解决方案:
public static IList ToList(this Type type, Enum[] valuesToSkip)
{
ArrayList enumList = new ArrayList();
Array enumValues = Enum.GetValues(type);
foreach (Enum value in enumValues)
{
if (valuesToSkip.Contains(value))
continue;
// in this solution I had a method to get the description from the Enum
// but you can avoid this part and populate your list with the enum values
//enumList.Add(new KeyValuePair<Enum, string>(value, GetEnumDescription(value)));
enumList.Add(value);
}
return list;
}
公共静态IList ToList(此类型,Enum[]valuesToSkip)
{
ArrayList enumList=新建ArrayList();
数组enumValues=Enum.GetValues(类型);
foreach(枚举值中的枚举值)
{
if(值跳过.包含(值))
继续;
//在这个解决方案中,我有一个从枚举中获取描述的方法
//但您可以避免这一部分,并用枚举值填充列表
//添加(新的KeyValuePair(value,GetEnumDescription(value));
枚举列表。添加(值);
}
退货清单;
}
我已经编写了自己的ToList方法,该方法返回枚举,不包括我通过valuesToSkip传递的枚举。
我以以下方式填充组合框:
comboBox.DataSource=EnumExtension.ToList(typeof(yourEnum),新Enum[]{yourEnum.ValueToSkip}) 如果这样做,我必须在我的VM中将string
转换为MyEnum
,这就是我想要避免的。@ZwoRmiobserveCollection MyEnumList=new observeCollection(Enum.GetValues(typeof(MyEnum)).Cast()代码>ObjectDataProvider呢?你试过这种方法吗?@Ilan没有试过,你会怎么做?我已经添加了一些解决方案。如果您需要澄清,请告诉我