C#自定义PropertyGrid属性

本文详细介绍了PropertyGrid控件的基本使用方法,包括属性的普通显示和自定义显示,以及如何利用特性更改属性的显示方式。此外,还深入探讨了如何通过自定义类型转换器和属性编辑器来增强控件的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近用到了PropertyGrid,原来从来没用到过,拿在手里,一头雾水,经过一段时间研究后,大概理解了Property的使用方法,下面仔细剖析一下。

PropertyGrid控件就是Visual Studio开发工具里面的属性浏览器,我们在VS里面可以通过属性浏览器查看,修改控件的属性,并主要通过使用反射来检索项目的属性。
一.如何显示属性
1)普通显示
在PropertyGrid中显示属性很容易,我们可以直接给propertyGrid1.SelectedObject属性赋值,SelectObject属性可以获取或设置当前选定的对象,数据类型为object,这就意味着我们可以直接将一个对象赋给它。针对一个对象,它会将对象中的所有公共属性显示在PropertyGrid上。假如我们定义一个Station类,如下
[csharp] view plaincopy
public class Station   
   {  
       private string _StationName;  
       private double _Lon = 103;  
       private double _Lat = 38;  
       private Color _color;  
       private string _file = string.Empty;  
       private Font _font;  
       public string FileName  
       {  
           get { return _file; }  
           set { _file = value; }  
       }  
       public Color Color  
       {  
           get { return _color; }  
           set { _color = value; }  
       }  
       public Font Font  
       {  
           get { return _font; }  
           set { _font = value; }  
       }  
       public string StationName  
       {  
           get { return _StationName; }  
           set { _StationName = value; }  
       }  
       public double Lon  
       {  
           get { return _Lon; }  
           set { _Lon = value; }  
       }  
       public double Lat  
       {  
           get { return _Lat; }  
           set { _Lat = value; }  
       }  
   }  
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
public class Station   
   {  
       private string _StationName;  
       private double _Lon = 103;  
       private double _Lat = 38;  
       private Color _color;  
       private string _file = string.Empty;  
       private Font _font;  
       public string FileName  
       {  
           get { return _file; }  
           set { _file = value; }  
       }  
       public Color Color  
       {  
           get { return _color; }  
           set { _color = value; }  
       }  
       public Font Font  
       {  
           get { return _font; }  
           set { _font = value; }  
       }  
       public string StationName  
       {  
           get { return _StationName; }  
           set { _StationName = value; }  
       }  
       public double Lon  
       {  
           get { return _Lon; }  
           set { _Lon = value; }  
       }  
       public double Lat  
       {  
           get { return _Lat; }  
           set { _Lat = value; }  
       }  
   }  
然后在窗体中拖拉一个PropertyGrid控件propertygrid1,在Form_load中代码如下
[csharp] view plaincopy
private void Form1_Load(object sender, EventArgs e)  
{  
  Station s=new Station();  
  propertygrid1.SelectObject=s;  
}  
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
private void Form1_Load(object sender, EventArgs e)  
{  
  Station s=new Station();  
  propertygrid1.SelectObject=s;  
}  
我们就可以看到如下效果:
我们看到属性名显示都是英文,那样很不方便阅读如果我们像显示中文,该如何实现呢?
更改了显示方式
要更改某些属性的显示方式,您可以对这些属性应用不同的特性。特性是用于为类型、字段、方法和属性等编程元素添加批注的声明标记,在运行时可以使用反射对其进行检索。下面列出了其中的一部分:
DescriptionAttribute - 设置显示在属性下方说明帮助窗格中的属性文本。这是一种为活动属性(即具有焦点的属性)提供帮助文本的有效方法。
CategoryAttribute - 设置属性在网格中所属的类别。当您需要将属性按类别名称分组时,此特性非常有用。如果没有为属性指定类别,该属性将被分配给杂项 类别。可以将此特性应用于所有属性。
BrowsableAttribute –  表示是否在网格中显示属性。此特性可用于在网格中隐藏属性。默认情况下,公共属性始终显示在网格中。
ReadOnlyAttribute –  表示属性是否为只读。此特性可用于禁止在网格中编辑属性。默认情况下,带有 get 和 set 访问函数的公共属性在网格中是可以编辑的。
DefaultValueAttribute –  表示属性的默认值。如果希望为属性提供默认值,然后确定该属性值是否与默认值相同,则可使用此特性。可以将此特性应用于所有属性。
DefaultPropertyAttribute –  表示类的默认属性。在网格中选择某个类时,将首先突出显示该类的默认属性。
下面我们在Station类中的属性Lon上方添加[CategoryAttribute("坐标"),DisplayNameAttribute("经度")],效果如下:
如果想要在属性表中添加颜色选择和字体选择那是很容易一件事,可以在Station类中添加Color类型属性,和Font类型属性,绑定后,就可以进行颜色选择和字体选择了,代码在Station中已经实现。
2)自定义显示
我们可以看出这种上面这种显示属性方法并不够灵活,我们不能方便的及时增加或者删除属性。
   //属性表管理类
