.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
图片,左边有个按钮,能够调用我自定义的对话框。右边的则不会出现。
两份代码,一份既可以显示中文又可以调用自定义的编辑器,一份只能显示中文,不能调用自定义的编辑器。
{
#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
不能调用自定义编辑器的
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的定义
{
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;
}
}
不知道这个算不算解决这个问题的办法?你有没有其他办法?