Reputation: 20464
In C# or VB.NET, under WinForms, I have a property that returns an array of a enum. See an example:
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};
By default, a PropertyGrid will show the values as int[], like: {0, 1, 2} instead of the enumeration value names, like: {"Name1", "Name2", "Name2"}, which is the visual representation that I would like to acchieve...
So, I would like to design a TypeConverter that could be able to return a string array with the value names, and apply it like this:
[TypeConverter(typeof(EnumArrayToStringArrayTypeConverter))]
public TestEnum[] TestProperty {get; set;} =
new[] {TestEnum.Name1, TestEnum.Name2, TestEnum.Name3};
In other words, If my property is represented like this in a PropertyGrid:
I would like to have this:
The biggest problem I'm facing is trying to retrieve the type of the enum from the custom type-converter class, to be able get the value names of that enum. I only can get the primitive data type of the array (like: int[], uint16[], etc)...
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;
}
// ...
}
Please take into account that I'm asking for a reusable solution that can work for any kind of enum. And, my enum in this example does not have the [Flags] attribute applied, but a solution should care about enums having it, so, If a enum item of the enum array is a enum that has various flags, those flags (the value names) should be concatenated for example using string.join().
Upvotes: 3
Views: 1041
Reputation: 20464
As mentioned by @NineBerry in his answer, the PropertyGrid does already show the names for the enum values. However, I discovered that exists a strange circumstance on wich it will not do it...
Since my original source-code is written in VB.NET, I'll put VB.NET sample codes to reproduce the issue.
The thing is that I was getting a value from a instance of a WMI class (specifically: Win32_DiskDrive.Capabilities), which returns an object that needs to be casted to a uint16 array. Then, I was casting that resulting uint16 array to my type of enum. To simplify things, I will not show WMI code, but an object that represents what I was getting from WMI...
Dim wmiValue As Object = {1US, 2US, 3US}
Dim castedValue As UShort() = DirectCast(wmiValue, UShort())
TestProperty = DirectCast(castedValue, TestEnum())
So, when doing that type-casting, and thanks to @NineBerry answer, I discovered that for some reason the default type converter of TestProperty goes wrong and the PropertyGrid shows uint16 values instead of the enum value-names.
( Note that using DirectCast() or CType() in VB.NET, it didn't changed the PropertyGrid behavior. )
To fix the error, I ended using Array.ConvertAll(), and then the PropertyGrid properly shows the value-names...
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)
Upvotes: 1
Reputation: 28499
The PropertyGrid
does already show the names for the enum
values. It can even handle [Flags]
correctly. See the sample below using a form with a default PropertyGrid and a default button and nothing else.
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;
}
}
Please supply some example code that can reproduce that the enum names are not shown in the PropertyGrid. You must be doing something wrong in the first place.
Upvotes: 1