[csharp] view plaincopy
<span style="font-size: 13px;"> public class PropertyManageCls : CollectionBase, ICustomTypeDescriptor  
    {  
        public void Add(Property value)  
        {  
            int flag=-1;  
            if (value != null)  
            {  
                if (base.List.Count>0)  
                {  
                    IList <Property> mList=new List<Property>();  
                    for (int i = 0; i < base.List.Count; i++)  
                    {  
                        Property p = base.List[i] as Property;  
                        if (value.Name == p.Name)  
                        {  
                            flag = i;  
                        }  
                        mList.Add(p);  
                    }  
                    if (flag == -1)  
                    {  
                        mList.Add(value);  
                    }  
                    base.List.Clear();  
                    foreach (Property p in mList)  
                    {  
                        base.List.Add(p);  
                    }  
                }  
                else  
                {  
                    base.List.Add(value);  
                }  
            }  
        }  
        public void Remove(Property value)  
        {  
            if(value!=null&&base.List.Count>0)  
            base.List.Remove(value);  
        }  
        public Property this[int index]  
        {  
            get  
            {  
                return (Property)base.List[index];  
            }  
            set  
            {  
                base.List[index] = (Property)value;  
            }  
        }  
        #region ICustomTypeDescriptor 成员  
        public AttributeCollection GetAttributes()  
        {  
            return TypeDescriptor.GetAttributes(this,true);  
        }  
        public string GetClassName()  
        {  
            return TypeDescriptor.GetClassName(this, true);  
        }  
        public string GetComponentName()  
        {  
            return TypeDescriptor.GetComponentName(this, true);  
        }  
        public TypeConverter GetConverter()  
        {  
            return TypeDescriptor.GetConverter(this, true);  
        }  
        public EventDescriptor GetDefaultEvent()  
        {  
            return TypeDescriptor.GetDefaultEvent(this, true);  
        }  
        public PropertyDescriptor GetDefaultProperty()  
        {  
            return TypeDescriptor.GetDefaultProperty(this, true);  
        }  
        public object GetEditor(Type editorBaseType)  
        {  
            return TypeDescriptor.GetEditor(this, editorBaseType, true);  
        }  
        public EventDescriptorCollection GetEvents(Attribute[] attributes)  
        {  
            return TypeDescriptor.GetEvents(this, attributes, true);  
        }  
        public EventDescriptorCollection GetEvents()  
        {  
            return TypeDescriptor.GetEvents(this,true);  
        }  
        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)  
        {  
            PropertyDescriptor[] newProps = new PropertyDescriptor[this.Count];  
            for (int i = 0; i < this.Count; i++)  
            {  
                Property prop = (Property)this[i];  
                newProps[i] = new CustomPropertyDescriptor(ref prop, attributes);  
            }  
            return new PropertyDescriptorCollection(newProps);  
        }  
        public PropertyDescriptorCollection GetProperties()  
        {  
            return TypeDescriptor.GetProperties(this, true);  
        }  
        public object GetPropertyOwner(PropertyDescriptor pd)  
        {  
            return this;          
        }  
        #endregion  
    }  
