netPropertyGrid动态生成属性页文档格式.docx
- 文档编号:19727234
- 上传时间:2023-01-09
- 格式:DOCX
- 页数:17
- 大小:100.27KB
netPropertyGrid动态生成属性页文档格式.docx
《netPropertyGrid动态生成属性页文档格式.docx》由会员分享,可在线阅读,更多相关《netPropertyGrid动态生成属性页文档格式.docx(17页珍藏版)》请在冰豆网上搜索。
get{returntheId;
}
set{theId=value;
publicstringCategory
get{returntheCategory;
set{theCategory=value;
publicboolReadOnly
get{returntheReadOnly;
set{theReadOnly=value;
publicstringName
get{returnthis.theName;
set{this.theName=value;
publicobjectValue
get{returnthis.theValue;
set{this.theValue=value;
publicstringDescription
get{returntheDescription;
set{theDescription=value;
publicSystem.TypeProType
get{returntheType;
set{theType=value;
publicboolBrowsable
get{returntheBrowsable;
set{theBrowsable=value;
publicvirtualTypeConverterConverter
get{returntheConverter;
set{theConverter=value;
我举一个例子:
privatestringstrdemo;
[DescriptionAttribute("
用于举例说明"
),
CategoryAttribute("
公有属性"
DefaultValueAttribute(“测试属性”),
ReadOnlyAttribute(false),
BrowsableAttribute(true),
TypeConverter(typeof(MyComboTypeConvert))
]
public
stringstrDemo
{
get
return
strdemo;
}
set
strdemo
=
value;
这是个写死的属性,那在我的项目中,根据对象的不同,会需要生产不同的属性页,所以需要一个可以动态生成的属性页,将上述这个一般属性定义,利用XProp类,写成:
PrivateXPropnewXpro=newXProp();
newXpro.Category=”公有属性”;
newXpro.Name=”strDemo”;
newXpro.Id="
A"
newXpro.Description=“用于举例说明”;
newXpro.ReadOnly=false;
newXpro.Value=“测试属性”;
newXpro.ProType=typeof(string);
newXpro.Browsable=true;
newXpro.Converter=null;
这样,一条属性就完成了。
当然你也可以根据需要自己重写更多的属性相关定义。
这里的Converter属性是在后面的下拉菜单中需要用到的,如果不是基础类型的(string,int,bool,enum等),我们可以赋值为null.
当然,这只是一条属性,原本按之前的方法,只要定义一个类,然后这个类里面定义多条属性就可以了。
但是现在,由于属性是动态生成的,我们并不能确定需要几个属性,也就不能直接在一个类里面定义完。
所以我们需要再定义一个List<
XProp>
类,作为一一张list可以随意添加多个项,然后将PropertyGrid.SelectedObject设置为这个类就好了:
先来定义以下两个类:
publicclassXProps:
List<
ICustomTypeDescriptor
#regionICustomTypeDescriptor成员
publicAttributeCollectionGetAttributes()
returnTypeDescriptor.GetAttributes(this,true);
publicstringGetClassName()
returnTypeDescriptor.GetClassName(this,true);
publicstringGetComponentName()
returnTypeDescriptor.GetComponentName(this,true);
publicTypeConverterGetConverter()
returnTypeDescriptor.GetConverter(this,true);
publicEventDescriptorGetDefaultEvent()
returnTypeDescriptor.GetDefaultEvent(this,true);
publicPropertyDescriptorGetDefaultProperty()
returnTypeDescriptor.GetDefaultProperty(this,true);
publicobjectGetEditor(System.TypeeditorBaseType)
returnTypeDescriptor.GetEditor(this,editorBaseType,true);
publicEventDescriptorCollectionGetEvents(System.Attribute[]attributes)
returnTypeDescriptor.GetEvents(this,attributes,true);
publicEventDescriptorCollectionGetEvents()
returnTypeDescriptor.GetEvents(this,true);
publicPropertyDescriptorCollectionGetProperties(System.Attribute[]attributes)
ArrayListprops=newArrayList();
for(inti=0;
i<
this.Count;
i++)
//判断属性是否显示
if(this[i].Browsable==true)
XPropDescriptorpsd=newXPropDescriptor(this[i],attributes);
props.Add(psd);
}
PropertyDescriptor[]propArray=(PropertyDescriptor[])props.ToArray(typeof(PropertyDescriptor));
returnnewPropertyDescriptorCollection(propArray);
publicPropertyDescriptorCollectionGetProperties()
returnTypeDescriptor.GetProperties(this,true);
publicobjectGetPropertyOwner(PropertyDescriptorpd)
returnthis;
#endregion
publicoverridestringToString()
StringBuildersb=newStringBuilder();
sb.Append("
["
+i+"
]"
+this[i].ToString()+System.Environment.NewLine);
returnsb.ToString();
privateclassXPropDescriptor:
PropertyDescriptor
XProptheProp;
publicXPropDescriptor(XPropprop,Attribute[]attrs)
:
base(prop.Name,attrs)
theProp=prop;
publicoverrideboolCanResetValue(objectcomponent)
returnfalse;
publicoverridestringCategory
get{returntheProp.Category;
publicoverridestringDescription
get{returntheProp.Description;
publicoverrideTypeConverterConverter
get{returntheProp.Converter;
publicoverrideSystem.TypeComponentType
get{returnthis.GetType();
publicoverrideobjectGetValue(objectcomponent)
returntheProp.Value;
publicoverrideboolIsReadOnly
get{returntheProp.ReadOnly;
publicoverrideSystem.TypePropertyType
get{returntheProp.ProType;
publicoverridevoidResetValue(objectcomponent)
publicoverridevoidSetValue(objectcomponent,objectvalue)
theProp.Value=value;
publicoverrideboolShouldSerializeValue(objectcomponent)
然后我们新声明一个属性列表:
PrivateXPropsxprops=newXProps();
//再将刚刚那个动态生成的属性添加进去,将属性页的selectobject赋值为这个类:
xprops.add(newXpro);
PropertyGridDemo.SelectedObject=xprops;
现在我们来看看效果:
根据需要,你可以添加多条属性。
也许你会想问,这里哪有动态生成啊,那些属性名称,属性类型什么的不还是写死的么。
呵呵,我这里只是举个例子所以写死了,在实际应用中,你可以根据需要,在生成属性列表的时候,动态赋值,例如你是从xml文件里读取到的,例如你是从服务器中获取到的。
根据你读取的对象,一个一个赋值就可以了。
下面来介绍如何在属性页中动态生成下拉菜单框,关于下拉菜单真的是很复杂,在.net的PropertyGrid控件中,想要具有下拉菜单的属性,简单的可以通过枚举类型来实现,还是以刚刚的那个例子来说明:
首先定义个枚举类型:
publicenumenumType
{
BOOLVAL,
DIGITALVAL,
STRINGVAL,
CHECKVAL,
RATIOVAL,
IPVAL,
COMBOBOX,
RESETBTN
}
然后代码中将属性值与属性类型修改为:
newXpro.Value=CustomClass.enumType.BOOLVAL;
//这里的属性值当然必须为枚举中的某一项
newXpro.ProType=typeof(enumType);
然后我们来看看实现的效果:
这就是最简单的下拉菜单的实现方式了。
但是这里的枚举类型仍然是需要代码中写死的,而我在网上也所搜了很久,枚举类型似乎没办法动态生成,如果要实现动态生成恐怕要另寻他途。
所幸的是,我曾经见过重写combobox来生成属性页的下来菜单的,我们需要定义:
//重写下拉菜单中的项,使之与属性页的项关联
publicabstractclassComboBoxItemTypeConvert:
TypeConverter
publicHashtablemyhash=null;
publicComboBoxItemTypeConvert()
myhash=newHashtable();
GetConvertHash();
publicabstractvoidGetConvertHash();
//是否支持选择列表的编辑
publicoverrideboolGetStandardValuesSupported(ITypeDescriptorContextcontext)
returntrue;
//重写combobox的选择列表
publicoverrideStandardValuesCollectionGetStandardValues(ITypeDescriptorContextcontext)
int[]ids=newint[myhash.Values.Count];
inti=0;
foreach(DictionaryEntrymyDEinmyhash)
ids[i++]=(int)(myDE.Key);
returnnewStandardValuesCollection(ids);
//判断转换器是否可以工作
publicoverrideboolCanConvertFrom(ITypeDescriptorContextcontext,TypesourceType)
if(sourceType==typeof(string))
returnbase.CanConvertFrom(context,sourceType);
//重写转换器,将选项列表(即下拉菜单)中的值转换到该类型的值
publicoverrideobjectConvertFrom(ITypeDescriptorContextcontext,System.Globalization.CultureInfoculture,objectobj)
if(objisstring)
if(myDE.Value.Equals((obj.ToString())))
returnmyDE.Key;
returnbase.ConvertFrom(context,culture,obj);
publicoverrideboolCanConvertTo(ITypeDescriptorContextcontext,TypedestinationType)
if(destinationType==typeof(string))
returnbase.CanConvertTo(context,destinationType);
//重写转换器将该类型的值转换到选择列表中
publicoverrideobjectConvertTo(ITypeDescriptorContextcontext,System.Globalization.CultureInfoculture,objectobj,TypedestinationType)
if(myDE.Key.Equals(obj))
returnmyDE.Value.ToString();
return"
returnbase.ConvertTo(context,culture,obj,destinationType);
publicoverrideboolGetStandardValuesExclusive(ITypeDescriptorContextcontext)
//重写下拉菜单,在这里实现定义下拉菜单内的项
publicclassMyComboItemConvert:
ComboBoxItemTypeConvert
privateHashtablehash;
publicoverridevoidGetConvertHash()
try
myhash=hash;
catch
thrownewNotImplementedException();
publicMyComboItemConvert(stringstr)
hash=newHashtable();
string[]stest=str.Split('
'
);
stest.Length;
hash.Add(i,stest[i]);
value=0;
publicintvalue{get;
set;
publicMyComboItemConvert(stringstr,ints)
value=s;
在这里你可以看到,MyComboItemConvert有两个重载,分别有不同的参数,其中string类型的那个参数就是用于获取下拉菜单的项的。
当然你也可以根据需要定义为其他类型的,例如List或是HashTable。
只要在函数中将下拉菜单的每一项放入哈希表中就可以了。
而在生成的代码中,我们就需要用到刚刚没有使用的Converter属性了:
举个例子:
XPropsxps=newXProps();
XPropxprop=newXProp();
xprop.Name="
姓名"
xprop.Value="
某人;
xprop.Category="
人类"
xprop.Description="
姓甚名谁"
xprop.ProType=typeof(String);
xprop.ReadOnly=true;
xps.Add(xprop);
xprop=newXProp();
年龄"
xprop.ProType=typeof(int);
2"
多大年纪"
xprop.ReadOnly=false;
性别"
xprop.Value=1;
xprop.ProType=typeof(CustomClass.MyComboItemCo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- net PropertyGrid动态生成属性页 PropertyGrid 动态 生成 属性