代码改变世界

.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;
}

}

示例程序下载

不知道这个算不算解决这个问题的办法?你有没有其他办法?