问题:
在PropertyGrid控件中的下拉列表绑定值后,可以选择,但是双击不会选择下一个值,会出现如下错误想要的效果是双击一下的时候应该是选择下一个值,列如现在ComboBox选择的值是“一”,双击一下应该选择的是“二”类的全部代码:
     public abstract class ComboBoxItemTypeConvert : TypeConverter
    {
        public Hashtable _hash;        public abstract void GetConvertHash();        public ComboBoxItemTypeConvert()
        {
            _hash = new Hashtable();
            GetConvertHash();
        }        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }        public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            string[] ids = new string[_hash.Values.Count];            int i = 0;
            foreach (DictionaryEntry myDE in _hash)
            {
                ids[i++] = (string)(myDE.Key);
            }            return new StandardValuesCollection(ids);
        }        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
                return true;            return base.CanConvertFrom(context, sourceType);
        }        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is string)
            {
                foreach (DictionaryEntry myDe in _hash)
                {
                    if(myDe.Key.Equals(value))
                        return myDe.Value;
                }
            }
            return base.ConvertFrom(context, culture, value);
        }        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object v, Type destinationType)
        {
            if (destinationType == typeof(string))
            {
                foreach (DictionaryEntry myDE in _hash)
                {
                    if (myDE.Value.Equals(v))
                        return myDE.Key.ToString();
                }
            }
            return base.ConvertTo(context, culture, v, destinationType);        }        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            return true;
        }
    }    public class Class2 : ComboBoxItemTypeConvert
    {
        public override void GetConvertHash()
        {
            _hash.Add("零", 0);
            _hash.Add("一",1);
            _hash.Add("二",2);
            _hash.Add("三", 3);
            _hash.Add("四", 4);
        }
    }    public class Demo
    {
        private int theCountry;
        private bool theLanguage;        [CategoryAttribute("基本信息"), DescriptionAttribute("如果你要将用户设置为删除状态,请选择“是”"), DisplayName("删除状态")]
        [TypeConverter(typeof(Class2))]
        public int Country
        {
            get
            {
                return theCountry;
            }
            set
            {
                theCountry = value;
            }
        }        [CategoryAttribute("基本信息"), DescriptionAttribute("如果你要将用户设置为锁定状态,请选择“是”"), DisplayName("锁定状态")]
        public bool Language
        {
            get
            {
                return theLanguage;
            }
            set
            {
                theLanguage = value;
            }
        }
    }WinForm代码:
         private void Form1_Load(object sender, EventArgs e)
        {
            Demo o = new Demo();
            propertyGrid1.SelectedObject = o;             //”propertyGrid1“为PropertyGrid控件
        }程序运行界面:

