3

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:

enter image description here

I would like to have this:

enter image description here


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().

3
  • For the first problem, how about Enum.GetNames(Type) Commented Dec 17, 2018 at 11:53
  • @blins yes... but for being able to do that, firstly I need to determine the enum type (that is the first, main problem). Thanks for comment. Commented Dec 17, 2018 at 12:10
  • In your example, the array contains the values 3, 4 and 10 which are not valid values of the enumeration (0,1,2). Maybe this is already the problem? Commented Dec 17, 2018 at 14:03

2 Answers 2

1

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;
    }
}

enter image description here enter image description here

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.

Sign up to request clarification or add additional context in comments.

1 Comment

many thanks for the tip. After debugging a little bit I discovered which was the problem (I published an answer to explain it). In short the problem was the way I was assigning the value of my property, but not sure why the property grid behavior radically changed for doing that. Thanks again.
1

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.