动态可订制属性的 PropertyGrid(转载)
參考:http://bbs.csdn.net/topics/380095345
參考:http://bbs.csdn.net/topics/390331033
轉自:http://blog.csdn.net/akron/article/details/2750566
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
在VB6, VC++, C#.net?里都可以見到一個屬性設計器,用來編輯修改?object?的屬性。C#?下提供了一個屬性設計器?PropertyGrid,?其使用極其簡單,只要
?
??????grid.SelectedObject?=?myOjbect;
?
就可以把myOjbect?的所有屬性顯示出來。不過很多時候我們不希望如此,因為欠缺一種靈活性。我希望可以自由的控制需要編輯的內容。能做的這一點,再配合可編輯的?ListView,?可以很好的解決復雜內容的修改編輯問題。
?
首先是定義一個CProperty,?用來設置?object?在PropertyGrid?中的內容,?還得定義一個實現ICustomTypeDescriptor?接口的容器CPropertyCollection,?最后定制一個?PropertyDescriptor,?用來描述?PropertyGrid?接口方法。
?
?
???????public?class?CPropertyCollection?:?CCollection<CProperty>,?ICustomTypeDescriptor
???????{
??????????????public?void?Add(CProperty?value)
??????????????{
?????????????????????base.Put(value.Name, value);
??????????????}
?
??????????????#region?"TypeDescriptor"
?
??????????????public?String?GetClassName()
??????????????{
?????????????????????return?TypeDescriptor.GetClassName(this,?true);
??????????????}
?
??????????????public?AttributeCollection?GetAttributes()
??????????????{
?????????????????????return?TypeDescriptor.GetAttributes(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[] propDes?=?new?PropertyDescriptor[this.Count];
?????????????????????for?(int?i?=?0; i?<?this.Count; i++) {
????????????????????????????CProperty?prop?=?(CProperty)?this[i];
????????????????????????????propDes[i]?=?new?CPropertyDescriptor(ref?prop, attributes);
?????????????????????}
?????????????????????return?new?PropertyDescriptorCollection(propDes);
??????????????}
?
??????????????public?PropertyDescriptorCollection?GetProperties()
??????????????{
?????????????????????return?TypeDescriptor.GetProperties(this,?true);
??????????????}
?
??????????????public?object?GetPropertyOwner(PropertyDescriptor?pd)
??????????????{
?????????????????????return?this;
??????????????}
??????????????#endregion
???????}
?
???????public?class?CProperty
???????{
??????????????private?string?m_Name?=?string.Empty;
??????????????private?bool?m_bReadOnly?=?false;
??????????????private?bool?m_bVisible?=?true;
??????????????private?object?m_Value?=?null;
??????????????private?string?m_Category?=?string.Empty;
??????????????TypeConverter?m_Converter?=?null;
??????????????object?m_Editor?=?null;
?
?
??????????????public?CProperty(string?name,?object?value)
??????????????{
?????????????????????m_Name?=?name;
?????????????????????m_Value?=?value;
??????????????}
?
??????????????public?CProperty(string?name,?object?value,?bool?bReadOnly,?bool?bVisible)
??????????????{
?????????????????????m_Name?=?name;
?????????????????????m_Value?=?value;
?????????????????????m_bReadOnly?=?bReadOnly;
?????????????????????m_bVisible?=?bVisible;
??????????????}
?
??????????????public?bool?ReadOnly
??????????????{
?????????????????????get?{?return?m_bReadOnly; }
?????????????????????set?{ m_bReadOnly?=?value; }
??????????????}
?
??????????????public?virtual?TypeConverter?Converter
??????????????{
?????????????????????get?{?return?m_Converter; }
?????????????????????set?{ m_Converter?=?value; }
??????????????}
?
??????????????public?string?Name
??????????????{
?????????????????????get?{?return?m_Name; }
?????????????????????set?{ m_Name?=?value; }
??????????????}
?
??????????????public?bool?Visible
??????????????{
?????????????????????get?{?return?m_bVisible; }
?????????????????????set?{ m_bVisible?=?value; }
??????????????}
?
??????????????public?virtual?object?Value
??????????????{
?????????????????????get?{?return?m_Value; }
?????????????????????set?{ m_Value?=?value; }
??????????????}
?
??????????????public?string?Category
??????????????{
?????????????????????get?{?return?m_Category; }
?????????????????????set?{ m_Category?=?value; }
??????????????}
?
??????????????public?virtual?object?Editor
??????????????{
?????????????????????get?{?return?m_Editor; }
?????????????????????set?{ m_Editor?=?value;??}
??????????????}
???????}
?
?
???????public?class?CPropertyDescriptor?:?PropertyDescriptor
???????{
??????????????CProperty?m_Property;
?
??????????????public?CPropertyDescriptor(ref?CProperty?property,?Attribute[] attrs)
?????????????????????:?base(property.Name, attrs)
??????????????{
?????????????????????m_Property?=?property;
??????????????}
?
??????????????#region?PropertyDescriptor "region"
?
??????????????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.Name; }
??????????????}
?
??????????????public?override?bool?IsReadOnly
??????????????{
?????????????????????get?{?return?m_Property.ReadOnly; }
??????????????}
?
??????????????public?override?TypeConverter?Converter
??????????????{
?????????????????????get?{?return?m_Property.Converter; }
??????????????}
?
??????????????public?override?void?ResetValue(object?component)
??????????????{
??????????????}
?
??????????????public?override?bool?ShouldSerializeValue(object?component)
??????????????{
?????????????????????return?false;
??????????????}
?
??????????????public?override?void?SetValue(object?component,?object?value)
??????????????{
?????????????????????m_Property.Value?=?value;
??????????????}
?
??????????????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
???????}
?
?
?
下面的事情變得很簡單:
?
???????private?void?Form_Load(object?sender,?EventArgs?e)
??????????????{
?????????????????????CProperty?myProp1?=?new?CProperty("Test1",?"test");
?????????????????????MyProp1.Category?=?"test";
?????????????????????CProperty?myProp2?=?new?CProperty("Test2",?1);
?????????????????????myProp2.Editor = new System.Drawing.Design.ColorEditor();
?????????????????????myProperties.Add(myProp1);
?????????????????????myProperties.Add(myProp2);
?????????????????????grid.SelectedObject?=?myProperties;
??????????????}
?
?
可以看到通過CProperty.Editor?可以使用各種的編輯器,甚至自定義的編輯器(從?UITypeEditor?派生,msdn中有例子)。另一個要點是CProperty.Converter,?用來自定義如何進行類型轉換,例如,enum?類型在PropertyGrid?中用?List?編輯,如果不想事先定義一個?enum,?可以用自己的?TypeConverter?來實現功能更強大的編輯方法。
?
???????public?class?ListConverter?:?StringConverter
???????{
??????????????object[] m_Objects;
??????????????public?ListConverter(object[] objects)
??????????????{
?????????????????????m_Objects?=?objects;
??????????????}
?
??????????????public?override?bool?GetStandardValuesSupported(ITypeDescriptorContext?context)
??????????????{
?????????????????????return?true;
??????????????}
??????????????public?override?bool?GetStandardValuesExclusive(ITypeDescriptorContext?context)
??????????????{
?????????????????????return?true;
??????????????}
?
??????????????public?override
??????????????System.ComponentModel.TypeConverter.StandardValuesCollection?GetStandardValues(ITypeDescriptorContext?context)
??????????????{
?????????????????????return?new?StandardValuesCollection(m_Objects);
??????????????}
???????}?
?
使用ListConverter:
?
????????????CProperty?myProp?=?new?CProperty("Test",?"test2");
????????????myProp.Converter?=?new?ListConverter(new?string[] {?"test1",?"test2","test3"?});
?
?
當click?屬性?Test?時,會彈出一個?List?框。重載?TypeConverter?的?ConvertTo and ConvertFrom?可以獲得更多的功能。
轉載于:https://www.cnblogs.com/Joetao/articles/5432316.html
總結
以上是生活随笔為你收集整理的动态可订制属性的 PropertyGrid(转载)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Unity Standard Asset
- 下一篇: 懒加载中进行字典转模型