I have an enum that contains duplicate values. For example:
public enum DataVals : byte
{
C1_Route1to2 = 1,
C4_Route3to5 = 1,
C6_Route1to2 = 2,
C7_Route3to5 = 2
}
The values C#
are just internal values within my application. Depending on which route is selected by the user, route
is another property in the class, a 1
could mean use C1
or C4
. The problem is I am using a PropertyGrid
in my Winform
and this property displays the duplicate values as having the same name. So C1_Route1to2
shows up twice instead of both C1_Route1to2
and C4_Route3to5
.
How do I tell the PropertyGrid
to display each unique name, rather than duplicating the values?
Although I agree with Gabriel, you could achieve what you need using the TypeConverter as I mentioned before. You might need to change the editor to allow selecting more than one enum if it has the FlagsAttribute...
Place the attribute:
[TypeConverter(typeof(ComplexEnumConverter ))]
public enum DataVals : byte
{
C1_Route1to2 = 1,
C4_Route3to5 = 1,
C6_Route1to2 = 2,
C7_Route3to5 = 2
}
And here is the converter:
public class ComplexEnumConverter : EnumConverter
{
public bool IsFlagged { get; }
public string[] EnumValues { get; }
public ComplexEnumConverter(Type type)
: base(type)
{
IsFlagged = TypeDescriptor.GetAttributes(type).OfType<FlagsAttribute>().Any();
EnumValues = Enum.GetNames(type);
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(string);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var str = value as string;
if (!string.IsNullOrWhiteSpace(str))
{
var values = str.Split(',').Select(s => s.Trim());
var enumValue = Enum.Parse(EnumType, values.First());
if (IsFlagged)
{
var temp = (int)enumValue;
foreach (var item in values.Skip(1))
{
temp |= (int)Enum.Parse(EnumType, item);
}
enumValue = temp;
}
return enumValue;
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
var type = value?.GetType();
if (type == EnumType)
{
var list = new List<string>();
int k = (int)value;
foreach (var item in Enum.GetNames(type))
{
var current = (int)Enum.Parse(type, item);
if ((k & current) == current)
{
list.Add(item);
}
}
return list.Aggregate((c, n) => $"{c}, {n}");
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return context.PropertyDescriptor.PropertyType.IsEnum;
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return context.PropertyDescriptor.PropertyType.IsEnum;
}
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(EnumValues);
}
}