//属性类  
    public class Property  
    {  
        private string _name=string.Empty;  
        private object _value=null;  
        private bool _readonly=false;  
        private bool _visible=true;  
        private string _category=string.Empty;  
        TypeConverter _converter=null;  
        object _editor = null;  
        private string _displayname = string.Empty;  
        public Property(string sName, object sValue)  
        {  
            this._name = sName;  
            this._value = sValue;  
        }  
        public Property(string sName, object sValue, bool sReadonly, bool sVisible)  
        {  
            this._name = sName;  
            this._value = sValue;  
            this._readonly = sReadonly;  
            this._visible = sVisible;  
        }  
        public string Name  //获得属性名  
        {  
            get  
            {  
                return _name;  
            }  
            set  
            {  
                _name=value;  
            }  
        }  
        public string DisplayName   //属性显示名称  
        {  
            get  
            {  
                return _displayname;  
            }  
            set  
            {  
                _displayname = value;  
            }  
        }  
        public TypeConverter Converter  //类型转换器,我们在制作下拉列表时需要用到  
        {  
            get   
            {  
                return _converter;  
            }  
            set  
            {  
                _converter = value;  
            }  
        }  
        public string Category  //属性所属类别  
        {  
            get  
            {  
                return _category;  
            }  
            set  
            {  
                _category = value;  
            }  
        }  
        public object Value  //属性值  
        {  
            get  
            {  
                return _value;  
            }  
            set  
            {  
                _value=value;  
            }  
        }  
        public bool ReadOnly  //是否为只读属性  
        {  
            get  
            {  
                return _readonly;  
            }  
            set  
            {  
                _readonly = value;  
            }  
        }  
        public bool Visible  //是否可见  
        {  
            get  
            {  
                return _visible;  
            }  
            set  
            {  
                _visible = value;  
            }  
        }  
        public virtual object Editor   //属性编辑器  
        {  
            get   
            {   
                return _editor;   
            }  
            set   
            {   
                _editor = value;   
            }  
        }  
    }  
    public class CustomPropertyDescriptor : PropertyDescriptor  
    {  
        Property m_Property;  
        public CustomPropertyDescriptor(ref Property myProperty, Attribute[] attrs)  
            : base(myProperty.Name, attrs)  
        {  
            m_Property = myProperty;  
        }  
        #region PropertyDescriptor 重写方法  
        public override bool CanResetValue(object component)  
        {  
            return false;  
        }  
        public override Type ComponentType  
        {  
            get  
            {  
                return null;  
            }  
        }  
        public override object GetValue(object component)  
        {  
            return m_Property.Value;  
        }  
        public override string Description  
        {  
            get  
            {  
                return m_Property.Name;  
            }  
        }  
        public override string Category  
        {  
            get  
            {  
                return m_Property.Category;  
            }  
        }  
        public override string DisplayName  
        {  
            get  
            {  
                return m_Property.DisplayName!=""?m_Property.DisplayName:m_Property.Name;  
            }  
        }  
        public override bool IsReadOnly  
        {  
            get  
            {  
                return m_Property.ReadOnly;  
            }  
        }  
        public override void ResetValue(object component)  
        {  
            //Have to implement  
        }  
        public override bool ShouldSerializeValue(object component)  
        {  
            return false;  
        }  
        public override void SetValue(object component, object value)  
        {  
            m_Property.Value = value;  
        }  
        public override TypeConverter Converter  
        {  
            get  
            {  
                return m_Property.Converter;  
            }  
        }  
        public override Type PropertyType  
        {  
            get { return m_Property.Value.GetType(); }  
        }  
        public override object GetEditor(Type editorBaseType)  
        {  
            return m_Property.Editor==null? base.GetEditor(editorBaseType):m_Property.Editor;  
        }  
        #endregion  
    }</span>  
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
<span style="font-size: 13px;"> public class PropertyManageCls : CollectionBase, ICustomTypeDescriptor  
    {  
        public void Add(Property value)  
        {  
            int flag=-1;  
            if (value != null)  
            {  
                if (base.List.Count>0)  
                {  
                    IList <Property> mList=new List<Property>();  
                    for (int i = 0; i < base.List.Count; i++)  
                    {  
                        Property p = base.List[i] as Property;  
                        if (value.Name == p.Name)  
                        {  
                            flag = i;  
                        }  
                        mList.Add(p);  
                    }  
                    if (flag == -1)  
                    {  
                        mList.Add(value);  
                    }  
                    base.List.Clear();  
                    foreach (Property p in mList)  
                    {  
                        base.List.Add(p);  
                    }  
                }  
                else  
                {  
                    base.List.Add(value);  
                }  
            }  
        }  
        public void Remove(Property value)  
        {  
            if(value!=null&&base.List.Count>0)  
            base.List.Remove(value);  
        }  
        public Property this[int index]  
        {  
            get  
            {  
                return (Property)base.List[index];  
            }  
            set  
            {  
                base.List[index] = (Property)value;  
            }  
        }  
        #region ICustomTypeDescriptor 成员  
        public AttributeCollection GetAttributes()  
        {  
            return TypeDescriptor.GetAttributes(this,true);  
        }  
        public string GetClassName()  
        {  
            return TypeDescriptor.GetClassName(this, true);  
        }  
        public string GetComponentName()  
        {  
            return TypeDescriptor.GetComponentName(this, true);  
        }  
        public TypeConverter GetConverter()  
        {  
            return TypeDescriptor.GetConverter(this, true);  
        }  
        public EventDescriptor GetDefaultEvent()  
        {  
            return TypeDescriptor.GetDefaultEvent(this, true);  
        }  
        public PropertyDescriptor GetDefaultProperty()  
        {  
            return TypeDescriptor.GetDefaultProperty(this, true);  
        }  
        public object GetEditor(Type editorBaseType)  
        {  
            return TypeDescriptor.GetEditor(this, editorBaseType, true);  
        }  
        public EventDescriptorCollection GetEvents(Attribute[] attributes)  
        {  
            return TypeDescriptor.GetEvents(this, attributes, true);  
        }  
        public EventDescriptorCollection GetEvents()  
        {  
            return TypeDescriptor.GetEvents(this,true);  
        }  
        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)  
        {  
            PropertyDescriptor[] newProps = new PropertyDescriptor[this.Count];  
            for (int i = 0; i < this.Count; i++)  
            {  
                Property prop = (Property)this[i];  
                newProps[i] = new CustomPropertyDescriptor(ref prop, attributes);  
            }  
            return new PropertyDescriptorCollection(newProps);  
        }  
        public PropertyDescriptorCollection GetProperties()  
        {  
            return TypeDescriptor.GetProperties(this, true);  
        }  
        public object GetPropertyOwner(PropertyDescriptor pd)  
        {  
            return this;          
        }  
        #endregion  
    }  
