过滤PropertyGrid中Enum属性的下拉列表

MC5*_*MC5 3 .net c# propertygrid enums

我在PropertyGrid中显示对象的属性.其中一个属性是枚举.因此,它使用组合框编辑器显示,该编辑器列出了枚举的所有值.这一切都很棒,但我需要在运行时过滤枚举值列表.我不能用Browsable属性装饰一些枚举值,因为我想要隐藏的值会有所不同.目前我倾向于定制的UITypeEditor,但我认为我应该首先与智能人员核实.

Ňɏs*_*arp 5

A TypeConverter可能就是您所需要的,特别是如果合法子集"时刻变化".鉴于枚举:

public enum AnimalSpecies
{
    Canine, Feline, Rodent, Dragon, Unicorn, Robot
}
Run Code Online (Sandbox Code Playgroud)

...用于财产:

public class Animal
{
    ...
    [TypeConverter(typeof(AnimalSpeciesConverter))]
    public AnimalSpecies Species { get; set; }
Run Code Online (Sandbox Code Playgroud)

如果你装饰枚举,转换器将适用于使用它的任何/所有东西; 在财产上,它只影响那个.对于转换器,您将要覆盖GetStandardValues():

class AnimalSpeciesConverter : TypeConverter
{
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        Animal test = context.Instance as Animal;

        if (test != null)
            return true;
        else
            return base.GetStandardValuesSupported();
    }

    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
    {
        return true;
    }

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        string[] names = Enum.GetNames(typeof(AnimalSpecies))
                           .Where(x => !x.StartsWith("Rob")).ToArray();

        return new StandardValuesCollection(names);
    }
}
Run Code Online (Sandbox Code Playgroud)
  • GetStandardValuesSupported()返回true表示TypeConvertercan并将提供值.
  • GetStandardValuesExclusive() 表示,用户无法选择键入自己的值.
  • GetStandardValues() 过滤列表并返回新子集.

结果:

在此输入图像描述 没有机器人!

如果过滤逻辑更复杂,您可能希望让类实例确定内容.或者你可能只是喜欢这种逻辑留在课堂上.为此,我喜欢使用界面:

public interface IValuesProvider
{
    string[] GetValues();
}

public class Animal : IValuesProvider
{
    public string Name { get; set; }
    [TypeConverter(typeof(AnimalSpeciesConverter))]
    public AnimalSpecies Species { get; set; }
    public int Value { get; set; }
    ...
    public string[] GetValues()
    {
        List<string> names = Enum.GetNames(typeof(AnimalSpecies)).ToList();

        // your logic here
        if (Value < 10)
            names.Remove(AnimalSpecies.Feline.ToString());
        else if (Value < 50)
            names.Remove(AnimalSpecies.Robot.ToString());

        return names.ToArray();
    }
Run Code Online (Sandbox Code Playgroud)

现在,当PropertyGrid请求值时,我们可以从实例中获取它们:

class AnimalSpeciesConverter : TypeConverter
{
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        IValuesProvider test = context.Instance as IValuesProvider;

        if (test != null)
            return true;
        else
            return base.GetStandardValuesSupported();
    }

    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
    {
        return true;
    }

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        IValuesProvider item = context.Instance as IValuesProvider;
        return new StandardValuesCollection(item.GetValues());
    }
}
Run Code Online (Sandbox Code Playgroud)

作为替代方案,GetValues如果您不希望以这种方式公开它并通过Reflection获取值,则可以跳过界面并将方法设为私有.在这种情况下,我可能GetStandardValuesSupported()只在方法存在时返回true .这样你就不会有一个你已经返回true Get...Supported()然后没有办法提供它们的情况.

这是动态的:每次下拉打开时都会刷新/重新填充值列表.每次更改时Value,下拉列表每次打开时都会更新.