TypeConverter
在本系列的上篇文章中,和大家控討了控件開發與propertyGrid的關系,不知現在大家現在對propertygrid有沒有一個較全面的了解,也不知大家有沒有做個工程,把propertyGrid拉進去鼓搗鼓搗?
“另起爐灶”
現在我們來思考一個問題:假於,propertygrid沒有把屬性和事件分成兩個分頁來顯示,會產生什麼效果?
那還用說,太亂了。
那如果你設計的控件有很多的屬性,而一些關聯性很強,或都是操作一個方面的,那麼我們可以把它們分門別類,擺到一起,怎麼做呢?
我們可以給這個控件類指定以下Attribute:
[PropertyTab(typeof(YourPropertyTab), PropertyTabScope.Component)]
public class YourControlClass
{
}
其中,前面一個參數指定處理PropertyTab的類,後一個參數說明要應用在什麼時候,Component為當前組件專用,Document當前文檔專用,Global只能由父給件顯式去除,Static不能去除。
internal class YourPropertyTab : PropertyTab
{
internal YourControlType target;
public override string TabName
{
get
{
return "選項卡的名字";
}
}
public override Bitmap Bitmap
{
get
{
return new Bitmap(base.Bitmap, new Size(16,16));//這裡是使用保存為嵌入資源的和YourPropertyTab類同名的.bmp文件
}
}
public override bool CanExtend(object o)
{
return o is YourControlType;//什麼時候用這個Tab
}
public override PropertyDescriptorCollection GetProperties(object component, Attribute[] attrs) {
return GetProperties(null, component, attrs);
}
/**//// 主要的邏輯. 在這裡定義如何實現分Tab顯示
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object component, Attribute[] attrs)
{
YourControlType uc = component as YourControlType;
if (uc == null)
{
//以下代碼實現不是YourControlType時,使用本身類型的邏輯。
TypeConverter tc = TypeDescriptor.GetConverter(component);
if (tc != null)
{
return tc.GetProperties(context, component, attrs);
}
else
{
return TypeDescriptor.GetProperties(component, attrs);
}
}
target = uc;
ArrayList propList = new ArrayList();
//..建立一個屬性List
propList.Add(new YourPropertyDescriptor(this);
PropertyDescriptor[] props = (PropertyDescriptor[])propList.ToArray(typeof(PropertyDescriptor));
return new PropertyDescriptorCollection(props);
}
//我們還要建立自定義的PropertyDescriptor供GetProperties方法使用。
private class YourPropertyDescriptor : PropertyDescriptor
{
YourPropertyTab owner;
public NumPointsPropertyDescriptor(YourPropertyTab owner) ://注意這裡的參數
base("PropertyName", new Attribute[]{CategoryAttribute.Data, RefreshPropertiesAttribute.All})//第二個參數是指定屬性改變時,與 //其它屬性的聯動,整個屬性頁是否刷新,All-刷新,Default-不,Repaint-重畫屬性窗口
{
this.owner = owner;
}
public override Type PropertyType//屬性的類型
{
get
{
return typeof(int);
}
}
屬性關聯對象是什麼類型
public override Type ComponentType
{
get
{
return typeof(YourControlType);
}
}
public override bool IsReadOnly {get{return false;}}
public override object GetValue(object o) //和關聯對象的什麼屬性相關
{
return ((YourControlType)o).Proterty_1;
}
public override void SetValue(object o, object value) //和關聯對象的什麼屬性相關
{
YourControlType uc = o as YourControlType;
uc.Property_1 = (int)value;
}
public override void ResetValue(object o){}//望文生義
public override bool CanResetValue(object o) //望文生義
{
return false;
}
/**////Does this property participate in code generation?
public override bool ShouldSerializeValue(object o)
{
return false;
}
}
}