//属性类  
    public class Property  
    {  
        private string _name=string.Empty;  
        private object _value=null;  
        private bool _readonly=false;  
        private bool _visible=true;  
        private string _category=string.Empty;  
        TypeConverter _converter=null;  
        object _editor = null;  
        private string _displayname = string.Empty;  
        public Property(string sName, object sValue)  
        {  
            this._name = sName;  
            this._value = sValue;  
        }  
        public Property(string sName, object sValue, bool sReadonly, bool sVisible)  
        {  
            this._name = sName;  
            this._value = sValue;  
            this._readonly = sReadonly;  
            this._visible = sVisible;  
        }  
        public string Name  //获得属性名  
        {  
            get  
            {  
                return _name;  
            }  
            set  
            {  
                _name=value;  
            }  
        }  
        public string DisplayName   //属性显示名称  
        {  
            get  
            {  
                return _displayname;  
            }  
            set  
            {  
                _displayname = value;  
            }  
        }  
        public TypeConverter Converter  //类型转换器,我们在制作下拉列表时需要用到  
        {  
            get   
            {  
                return _converter;  
            }  
            set  
            {  
                _converter = value;  
            }  
        }  
        public string Category  //属性所属类别  
        {  
            get  
            {  
                return _category;  
            }  
            set  
            {  
                _category = value;  
            }  
        }  
        public object Value  //属性值  
        {  
            get  
            {  
                return _value;  
            }  
            set  
            {  
                _value=value;  
            }  
        }  
        public bool ReadOnly  //是否为只读属性  
        {  
            get  
            {  
                return _readonly;  
            }  
            set  
            {  
                _readonly = value;  
            }  
        }  
        public bool Visible  //是否可见  
        {  
            get  
            {  
                return _visible;  
            }  
            set  
            {  
                _visible = value;  
            }  
        }  
        public virtual object Editor   //属性编辑器  
        {  
            get   
            {   
                return _editor;   
            }  
            set   
            {   
                _editor = value;   
            }  
        }  
    }  
    public class CustomPropertyDescriptor : PropertyDescriptor  
    {  
        Property m_Property;  
        public CustomPropertyDescriptor(ref Property myProperty, Attribute[] attrs)  
            : base(myProperty.Name, attrs)  
        {  
            m_Property = myProperty;  
        }  
        #region PropertyDescriptor 重写方法  
        public override bool CanResetValue(object component)  
        {  
            return false;  
        }  
        public override Type ComponentType  
        {  
            get  
            {  
                return null;  
            }  
        }  
        public override object GetValue(object component)  
        {  
            return m_Property.Value;  
        }  
        public override string Description  
        {  
            get  
            {  
                return m_Property.Name;  
            }  
        }  
        public override string Category  
        {  
            get  
            {  
                return m_Property.Category;  
            }  
        }  
        public override string DisplayName  
        {  
            get  
            {  
                return m_Property.DisplayName!=""?m_Property.DisplayName:m_Property.Name;  
            }  
        }  
        public override bool IsReadOnly  
        {  
            get  
            {  
                return m_Property.ReadOnly;  
            }  
        }  
        public override void ResetValue(object component)  
        {  
            //Have to implement  
        }  
        public override bool ShouldSerializeValue(object component)  
        {  
            return false;  
        }  
        public override void SetValue(object component, object value)  
        {  
            m_Property.Value = value;  
        }  
        public override TypeConverter Converter  
        {  
            get  
            {  
                return m_Property.Converter;  
            }  
        }  
        public override Type PropertyType  
        {  
            get { return m_Property.Value.GetType(); }  
        }  
        public override object GetEditor(Type editorBaseType)  
        {  
            return m_Property.Editor==null? base.GetEditor(editorBaseType):m_Property.Editor;  
        }  
        #endregion  
    }</span>  
