在C#或VB.NET中,在WinForms下,我有一个返回枚举数组的属性。查看示例:
public enum TestEnum: int {
Name1 = 0,
Name2 = 1,
Name3 = 2
} // Note that the enum does not apply for the [Flags] attribute.
public TestEnum[] TestProperty {get; set;} =
new[] {TestEnum.Name1, TestEnum.Name2, TestEnum.Name3};
默认情况下,PropertyGrid会将值显示为int [],例如:{0,1,2}而不是枚举值名称,例如:{“ Name1”,“ Name2”,“ Name2 “},这是我想要实现的视觉效果...
因此,我想设计一个TypeConverter,它可以返回带有值名称的字符串数组,并像这样应用它:
[TypeConverter(typeof(EnumArrayToStringArrayTypeConverter))]
public TestEnum[] TestProperty {get; set;} =
new[] {TestEnum.Name1, TestEnum.Name2, TestEnum.Name3};
换句话说,如果我的属性在PropertyGrid中这样表示:
我想要这个:
我面临的最大问题是尝试从自定义类型转换器类中检索枚举的类型,以便能够获取该枚举的值名称。我只能得到数组的原始数据类型(例如:int [],uint16 []等)。
public class EnumArrayToStringArrayTypeConverter : TypeConverter {
// ...
public override object ConvertTo(ITypeDescriptorContext context,
CultureInfo culture,
object value,
Type destinationType) {
if (destinationType == null) {
throw new ArgumentNullException(nameof(destinationType));
}
try {
// This will return the array-type for the
// primitive data type of the declared enum,
// such as int[], uint16[], etc.
Type t = value.GetType();
// I'm stuck at this point.
// ...
} catch (Exception ex) {
}
return null;
}
// ...
}
请考虑到我正在寻求可用于任何枚举的可重用解决方案。并且,在此示例中,我的枚举没有应用[Flags]属性,但是解决方案应该考虑具有该属性的枚举,因此,如果枚举数组的枚举项是具有多个标志的枚举,则这些标志(值名称)应进行连接,例如使用 string.join()。
答案 0 :(得分:1)
PropertyGrid
已经显示了enum
值的名称。它甚至可以正确处理[Flags]
。使用具有默认PropertyGrid和默认按钮且没有其他内容的表单,请参见下面的示例。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[Flags]
public enum TestEnum : int
{
Name1 = 0,
Name2 = 1,
Name3 = 2
}
public class TestObject
{
public string Name { get; set; } = "Hello World";
public TestEnum[] TestProperty { get; set; } =
new[] { TestEnum.Name1, TestEnum.Name2 | TestEnum.Name3, TestEnum.Name3 };
}
private void button1_Click(object sender, EventArgs e)
{
TestObject o = new TestObject();
propertyGrid1.SelectedObject = o;
}
}
请提供一些示例代码,这些代码可以重现PropertyGrid中未显示枚举名称。首先,您一定在做错事。
答案 1 :(得分:1)
正如@NineBerry在his answer中提到的那样, PropertyGrid 已经显示了枚举值的名称。但是,我发现在这种情况下存在一种奇怪的情况是不会这样做的。
由于我的原始源代码是用VB.NET编写的,因此我将放置VB.NET示例代码来重现此问题。
问题是我正在从WMI类的实例(具体是Win32_DiskDrive.Capabilities)的实例中获取一个值,该实例返回一个需要转换为uint16数组的对象。然后,我将生成的uint16数组转换为我的枚举类型。为简化起见,我不会显示WMI代码,而是显示一个代表我从WMI中得到的内容的对象...
Dim wmiValue As Object = {1US, 2US, 3US}
Dim castedValue As UShort() = DirectCast(wmiValue, UShort())
TestProperty = DirectCast(castedValue, TestEnum())
因此,在进行类型转换时,并感谢@NineBerry的回答,我发现由于某种原因, TestProperty 的默认类型转换器出错,并且 PropertyGrid 显示uint16值而不是枚举值名称。
(请注意,在VB.NET中使用 DirectCast()或 CType(),它并没有更改 PropertyGrid 行为。)
要解决该错误,我结束了使用 Array.ConvertAll(),然后 PropertyGrid 正确显示了值名称...
Dim wmiValue As Object = {1US, 2US, 3US}
Dim castedValue As UShort() = DirectCast(wmiValue, UShort())
TestProperty = Array.ConvertAll(castedValue,
Function(value As UShort)
Return DirectCast(value, TestEnum)
End Function)