PropertyGrid显示中文属性名网上整理的原作别介意.docx
《PropertyGrid显示中文属性名网上整理的原作别介意.docx》由会员分享,可在线阅读,更多相关《PropertyGrid显示中文属性名网上整理的原作别介意.docx(11页珍藏版)》请在冰豆网上搜索。
PropertyGrid显示中文属性名网上整理的原作别介意
C#基础系列:
开发自己的窗体设计器(PropertyGrid显示中文属性名)
既然是一个窗体设计器,那就应该能够设置控件的属性,设置属性最好的当然是PropertyGrid了,我们仅仅需要使用一个PropertyGrid.SelectedObject=Control就可以搞定,让PropertyGrid显示Control的所有属性。
可是这里显示的属性名是英文的。
对于我们开发人员来说这无可厚非,我们也乐于接受。
并且让PropertyGrid显示中文属性名,这对于我们开发人员的使用来说显得多此一举。
可是,对于我这种类型的一个应用工具,英文属性名对于很多客户来说可能就很难懂了。
所以应该让PrpertyGrid能够显示中文属性名。
如图:
另外,对于这样的一个系统。
并不是控件的所有属性都是用户希望的,可能用户希望看到的仅仅是控件高度、控件宽度、控件文本。
。
等等的属性,但是如果直接将一个控件属性全部显示给用户的话,估计对用户造成的干扰和困惑是很大的。
如何解决这个问题呢?
其实用户控件开发的时候,如果我们不希望此属性在PropertyGrid中显示,我们可以设置这个控件的Attribute,如:
[Browsable(false)]
publicintWidth
{
get{}
set{}
}
通过使用BrowsableAttribute就可以设置将此属性对PropertyGrid隐藏。
你可能要问到了,对于控件来说,其中的很多属性都是直接继承来的,我们并没有办法控制是否对PropertyGrid隐藏啊?
呵呵,对啊,这就是我下面要说的解决方法(当然此方法显得不是很灵活,但是对于这种类型的系统的确相当有用)。
在我的解决方式中,我不直接这样PropertyGrid.SelectedObject=Control,而是把这个Control替换成一个专门为此类型的Control设计的类对象上。
比如我对TextBox设计了一个TextBoxProperty,这样我们使用的是PropertyGrid.SelectedObject=TextBoxProperty的一个对象。
下面就是TextBoxProperty的代码:
publicclassTextBoxProperty:
PropertyBase
{
privateTextBox_Control;
publicTextBoxProperty()
{
}
publicTextBoxProperty(TextBoxcontrol)
{
this._Control=control;
}
[MyControlAttibute("文本","获取或者设置控件文本","")]
publicstringText
{
get{returnthis._Control.Text;}
set
{
this._Control.Text=value;
}
}
[MyControlAttibute("宽度","获取或者设置控件宽度","")]
publicintWidth
{
get{returnthis._Control.Width;}
set
{
this._Control.Width=(int)value;
}
}
[MyControlAttibute("高度","获取或者设置控件高度","")]
publicintHeight
{
get{returnthis._Control.Height;}
set
{
this._Control.Height=(int)value;
}
}
[MyControlAttibute("上边距","获取或者设置控件上边位置","")]
publicintTop
{
get{returnthis._Control.Top;}
set
{
this._Control.Top=value;
}
}
[MyControlAttibute("左边距","获取或者设置控件左边位置","")]
publicintLeft
{
get{returnthis._Control.Left;}
set
{
this._Control.Left=value;
}
}
[MyControlAttibute("背景色","获取或者设置控件背景颜色","")]
publicColorBackColor
{
get{returnthis._Control.BackColor;}
set
{
this._Control.BackColor=value;
}
}
[MyControlAttibute("前景色","获取或者设置控件的前景颜色","")]
publicColorForeColor
{
get{returnthis._Control.ForeColor;}
set
{
this._Control.ForeColor=value;
}
}
}
你从代码里面已经看出了一些端倪了,在TextBoxProperty中每个要属性都增加了MyControlAttibute,具体Attribute的概念和使用方法您可以参考我的另一篇Blog文《C#基础系列:
实现自己的ORM(反射以及Attribute在ORM中的应用)》。
这里对Attribute做了详细的介绍(对初学者有效)。
所以我就直接贴出MyControlAttibute的代码好了:
publicclassMyControlAttibute:
Attribute
{
privatestring_PropertyName;
privatestring_PropertyDescription;
privateobject_DefaultValue;
publicMyControlAttibute(stringName,stringDescription,objectDefalutValue)
{
this._PropertyName=Name;
this._PropertyDescription=Description;
this._DefaultValue=DefalutValue;
}
publicMyControlAttibute(stringName,stringDescription)
{
this._PropertyName=Name;
this._PropertyDescription=Description;
this._DefaultValue="";
}
publicMyControlAttibute(stringName)
{
this._PropertyName=Name;
this._PropertyDescription="";
this._DefaultValue="";
}
publicstringPropertyName
{
get{returnthis._PropertyName;}
}
publicstringPropertyDescription
{
get{returnthis._PropertyDescription;}
}
publicobjectDefaultValue
{
get{returnthis._DefaultValue;}
}
}
通过上面的两段代码,你已经初步看出了在PropertyGrid中显示中文属性以及仅仅显示我们需要的属性的基本思路。
下面就介绍的就是怎么让MyControlAttibute中定义了的中文属性名在PropertyGrid中显示出来。
下面这段代码,我仅仅贡献了PropertyStub中这个函数的实现。
所以不做过多解释了:
publicoverridestringDisplayName
{
get
{
if(info!
=null)
{
MyControlAttibuteuicontrolattibute=(MyControlAttibute)Attribute.GetCustomAttribute(info,typeof(MyControlAttibute));
if(uicontrolattibute!
=null)
returnuicontrolattibute.PropertyName;
else
{
returninfo.Name;
}
}
else
return"";
}
}
整个代码如下,里面包含两个类,你直接拷贝出来就可以使用了:
publicdelegatevoidPropertyChanged(objectValue);
///
///主要是实现中文化属性显示
///
publicclassPropertyBase:
ICustomTypeDescriptor
{
///
///下面这段代码来源于:
///
///
#regionICustomTypeDescriptor显式接口定义
AttributeCollectionICustomTypeDescriptor.GetAttributes()
{
returnTypeDescriptor.GetAttributes(this,true);
}
stringICustomTypeDescriptor.GetClassName()
{
returnTypeDescriptor.GetClassName(this,true);
}
stringICustomTypeDescriptor.GetComponentName()
{
returnTypeDescriptor.GetComponentName(this,true);
}
TypeConverterICustomTypeDescriptor.GetConverter()
{
returnTypeDescriptor.GetConverter(this,true);
}
EventDescriptorICustomTypeDescriptor.GetDefaultEvent()
{
returnTypeDescriptor.GetDefaultEvent(this,true);
}
PropertyDescriptorICustomTypeDescriptor.GetDefaultProperty()
{
returnnull;
}
objectICustomTypeDescriptor.GetEditor(TypeeditorBaseType)
{
returnTypeDescriptor.GetEditor(this,editorBaseType,true);
}
EventDescriptorCollectionICustomTypeDescriptor.GetEvents()
{
returnTypeDescriptor.GetEvents(this,true);
}
EventDescriptorCollectionICustomTypeDescriptor.GetEvents(Attribute[]attributes)
{
returnTypeDescriptor.GetEvents(this,attributes,true);
}
PropertyDescriptorCollectionICustomTypeDescriptor.GetProperties()
{
return((ICustomTypeDescriptor)this).GetProperties(newAttribute[0]);
}
PropertyDescriptorCollectionICustomTypeDescriptor.GetProperties(Attribute[]attributes)
{
ArrayListprops=newArrayList();
TypethisType=this.GetType();
PropertyInfo[]pis=thisType.GetProperties();
foreach(PropertyInfopinpis)
{
if(p.DeclaringType==thisType||p.PropertyType.ToString()=="System.Drawing.Color")
{
//判断属性是否显示
BrowsableAttributeBrowsable=(BrowsableAttribute)Attribute.GetCustomAttribute(p,typeof(BrowsableAttribute));
if(Browsable!
=null)
{
if(Browsable.Browsable==true||p.PropertyType.ToString()=="System.Drawing.Color")
{
PropertyStubpsd=newPropertyStub(p,attributes);
props.Add(psd);
}
}
else
{
PropertyStubpsd=newPropertyStub(p,attributes);
props.Add(psd);
}
}
}
PropertyDescriptor[]propArray=(PropertyDescriptor[])props.ToArray(typeof(PropertyDescriptor));
returnnewPropertyDescriptorCollection(propArray);
}
objectICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptorpd)
{
returnthis;
}
#endregion
}
///
///下面这段代码来源于:
///
#regionPropertyStub定义
publicclassPropertyStub:
PropertyDescriptor
{
PropertyInfoinfo;
publicPropertyStub(PropertyInfopropertyInfo,Attribute[]attrs)
:
base(propertyInfo.Name,attrs)
{
this.info=propertyInfo;
}
publicoverrideTypeComponentType
{
get{returnthis.info.ReflectedType;}
}
publicoverrideboolIsReadOnly
{
get{returnthis.info.CanWrite==false;}
}
publicoverrideTypePropertyType
{
get{returnthis.info.PropertyType;}
}
publicoverrideboolCanResetValue(objectcomponent)
{
returnfalse;
}
publicoverrideobjectGetValue(objectcomponent)
{
//Console.WriteLine("GetValue:
"+component.GetHashCode());
try
{
returnthis.info.GetValue(component,null);
}
catch
{
returnnull;
}
}
publicoverridevoidResetValue(objectcomponent)
{
}
publicoverridevoidSetValue(objectcomponent,objectvalue)
{
//Console.WriteLine("SetValue:
"+component.GetHashCode());
this.info.SetValue(component,value,null);
}
publicoverrideboolShouldSerializeValue(objectcomponent)
{
returnfalse;
}
//通过重载下面这个属性,可以将属性在PropertyGrid中的显示设置成中文
publicoverridestringDisplayName
{
get
{
if(info!
=null)
{
MyControlAttibuteuicontrolattibute=(MyControlAttibute)Attribute.GetCustomAttribute(info,typeof(MyControlAttibute));
if(uicontrolattibute!
=null)
returnuicontrolattibute.PropertyName;
else1
{
returninfo.Name;
}
}
else
return"";
}
}
}
#endregion修改后的Form界面如下:
Form中由于我仅仅是演示了TextBox所以我就是直接将创建TextBoxProperty对象的代码放在了Control_Click中:
//我这里仅仅做TextBox的属性演示,如果是其它的控件的话,那么你需要设计不同的ControlProperty(比如TextBoxProperty,ComboBoxProperty)
if(senderisTextBox)
{
this.propertyGrid1.SelectedObject=newTextBoxProperty((TextBox)sender);
}
else
{
this.propertyGrid1.SelectedObject=null;
}
对于实际的需要来说应该是根据C