下面我们来看看该如何使用,我们仍然在Form_load中添加代码如下:
[csharp] view plaincopy
<span style="font-size: 13px;">            PropertyManageCls pmc = new PropertyManageCls();  
            Property pp = new Property("ID", "1", false, true);  
            pp.Category = "基本信息";  
            pp.DisplayName = "我的ID";  
            pmc.Add(pp);  
            propertyGrid1.SelectObject=pmc;</span>  
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
<span style="font-size: 13px;">            PropertyManageCls pmc = new PropertyManageCls();  
            Property pp = new Property("ID", "1", false, true);  
            pp.Category = "基本信息";  
            pp.DisplayName = "我的ID";  
            pmc.Add(pp);  
            propertyGrid1.SelectObject=pmc;</span>  
显示结果:
我们可以看到上面的属性显示很简单,如果想要自定义一个下拉框,或者有一个路径选择的该怎么办呢。
1)类型转换器
要实现下拉框的方法:使用类型转换器,需要继承与TypeConverter或者StringConverter,然后重写方法,代码如下:
[csharp] view plaincopy
<span style="font-size: 13px;">    //下拉框类型转换器  
    public class DropDownListConverter : StringConverter  
    {  
        object[] m_Objects;  
        public DropDownListConverter(object[] objects)  
        {  
            m_Objects = objects;  
        }  
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)  
        {  
            return true;  
        }  
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)  
        {  
            return true;</span><span style='color: rgb(0, 130, 0); line-height: 15.39px; font-family: Consolas, "Bitstream Vera Sans Mono", "Courier New", Courier, monospace; font-size: 14px;'>//true下拉框不可编辑</span><span style="font-size: 13px;">  
</span><span style="font-size: 13px;">  
        }  
        public override  
        System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)  
        {  
            return new StandardValuesCollection(m_Objects);//我们可以直接在内部定义一个数组,但并不建议这样做,这样对于下拉框的灵活             //性有很大影响  
        }  
    }</span>  
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
<span style="font-size: 13px;">    //下拉框类型转换器  
    public class DropDownListConverter : StringConverter  
    {  
        object[] m_Objects;  
        public DropDownListConverter(object[] objects)  
        {  
            m_Objects = objects;  
        }  
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)  
        {  
            return true;  
        }  
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)  
        {  
            return true;</span><span style="font-family:Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace;font-size:14px;color:#0820;line-height: 15.39px;">//true下拉框不可编辑</span><span style="font-size: 13px;">  
</span><span style="font-size: 13px;">  
        }  
        public override  
        System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)  
        {  
            return new StandardValuesCollection(m_Objects);//我们可以直接在内部定义一个数组,但并不建议这样做,这样对于下拉框的灵活             //性有很大影响  
        }  
    }</span>  