解决方案 »

  1.   

    那个功能你需要的是 PropertyEditor 不是 TypeConverter
      

  2.   

    PropertyEditor在哪个名空间里?
    能贴个代码瞧瞧吗?
    谢谢!
      

  3.   


       public abstract class MyComboBox : TypeConverter
            {
                public Hashtable _hash = null;            public MyComboBox()
                {
                    _hash = new Hashtable();
                    GetConvertHash();
                }
                public abstract void GetConvertHash();
                public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
                {
                    return true;
                }
                public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
                {
                    string[] ids = new string[_hash.Values.Count];
                    int i = 0;
                    foreach (DictionaryEntry myde in _hash)
                    {
                        ids[i++] = myde.Key.ToString();
                    }
                    return new StandardValuesCollection(ids);
                }
                public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourcetype)
                {
                    if (sourcetype == typeof(string))
                    {
                        return true;
                    }
                    return base.CanConvertFrom(context, sourcetype);
                }
                public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object v)
                {
                    if (v is string)
                    {
                        foreach (DictionaryEntry myde in _hash)
                        {
                            if (myde.Value.Equals((v.ToString())))
                                return myde.Key;
                        }
                    }
                    return "";
                    // return base.ConvertFrom(context, culture, v);
                }
                public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object v, Type destinationtype)
                {
                    if (destinationtype == typeof(string))
                    {
                        foreach (DictionaryEntry myde in _hash)
                        {
                            if (myde.Key.Equals(v))
                                return myde.Value.ToString();
                        }
                        return "";
                    }
                    return base.ConvertTo(context, culture, v, destinationtype);
                }
                public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
                {
                    return false;
                }        }
    [DefaultValue("FA"), Category("FFF"), Description("属性"), ReadOnlyAttribute(false), TypeConverter(typeof(propertygridcomboboxitem))]
            public class propertygridcomboboxitem : Dest.MyAttribControl.MyComboBox
            {
            public override void GetConvertHash()
            {
            _hash.Add("0", "炒肝");
           _hash.Add("1", "豆汁");
                         _hash.Add("2", "灌肠");
              }
              }
      

  4.   

    上一楼的代码
    Hashtable表的Key与Value好像弄反了,我是想在ComBox下拉列表中显示Hashtable的Key,程序所使用的是Hashtable的Value,因为可能会有多种类型的数据要在下拉列表里选择,例如要把bool型的true值在ComBox下拉列表显示成“删除”等。
    照楼上的试了下,好像还是不行。
      

  5.   

    我错了, 你从 EnumConverter 派生试试
      

  6.   

    刚才看了一下 PropertyGrid 相关源码, 双击取下一个值的确是通过 TypeConverter 实现的.ndp\fx\src\WinForms\Managed\System\WinForms\PropertyGridInternal 目录下的:
    PropertyGridView.cs 函数 DoubleClickRow 调用了
    GridEntry.cs GetPropertyValueList 来获得 TypeConverter
      

  7.   

    请lz参考下面的实现:
    public class ComboBoxItemTypeConvert : TypeConverter
    {
        private ArrayList _values = null;
        public ComboBoxItemTypeConvert()
        {
            this._values = new ArrayList();
            this._values.Add("零");
            this._values.Add("一");
            this._values.Add("二");
            this._values.Add("三");
            this._values.Add("四");
            this._values.Sort();
        }    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }    public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            return new StandardValuesCollection(this._values);
        }    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
                return true;        return base.CanConvertFrom(context, sourceType);
        }    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is string)
            {
                return value.ToString();
            }
            return base.ConvertFrom(context, culture, value);
        }
    }public partial class UserControl1 : UserControl
    {
        ...
        private string theCountry;
        [TypeConverter(typeof(ComboBoxItemTypeConvert))]
        public string Country
        {
            get
            {
                return theCountry;
            }
            set
            {
                theCountry = value;
            }
        }
    }
    实现在属性浏览器中提供标准值下拉列表的简单类型转换器
    1、定义一个从 TypeConverter 派生的类。
    2、重写 GetStandardValuesSupported 方法并返回 true。
    3、重写 GetStandardValues 方法并返回包含属性类型标准值的 TypeConverter..::.StandardValuesCollection。属性的标准值       必须与属性自身的类型一致。
    4、重写 CanConvertFrom 方法并为类型字符串的 sourceType 参数值返回 true。
    5、重写 ConvertFrom 方法并基于 value 参数返回相应的属性值。
    6、将指示类型转换器类型的 TypeConverterAttribute 应用于要为其提供一组标准值的类型。lz出现问题的关键是上面的第三点。
      

  8.   

    楼上说的是
    重点是第3点,属性的标准值的集合必须与属性自身的类型一致,
    但是,程序本身的需要是ComBox下拉显示的是string类型的,而取得的值要是object类型的
    就像bool型一样,它的值只有ture和false,但是ComBox下拉时要显示成“是”与“否”,或者显示成“删除”,“取消删除”等等。
    如果是要实现这样的功能,应该怎么弄呢?
    我贴的全部类的代码就是通过Hash表达到想要的这种效果,但是双击时就出现了以上的那个错误。
      

  9.   

    5楼说的从EnumConverter继承不行,EnumConverter的构造函数要传Enum类型参数
    如果是这样子,达不到想的的效果。
    程序本身的需要是ComBox下拉显示的是string类型的,而取得的值要是object类型的 
    就像bool型一样,它的值只有ture和false,但是ComBox下拉时要显示成“是”与“否”,或者显示成“删除”,“取消删除”等等
      

  10.   

    关于TypeConverter的使用方法可以参照7楼的实现方式;
    至于lz的问题我想可以改变一下设计或许会更好一些,以下的仅供参考:
    1、将类型定义为枚举;
    public enum TestEnum

        零 = 0,
        一,
        二,
        三,
        四,
    }private TestEnum test;
    [DefaultValue(typeof(TestEnum), "零")]
    public TestEnum TestEnu
    {
        get
        {
            return this.test;
        }
        set
        {
            this.test = value;
        }
    }2、在类中实现属性的赋值适配器;
      

  11.   

    比如说:
    “程序本身的需要是ComBox下拉显示的是string类型的,而取得的值要是object类型的”
    1、可以将“ComBox下拉显示的string”定义为枚举;
    2、根据枚举值来获取对应的obj;
    PS:可以先定义一个static的Dictionary来存储obj:
    private static Dictionary<TestEnum , “obj对应的class”> _values;
      

  12.   

    哦,最好是private static readonly Dictionary <TestEnum , “obj对应的class”> _values