.net PropertyGrid动态生成属性页x_第1页
.net PropertyGrid动态生成属性页x_第2页
.net PropertyGrid动态生成属性页x_第3页
.net PropertyGrid动态生成属性页x_第4页
.net PropertyGrid动态生成属性页x_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

对于这几个月的这个项目,一直想做个总结,但是鉴于本人记性之差,总是将这件事想起又忘记,终于在这个月工作的最后几天有了几天的空闲,把这个经验好好的记录下来。PropertyGrid,.net框架下的一个控件,这是一个软件升级的项目,原来的软件用的是C+,控件用的还是第三方,这次升级到visual studio .net4.0版本,原以为.net的东西用起来不会费劲的,没想到想要实现项目需要的效果还真没那么简单。由于需要,我这里主要是为了能动态的生成属性页,还要带能动态生成下来菜单,所以今天主要从这方面总结。首先定义一个属性类:/单条属性类 public class XProp private string theId = ; /属性Id,我的项目中需要,大家可以忽略 private string theCategory = ; /属性所属类别 private string theName = ; /属性名称 private bool theReadOnly = false; /属性的只读性,true为只读 private string theDescription = ; /属性的描述内容 private object theValue = null; /值 private System.Type theType = null; /类型 private bool theBrowsable = true; /显示或隐藏,true为显示 TypeConverter theConverter = null; /类型转换 public string Id get return theId; set theId = value; public string Category get return theCategory; set theCategory = value; public bool ReadOnly get return theReadOnly; set theReadOnly = value; public string Name get return this.theName; set this.theName = value; public object Value get return this.theValue; set this.theValue = value; public string Description get return theDescription; set theDescription = value; public System.Type ProType get return theType; set theType = value; public bool Browsable get return theBrowsable; set theBrowsable = value; public virtual TypeConverter Converter get return theConverter; set theConverter = value; 我举一个例子:private string strdemo;DescriptionAttribute(用于举例说明),CategoryAttribute(公有属性),DefaultValueAttribute(“测试属性”),ReadOnlyAttribute(false),BrowsableAttribute(true),TypeConverter(typeof(MyComboTypeConvert)publicstring strDemogetreturnstrdemo;setstrdemo=value;这是个写死的属性,那在我的项目中,根据对象的不同,会需要生产不同的属性页,所以需要一个可以动态生成的属性页,将上述这个一般属性定义,利用XProp类,写成:Private XProp newXpro = new XProp();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类,作为一一张list可以随意添加多个项,然后将PropertyGrid.SelectedObject设置为这个类就好了:先来定义以下两个类:public class XProps : List, ICustomTypeDescriptor #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(System.Type editorBaseType) return TypeDescriptor.GetEditor(this, editorBaseType, true); public EventDescriptorCollection GetEvents(System.Attribute attributes) return TypeDescriptor.GetEvents(this, attributes, true); public EventDescriptorCollection GetEvents() return TypeDescriptor.GetEvents(this, true); public PropertyDescriptorCollection GetProperties(System.Attribute attributes) ArrayList props = new ArrayList(); for (int i = 0; i this.Count; i+) /判断属性是否显示 if (thisi.Browsable = true) XPropDescriptor psd = new XPropDescriptor(thisi, attributes); props.Add(psd); PropertyDescriptor propArray = (PropertyDescriptor)props.ToArray(typeof(PropertyDescriptor); return new PropertyDescriptorCollection(propArray); public PropertyDescriptorCollection GetProperties() return TypeDescriptor.GetProperties(this, true); public object GetPropertyOwner(PropertyDescriptor pd) return this; #endregion public override string ToString() StringBuilder sb = new StringBuilder(); for (int i = 0; i this.Count; i+) sb.Append( + i + + thisi.ToString() + System.Environment.NewLine); return sb.ToString(); private class XPropDescriptor : PropertyDescriptor XProp theProp; public XPropDescriptor(XProp prop, Attribute attrs) : base(prop.Name, attrs) theProp = prop; public override bool CanResetValue(object component) return false; public override string Category get return theProp.Category; public override string Description get return theProp.Description; public override TypeConverter Converter get return theProp.Converter; public override System.Type ComponentType get return this.GetType(); public override object GetValue(object component) return theProp.Value; public override bool IsReadOnly get return theProp.ReadOnly; public override System.Type PropertyType get return theProp.ProType; public override void ResetValue(object component) public override void SetValue(object component, object value) theProp.Value = value; public override bool ShouldSerializeValue(object component) return false; 然后我们新声明一个属性列表:Private XProps xprops = new XProps();/再将刚刚那个动态生成的属性添加进去,将属性页的selectobject赋值为这个类:xprops.add(newXpro);PropertyGridDemo.SelectedObject = xprops;现在我们来看看效果:根据需要,你可以添加多条属性。也许你会想问,这里哪有动态生成啊,那些属性名称,属性类型什么的不还是写死的么。呵呵,我这里只是举个例子所以写死了,在实际应用中,你可以根据需要,在生成属性列表的时候,动态赋值,例如你是从xml文件里读取到的,例如你是从服务器中获取到的。根据你读取的对象,一个一个赋值就可以了。下面来介绍如何在属性页中动态生成下拉菜单框,关于下拉菜单真的是很复杂,在.net的PropertyGrid控件中,想要具有下拉菜单的属性,简单的可以通过枚举类型来实现,还是以刚刚的那个例子来说明:首先定义个枚举类型:public enum enumType BOOLVAL, DIGITALVAL, STRINGVAL, CHECKVAL, RATIOVAL, IPVAL, COMBOBOX, RESETBTN然后代码中将属性值与属性类型修改为:newXpro.Value = CustomClass.enumType.BOOLVAL; /这里的属性值当然必须为枚举中的某一项newXpro.ProType = typeof(enumType);然后我们来看看实现的效果:这就是最简单的下拉菜单的实现方式了。但是这里的枚举类型仍然是需要代码中写死的,而我在网上也所搜了很久,枚举类型似乎没办法动态生成,如果要实现动态生成恐怕要另寻他途。所幸的是,我曾经见过重写combobox来生成属性页的下来菜单的,我们需要定义:/重写下拉菜单中的项,使之与属性页的项关联 public abstract class ComboBoxItemTypeConvert : TypeConverter public Hashtable myhash = null; public ComboBoxItemTypeConvert() myhash = new Hashtable(); GetConvertHash(); public abstract void GetConvertHash(); /是否支持选择列表的编辑 public override bool GetStandardValuesSupported(ITypeDescriptorContext context) return true; /重写combobox的选择列表 public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) int ids = new intmyhash.Values.Count; int i = 0; foreach (DictionaryEntry myDE in myhash) idsi+ = (int)(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 obj) if (obj is string) foreach (DictionaryEntry myDE in myhash) if (myDE.Value.Equals(obj.ToString() return myDE.Key; return base.ConvertFrom(context, culture, obj); public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) if (destinationType = typeof(string) return true; return base.CanConvertTo(context, destinationType); /重写转换器将该类型的值转换到选择列表中 public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object obj, Type destinationType) if (destinationType = typeof(string) foreach (DictionaryEntry myDE in myhash) if (myDE.Key.Equals(obj) return myDE.Value.ToString(); return ; return base.ConvertTo(context, culture, obj, destinationType); public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) return false; /重写下拉菜单,在这里实现定义下拉菜单内的项public class MyComboItemConvert : ComboBoxItemTypeConvert private Hashtable hash; public override void GetConvertHash() try myhash = hash; catch throw new NotImplementedException(); public MyComboItemConvert(string str) hash = new Hashtable(); string stest = str.Split(,); for (int i = 0; i stest.Length; i+) hash.Add(i, stesti); GetConvertHash(); value = 0; public int value get; set; public MyComboItemConvert(string str,int s) hash = new Hashtable(); string stest = str.Split(,); for (int i = 0; i stest.Length; i+) hash.Add(i, stesti); GetConvertHash(); value = s; 在这里你可以看到,MyComboItemConvert有两个重载,分别有不同的参数,其中string类型的那个参数就是用于获取下拉菜单的项的。当然你也可以根据需要定义为其他类型的,例如List或是HashTable。只要在函数中将下拉菜单的每一项放入哈希表中 就可以了。而在生成的代码中,我们就需要用到刚刚没有使用的Converter属性了:举个例子:XPr

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论