我们实现了下拉框类型转换器,但该如何使用呢?
使用方法一:我们仍然以Station类作为例子,在属性上方添加标记[TypeConverter(typeof(DropDownListConverter))],但在这种情况下,我们需要预先在DropDownListConverter中定义下拉框内容。
使用方法二:这种方法我们可以在外部定义数组,使用方便,使用方法代码如下:
[csharp] view plaincopy
<span style="color: rgb(51, 51, 51); font-family: Arial;"><span style="font-size: 13px;">        private void Form_load(object sender, EventArgs e)  
        {  
                PropertyManageCls pmc = new PropertyManageCls();  
                string []s=new string[] { "1", "2", "3", "4" };  
                Property pp = new Property(txtname.Text,txtvalue.Text, false, true);  
                pp.Category = "基本信息";  
                pp.DisplayName = "我的ID";  
                pp.Converter = new DropDownListConverter(s);//Property的Converter属性就可以设置类型转换  
                pmc.Add(pp);  
                propertyGrid1.SelectObject = pmc;  
    }</span></span>  
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
<span style="font-family:Arial;color:#333333;"><span style="font-size: 13px;">        private void Form_load(object sender, EventArgs e)  
        {  
                PropertyManageCls pmc = new PropertyManageCls();  
                string []s=new string[] { "1", "2", "3", "4" };  
                Property pp = new Property(txtname.Text,txtvalue.Text, false, true);  
                pp.Category = "基本信息";  
                pp.DisplayName = "我的ID";  
                pp.Converter = new DropDownListConverter(s);//Property的Converter属性就可以设置类型转换  
                pmc.Add(pp);  
                propertyGrid1.SelectObject = pmc;  
    }</span></span>  
效果图:


