C# 筛选PropertyGrid中枚举属性的下拉列表
我正在PropertyGrid中显示对象的属性。这些属性之一是枚举。因此,它将与列出枚举的所有值的组合框编辑器一起显示。这很好,但我需要在运行时过滤枚举值列表。我不能仅仅用Browsable属性装饰一些枚举值,因为我想隐藏的值会有所不同。目前,我倾向于使用自定义UITypeEditor,但我认为我应该先与聪明人核实一下。aC# 筛选PropertyGrid中枚举属性的下拉列表,c#,.net,enums,propertygrid,C#,.net,Enums,Propertygrid,我正在PropertyGrid中显示对象的属性。这些属性之一是枚举。因此,它将与列出枚举的所有值的组合框编辑器一起显示。这很好,但我需要在运行时过滤枚举值列表。我不能仅仅用Browsable属性装饰一些枚举值,因为我想隐藏的值会有所不同。目前,我倾向于使用自定义UITypeEditor,但我认为我应该先与聪明人核实一下。aTypeConverter可能是您所需要的全部,尤其是如果合法子集“每时每刻都在变化”的话。给定一个枚举: public enum AnimalSpecies { Ca
TypeConverter
可能是您所需要的全部,尤其是如果合法子集“每时每刻都在变化”的话。给定一个枚举:
public enum AnimalSpecies
{
Canine, Feline, Rodent, Dragon, Unicorn, Robot
}
…用于财产的:
public class Animal
{
...
[TypeConverter(typeof(AnimalSpeciesConverter))]
public AnimalSpecies Species { get; set; }
如果装饰枚举,转换器将应用于使用它的任何东西;在属性上,它仅影响该属性。对于转换器,您需要覆盖GetStandardValues()
:
返回true以指示GetStandardValuesSupported()
可以并将提供值李>TypeConverter
表示用户不能选择键入自己的值李>getStandardValuesEnclusive()
过滤列表并返回新的子集李>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();
}
另一种选择是,如果您不喜欢以这种方式公开GetValues
方法并通过反射获取值,则可以跳过该接口,将该方法设置为私有。在这种情况下,只有当方法存在时,我才可能为GetStandardValuesSupported()
返回true。这样,您就不会遇到这样的情况:您为Get…Supported()
返回true,然后又无法提供它们
这是动态的:每次打开下拉列表时,都会刷新/重新填充值列表。每次更改
值时,下拉列表都会在每次打开时更新。为什么选择此筛选器?其中一些在运行时不合法吗?部分类和枚举的代码对于上下文来说很好。是的,适当的枚举值集每时每刻都在变化。我刚用了一个自定义UITypeEditor。这是一个示例,尽管它解决了一个稍有不同的问题(不允许的枚举值不会发生变化)(我认为在没有自定义编辑器的情况下,Browsable属性也会发生变化)。在我的例子中,我只是将所需的项目添加到EditValue()中的列表框中。Simon的回答不允许“每时每刻”进行更改。一个类型转换器可能更合适更有趣!非常感谢你周到的回答。我在自定义UITypeEditor方面也取得了成功,在自定义UITypeEditor中,EditValue()被覆盖,以获取当前适当的值列表并将其添加到列表框中;下拉列表每次打开时都会更新。但这当然更好。我完全忘记了TypeConverter除了用于转换类型的方法外,还有其他方法可以重写;-)做大多数事情的方法很多,很难知道哪种方法最有效。非常有用的答案。我使用动态值选择方法制作了一个抽象枚举转换器:公共类EnumValueSelector或TypeConverter。。。受保护的虚拟bool SelectIsStandardValuesByContextInstance(对象上下文实例,输出标准值集合值)。。。还有一个字符串转换方法:受保护的虚拟IEnumerable ConvertSelectionToString(IEnumerable selection)。。。
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();
}
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());
}
}