如何在.NET PropertyGrid中显示具有重复值的枚举?

时间:2018-02-13 13:52:28

标签: c# winforms enums propertygrid

我有一个包含重复值的枚举。例如:

public enum DataVals : byte 
{
    C1_Route1to2 = 1,
    C4_Route3to5 = 1,
    C6_Route1to2 = 2,
    C7_Route3to5 = 2
}

C#只是我应用程序中的内部值。根据用户选择的路线,route是班级中的另一个属性,1可能意味着使用C1C4。问题是我在PropertyGrid中使用了Winform,此属性将重复值显示为具有相同的名称。因此C1_Route1to2显示两次,而不是C1_Route1to2C4_Route3to5

如何告诉PropertyGrid显示每个唯一名称,而不是复制值?

1 个答案:

答案 0 :(得分:0)

虽然我同意Gabriel的意见,但你可以使用我之前提到的TypeConverter来实现你所需要的。您可能需要更改编辑器以允许选择多个枚举(如果它具有FlagsAttribute ...

放置属性:

[TypeConverter(typeof(ComplexEnumConverter ))]
public enum DataVals : byte 
{
    C1_Route1to2 = 1,
    C4_Route3to5 = 1,
    C6_Route1to2 = 2,
    C7_Route3to5 = 2
}

这是转换器:

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