.net2.0 PropertyGrid 显示中文后无法使用自定义的编辑器
2011-05-12 12:29 kwjlk 阅读(562) 评论(0) 编辑 收藏 举报.NET2.0中如何在PropertyGrid中显示中文,首先你要确认你不得不使用继承ICustomTypeDescriptor、继承PropertyDescriptor,继承UITyperEditor的方法。
然后使用之后发现不能调用自己定义的编辑器了?那么,希望下面的代码能够给你提供帮助。
解决办法核心:
主要在继承ICustomTypeDescriptor的类在重载GetProperties方法时,里面构造PropertyDescriptor子类时
需要传入 正确的属性集合。 代码,attributes = Attribute.GetCustomAttributes(p);。 具体实现看下面的代码
主要是因为 MemberDescriptor中GetEditor的实现,他是根据自身的Attributes查找是否有EditorAttribute
没有则使用默认的。而这个Atrrbutes是外界传入的。继承关系 你的PropertyDescriptor 继承 系统的PropertyDescriptor
系统的PropertyDescriptor 继承 系统的MemberDescriptor。
感谢.NET Reflector 网上好用的.NET Reflector 已经不多了,需要的可以邮件的。klvk.com@gmail.com
图片,左边有个按钮,能够调用我自定义的对话框。右边的则不会出现。
两份代码,一份既可以显示中文又可以调用自定义的编辑器,一份只能显示中文,不能调用自定义的编辑器。
public class MyTestClass : ICustomTypeDescriptor
{
#region 类内部变量
private string _Name = string.Empty;
[Editor(typeof(MyEditor),typeof(UITypeEditor))]
public string Name
{
get { return _Name; }
set { _Name = value; }
}
private int _Age = 0;
[Editor(typeof(MyEditor),typeof(UITypeEditor))]
public int Age
{
get { return _Age; }
set { _Age = value; }
}
#endregion
/// <summary>
/// 下面这段代码来源于:http://www.bluespace.cn/Html/Csdn/2_47/View_4702219.html
/// </summary>
/// <returns></returns>
#region ICustomTypeDescriptor 显式接口定义
#region 没什么特别改动的
AttributeCollection ICustomTypeDescriptor.GetAttributes()
{
return TypeDescriptor.GetAttributes(this, true);
}
string ICustomTypeDescriptor.GetClassName()
{
return TypeDescriptor.GetClassName(this, true);
}
string ICustomTypeDescriptor.GetComponentName()
{
return TypeDescriptor.GetComponentName(this, true);
}
TypeConverter ICustomTypeDescriptor.GetConverter()
{
return TypeDescriptor.GetConverter(this, true);
}
EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(this, true);
}
PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
{
return null;
}
object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(this, editorBaseType, true);
}
EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
{
return TypeDescriptor.GetEvents(this, true);
}
EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(this, attributes, true);
}
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
{
return ((ICustomTypeDescriptor)this).GetProperties(new Attribute[0]);
}
object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
{
return this;
}
#endregion
#region 主要工作在这里
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
{
ArrayList props = new ArrayList();
Type thisType = this.GetType();
PropertyInfo[] pis = thisType.GetProperties();
foreach (PropertyInfo p in pis)
{//主要是这句代码的作用
//这样,可以在编辑时调用自定义的编辑框
attributes = Attribute.GetCustomAttributes(p);
if (p.DeclaringType == thisType || p.PropertyType.ToString() == "System.Drawing.Color")
{
//判断属性是否显示
BrowsableAttribute Browsable = (BrowsableAttribute)Attribute.GetCustomAttribute(p, typeof(BrowsableAttribute));
if (Browsable != null)
{
if (Browsable.Browsable == true || p.PropertyType.ToString() == "System.Drawing.Color")
{
PropertyStub psd = new PropertyStub(p, attributes);
props.Add(psd);
}
}
else
{
PropertyStub psd = new PropertyStub(p, attributes);
props.Add(psd);
}
}
}
PropertyDescriptor[] propArray = (PropertyDescriptor[])props.ToArray(typeof(PropertyDescriptor));
return new PropertyDescriptorCollection(propArray);
}
#endregion
#endregion
}
#region PropertyStub 定义
/// <summary>
/// 继承与PropertyDescriptor
/// 主要重载DisplayName,以在PropertyGrid中显示中文
/// </summary>
public class PropertyStub : PropertyDescriptor
{
#region 没什么特别的,但必须有
PropertyInfo info;
public PropertyStub(PropertyInfo propertyInfo, Attribute[] attrs)
: base(propertyInfo.Name, attrs)
{
this.info = propertyInfo;
}
public override Type ComponentType
{
get { return this.info.ReflectedType; }
}
public override bool IsReadOnly
{
get { return this.info.CanWrite == false; }
}
public override Type PropertyType
{
get { return this.info.PropertyType; }
}
public override bool CanResetValue(object component)
{
return false;
}
public override object GetValue(object component)
{
try
{
return this.info.GetValue(component, null);
}
catch
{
return null;
}
}
public override void SetValue(object component, object value)
{
this.info.SetValue(component, value, null);
}
public override void ResetValue(object component)
{
}
public override bool ShouldSerializeValue(object component)
{
return false;
}
#endregion
#region 主要工作在这里
//通过重载下面这个属性,可以将属性在PropertyGrid中的显示设置成中文
public override string DisplayName
{
get
{
//为了简单的,实现更改名称为中文的功能
return "很好玩啊";
}
}
#endregion
}
#endregion
不能调用自定义编辑器的
#region 不能调用自定义编辑器的对比类
public class MyTestClassTwo : ICustomTypeDescriptor
{
#region 类内部变量
private string _Name = string.Empty;
[Editor(typeof(MyEditor), typeof(UITypeEditor))]
public string Name
{
get { return _Name; }
set { _Name = value; }
}
private int _Age = 0;
[Editor(typeof(MyEditor), typeof(UITypeEditor))]
public int Age
{
get { return _Age; }
set { _Age = value; }
}
#endregion
/// <summary>
/// 下面这段代码来源于:http://www.bluespace.cn/Html/Csdn/2_47/View_4702219.html
/// </summary>
/// <returns></returns>
#region ICustomTypeDescriptor 显式接口定义
#region 没什么特别改动的
AttributeCollection ICustomTypeDescriptor.GetAttributes()
{
return TypeDescriptor.GetAttributes(this, true);
}
string ICustomTypeDescriptor.GetClassName()
{
return TypeDescriptor.GetClassName(this, true);
}
string ICustomTypeDescriptor.GetComponentName()
{
return TypeDescriptor.GetComponentName(this, true);
}
TypeConverter ICustomTypeDescriptor.GetConverter()
{
return TypeDescriptor.GetConverter(this, true);
}
EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(this, true);
}
PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
{
return null;
}
object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(this, editorBaseType, true);
}
EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
{
return TypeDescriptor.GetEvents(this, true);
}
EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(this, attributes, true);
}
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
{
return ((ICustomTypeDescriptor)this).GetProperties(new Attribute[0]);
}
object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
{
return this;
}
#endregion
#region 主要工作在这里
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
{
ArrayList props = new ArrayList();
Type thisType = this.GetType();
PropertyInfo[] pis = thisType.GetProperties();
foreach (PropertyInfo p in pis)
{
//正式因为缺少下面这句,才不能够调用自定义的编辑对话框
////这样,可以在编辑时调用自定义的编辑框
//attributes = Attribute.GetCustomAttributes(p);
if (p.DeclaringType == thisType || p.PropertyType.ToString() == "System.Drawing.Color")
{
//判断属性是否显示
BrowsableAttribute Browsable = (BrowsableAttribute)Attribute.GetCustomAttribute(p, typeof(BrowsableAttribute));
if (Browsable != null)
{
if (Browsable.Browsable == true || p.PropertyType.ToString() == "System.Drawing.Color")
{
PropertyStub psd = new PropertyStub(p, attributes);
props.Add(psd);
}
}
else
{
PropertyStub psd = new PropertyStub(p, attributes);
props.Add(psd);
}
}
}
PropertyDescriptor[] propArray = (PropertyDescriptor[])props.ToArray(typeof(PropertyDescriptor));
return new PropertyDescriptorCollection(propArray);
}
#endregion
#endregion
}
#endregion
#region PropertyStub 定义 两个PropertyStub使用的是同一份
/// <summary>
/// 继承与PropertyDescriptor
/// 主要重载DisplayName,以在PropertyGrid中显示中文
/// </summary>
public class PropertyStub : PropertyDescriptor
{
#region 没什么特别的,但必须有
PropertyInfo info;
public PropertyStub(PropertyInfo propertyInfo, Attribute[] attrs)
: base(propertyInfo.Name, attrs)
{
this.info = propertyInfo;
}
public override Type ComponentType
{
get { return this.info.ReflectedType; }
}
public override bool IsReadOnly
{
get { return this.info.CanWrite == false; }
}
public override Type PropertyType
{
get { return this.info.PropertyType; }
}
public override bool CanResetValue(object component)
{
return false;
}
public override object GetValue(object component)
{
try
{
return this.info.GetValue(component, null);
}
catch
{
return null;
}
}
public override void SetValue(object component, object value)
{
this.info.SetValue(component, value, null);
}
public override void ResetValue(object component)
{
}
public override bool ShouldSerializeValue(object component)
{
return false;
}
#endregion
#region 主要工作在这里
//通过重载下面这个属性,可以将属性在PropertyGrid中的显示设置成中文
public override string DisplayName
{
get
{
//为了简单的,实现更改名称为中文的功能
return "很好玩啊";
}
}
#endregion
}
#endregion
MyEditor的定义
class MyEditor : UITypeEditor
{
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IWindowsFormsEditorService edSvc = ((IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)));
if (edSvc == null)
return null;
System.Windows.Forms.MessageBox.Show("有点莫名其妙的想知道,你要不要找男朋友啊?");
return "好啊";
return value;
}
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
}
不知道这个算不算解决这个问题的办法?你有没有其他办法?