【问题标题】:C# Propertygrid combobox with enum values (Win Forms)具有枚举值的 C# Propertygrid 组合框(Win Forms)
【发布时间】:2012-09-19 09:58:17
【问题描述】:
public enum eVisualType
{
    None = 0, Torch = 1, Rune01, Rune02, Rune03, FireRed01,
    LaserBlackWhiteLeft, LaserBlackWhiteRight, LaserBlueRedLeft, LaserBlueRedRight,
    Wheel01, Wheel01a, Wheel02, BlinkingStar, MovingPillar
}

public class EnumTypeConverter : TypeConverter
{
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true; // True means show a combobox
    }
    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
    {
        return true; // True will limit to list. false will show the list, but allow free-formentry
    }
}

public class VisualTypeConverter : EnumTypeConverter
{
    public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        return new StandardValuesCollection(new eVisualType[] { eVisualType.BlinkingStar, eVisualType.FireRed01, eVisualType.LaserBlackWhiteLeft, eVisualType.LaserBlackWhiteRight, eVisualType.LaserBlueRedLeft, eVisualType.LaserBlueRedRight, eVisualType.MovingPillar, eVisualType.Rune01, eVisualType.Rune02, eVisualType.Rune03, eVisualType.Torch, eVisualType.Wheel01, eVisualType.Wheel01a, eVisualType.Wheel02 });
    }

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        if(value is string)
            return (eVisualType)Enum.Parse(typeof(eVisualType), value.ToString(), true);
        return base.ConvertFrom(context, culture, value);
    }

}

propertygrid 类中的代码:

    private eVisualType m_VisualType = eVisualType.FireRed01;
    [CategoryAttribute("Basic"), DescriptionAttribute("The visual type.")]
    [TypeConverter(typeof(VisualTypeConverter))]
    [DisplayName("Visual Type")]
    public eVisualType VisualType
    {
        get { return m_VisualType; }
        set { m_VisualType = value; }
    }

在运行时在 propertygrid 中选择不同的值时,上面仍然会产生错误:“System.String”类型的对象无法转换为“[项目名称].eVisualType”类型。

这个问题曾经被问过一次或两次,但从未详细说明过,或者仅针对 WPF+绑定。我使用 Windows 窗体。

我也不确定是否需要 ConvertFrom(..)。

【问题讨论】:

  • 不清楚真正想要什么,最好告诉我们这件事是如何开始的,结果如何。
  • 我的属性网格中需要一个组合框来显示枚举值。但它也应该是一个枚举而不是一个字符串。所以 myPropGrid.VisualType 应该是 eVisual 类型的枚举,而不是字符串。当前结果是出现问题中提到的错误的崩溃。

标签: c# windows forms enums propertygrid


【解决方案1】:

TypeConverter 不好(我需要从 EnumConverter 派生而不是从 TypeConverter 派生。

using System;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;

namespace [namespace]
{
    public class EnumTypeConverter : EnumConverter
    {
        private Type m_EnumType;
        public EnumTypeConverter(Type type)
            : base(type)
        {
            m_EnumType = type;
        }

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destType)
        {
            return destType == typeof(string);
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destType)
        {
            FieldInfo fi = m_EnumType.GetField(Enum.GetName(m_EnumType, value));
            DescriptionAttribute dna =
                (DescriptionAttribute)Attribute.GetCustomAttribute(
                fi, typeof(DescriptionAttribute));

            if (dna != null)
                return dna.Description;
            else
                return value.ToString();
        }

        public override bool CanConvertFrom(ITypeDescriptorContext context, Type srcType)
        {
            return srcType == typeof(string);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            foreach (FieldInfo fi in m_EnumType.GetFields())
            {
                DescriptionAttribute dna =
                (DescriptionAttribute)Attribute.GetCustomAttribute(
                fi, typeof(DescriptionAttribute));

                if ((dna != null) && ((string)value == dna.Description))
                    return Enum.Parse(m_EnumType, fi.Name);
            }
            return Enum.Parse(m_EnumType, (string)value);
        }
    }
}

http://www.codeproject.com/Articles/22717/Using-PropertyGrid

【讨论】:

    【解决方案2】:

    通过反思尝试:

    public static T GetEnumMemberFromName<T>(string name)
        {
            return (T)Enum.Parse(typeof(T), name);
        }
    

    在您的代码中:

    public class VisualTypeConverter : EnumTypeConverter  
    {  
        public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)  
        {  
            return new StandardValuesCollection(new eVisualType[] { eVisualType.BlinkingStar, eVisualType.FireRed01, eVisualType.LaserBlackWhiteLeft, eVisualType.LaserBlackWhiteRight, eVisualType.LaserBlueRedLeft, eVisualType.LaserBlueRedRight, eVisualType.MovingPillar, eVisualType.Rune01, eVisualType.Rune02, eVisualType.Rune03, eVisualType.Torch, eVisualType.Wheel01, eVisualType.Wheel01a, eVisualType.Wheel02 });  
        }  
    
         public T GetEnumMemberFromName<T>(string name)
        {
            return (T)Enum.Parse(typeof(T), name);
        }
    
    }  
    

    例子:

    eVisualType  myEnumMember = myVisualTypeConverterInstance.GetEnumMemberFromName<eVisualType>("Torch");
    

    【讨论】:

    • 抱歉,我需要更多信息。我在哪里调用这个函数?
    • 抱歉,仍然出现同样的错误。也许我做错了什么。但是 GetEnumMemberFromName 只是以通用方式将字符串转换为适当的枚举值。结果与我之前的 ConvertFrom() 函数相同。我仍然认为问题出在 getter/setter 的某个地方,propertygrid 本身除了字符串值或其他东西之外什么都不接受?
    猜你喜欢
    • 1970-01-01
    • 2020-07-26
    • 1970-01-01
    • 2012-08-19
    • 1970-01-01
    • 2015-08-03
    • 1970-01-01
    • 2018-11-12
    • 2020-02-07
    相关资源
    最近更新 更多