将 Combobox 绑定到一个枚举,除了一个枚举元素

Zwo*_*Rmi 2 c# wpf enums binding combobox

实际上,我可以将我的绑定ComboboxEnum使用他们的DescriptionAttribute

<ComboBox ItemsSource="{Binding Source={extension:Enumeration {x:Type model:MyEnum}}}"
      DisplayMemberPath="Description" 
      SelectedValue="{Binding Path=DataContextEnumProp}"
      SelectedValuePath="Value"/>
Run Code Online (Sandbox Code Playgroud)

我用过这个 SO 答案

我的枚举是:

public enum MyEnum
{
    [XmlEnum("first")]
    [Description("first")]
    FirstEnumMember,

    [XmlEnum("second")]
    [Description("second")]
    SecondEnumMember,

    //[XmlIgnore]
    [Description("second")]
    AlternativeToSecondEnumMember //I don't want this one to be in the combobox
}
Run Code Online (Sandbox Code Playgroud)

我需要隐藏AlternativeToSecondEnumMember,因为在ComboBox.

为此,最好的解决方案是什么?也许 aConverter或将ItemsSourcein 代码设置在后面?

Ila*_*lan 5

这是一些使用 ObjectDataProvider 特殊实现的基于属性的解决方案。因此,如果枚举字段由 ShouldBeHiddenAttribute 修饰并且其值为 true,则该枚举字段将隐藏在 UI(ComboBox) 中。

应该隐藏属性代码

/// <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; }
}
Run Code Online (Sandbox Code Playgroud)

你的枚举装饰了我的属性

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
}
Run Code Online (Sandbox Code Playgroud)

特殊的 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Xaml ObjectDataProvider 定义

    <ObjectDataProvider x:Key="MyEnumMembers" MethodName="GetShortListOfApplicationGestures" ObjectType="{x:Type pageBasedApp:AttributeBasedObjectDataProvider}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="pageBasedApp:MyEnum" />
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
Run Code Online (Sandbox Code Playgroud)

组合绑定

<ComboBox ItemsSource="{Binding Source={StaticResource MyEnumMembers}}" Width="150"/>
Run Code Online (Sandbox Code Playgroud)

问候。