2)属性编辑器
使用属性编辑器实现路径选择:属性编辑器需要继承与UITypeEditor
[csharp] view plaincopy
<span style="font-size: 13px;">//文件路径选择                                                                                                                       public class PropertyGridFileItem : UITypeEditor  
    {  
  
        public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)  
        {  
  
            return UITypeEditorEditStyle.Modal;  
  
        }  
  
        public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.  
  
IServiceProvider provider, object value)  
        {  
  
            IWindowsFormsEditorService edSvc =  
                (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));  
  
            if (edSvc != null)  
            {  
  
                // 可以打开任何特定的对话框  
  
                OpenFileDialog dialog = new OpenFileDialog();  
  
                dialog.AddExtension = false;  
  
                if (dialog.ShowDialog().Equals(DialogResult.OK))  
                {  
  
                    return dialog.FileName;  
  
                }  
            }  
  
            return value;  
  
        }  
  
    }</span>  
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
<span style="font-size: 13px;">//文件路径选择                                                                                                                       public class PropertyGridFileItem : UITypeEditor  
    {  
  
        public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)  
        {  
  
            return UITypeEditorEditStyle.Modal;  
  
        }  
  
        public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.  
  
IServiceProvider provider, object value)  
        {  
  
            IWindowsFormsEditorService edSvc =  
                (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));  
  
            if (edSvc != null)  
            {  
  
                // 可以打开任何特定的对话框  
  
                OpenFileDialog dialog = new OpenFileDialog();  
  
                dialog.AddExtension = false;  
  
                if (dialog.ShowDialog().Equals(DialogResult.OK))  
                {  
  
                    return dialog.FileName;  
  
                }  
            }  
  
            return value;  
  
        }  
  
    }</span>  
使用方法一:以Station类为例,在属性上方添加标记[EditorAttribute(typeof(PropertyGridFileItem),
 typeof(System.Drawing.Design.UITypeEditor))],然后将PropertyGrid的SelectObject等于Station实例就可以了;
使用方法二:使用方法代码如下:
[csharp] view plaincopy
<span style="font-size: 13px;">        private void Form_load(object sender, EventArgs e)  
        {  
                PropertyManageCls pmc = new PropertyManageCls();  
                Property pp = new Property(txtname.Text,txtvalue.Text, false, true);  
                pp.Category = "基本信息";  
                pp.DisplayName = "我的ID";  
                pp.Editor= new PropertyGridFileItem();//Property的Editor属性就可以设置属性编辑  
                pmc.Add(pp);  
                propertyGrid1.SelectObject = pmc;  
    }</span>  
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
<span style="font-size: 13px;">        private void Form_load(object sender, EventArgs e)  
        {  
                PropertyManageCls pmc = new PropertyManageCls();  
                Property pp = new Property(txtname.Text,txtvalue.Text, false, true);  
                pp.Category = "基本信息";  
                pp.DisplayName = "我的ID";  
                pp.Editor= new PropertyGridFileItem();//Property的Editor属性就可以设置属性编辑  
                pmc.Add(pp);  
                propertyGrid1.SelectObject = pmc;  
    }</span>  
效果图如下:
通过以上方法我们可以满足一些基本需求想要了解更多,可以看以下链接:
PropertyGrid控件心得
http://blog.youkuaiyun.com/luyifeiniu/article/details/5426960#创建 PropertyGrid 控件
Customized display of collection data in a PropertyGrid
http://www.codeproject.com/KB/tabs/customizingcollectiondata.aspx
TypeConverter的层次结构
http://msdn.microsoft.com/en-us/library/8cexyz1e
关于PropertyGrid中属性的值动态从数据库取出
http://topic.youkuaiyun.com/u/20100827/11/5524219a-4457-4921-b8f2-b4c63bc6b016.html
动态可订制属性的 PropertyGrid
http://blog.youkuaiyun.com/akron/article/details/2750566
转自http://blog.youkuaiyun.com/lxping1012/article/details/7073944

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值