這章主要講Component的Designer,Designer顧名思義就是為Component設計時服務的,Designer可以 在設計時修改組件的行為,還可以提供它自己的服務和行為。
在.net裡要為Control或者Component定制Designer,只要從IDesigner繼承下來即可,但是在.net裡ms 已經幫我們做了兩個從IDesigner繼承下來的基類,ComponentDesigner和ControlDesigner, ComponentDesigner是為Component而設計的,ControlDesigner是為Control而設計的,所以我們可以直接 從ComponentDesigner繼承。
Designer可以提供右鍵快捷菜單上的菜單命令,我們可以通過實現ComponentDesigner 謂詞(Verbs) 屬性來定義 get 訪問器,該訪問器返回的 DesignerVerbCollection 中包含用於生成菜單命令的 DesignerVerb 對象。
同時我們對組件被雙擊時定制默認操作,在Component Designer實現 DoDefaultAction 方法即可。
示例代碼如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace ClassLibrary1
{
[DefaultEvent("CustomerLogin")]
[Designer(typeof(Class1Designer), typeof(IDesigner)), Editor(typeof(Class1Editor), typeof(ComponentEditor))]
public class Customer : Component
{
private string _parentComponentName;
private int _age;
private string _address;
public delegate void CustomerLoginEventHandler(object sender, CustomerLoginEventArgs e);
public delegate void CustomerLogoutEventHandler(object sender, CustomerLogoutEventArgs e);
public string ParentComponentName
{
get { return _parentComponentName; }
set { _parentComponentName = value; }
}
public int Age
{
get { return _age; }
set { _age = value; }
}
public string Address
{
get { return _address; }
set { _address = value; }
}
public sealed class CustomerLoginEventArgs : EventArgs { }
public sealed class CustomerLogoutEventArgs : EventArgs { }
public event CustomerLoginEventHandler CustomerLogin
{
add { }
remove { }
}
public event CustomerLogoutEventHandler CustomerLogout
{
add { }
remove { }
}
}
public class Class1Designer : ComponentDesigner
{
public Class1Designer() : base()
{
// 添加一個謂詞。
// 添加"Click Me"到右鍵菜單和智能標記中。
DesignerVerb verb = new DesignerVerb("Click Me", new EventHandler (OnChoseMe));
this.Verbs.Add(verb);
}
private void OnChoseMe(object sender, EventArgs e)
{
MessageBox.Show("You clicked.");
}
// 1、可以設計Component的默認事件創建方法簽名,並將用戶的光標定位到該位置。
// 2、也可以為Component添加雙擊時要進行的操作。
public override void DoDefaultAction()
{
MessageBox.Show(" You double clicked.");
}
// 從工具箱上拖放一個Component時,執行此方法。
public override void InitializeNewComponent(System.Collections.IDictionary defaultValues)
{
/**//*
在創建一個新的Component時,把Parent Component的名稱寫到ParentName屬 性中去。
*/
// 因為是在Design Time,所以ParentComponent的Site是存在的。
string parentName = ((Component) this.ParentComponent).Site.Name;
((Customer)(this.Component)).ParentComponentName = parentName;
/**//*
對Component設置默認屬性。
*/
((Customer)(this.Component)).Age = 18;
}
// InitializeExistingComponent、InitializeNonDefault請大家自己研究。
// 可以對Component的屬性進行操作,如移出、添加。
protected override void PostFilterProperties(System.Collections.IDictionary properties)
{
// 提供有關組件屬性 (Attribute) 的信息,如組件的屬性 (Attribute)、屬 性 (Property) 和事件。
// 刪除Address屬性。
properties.Remove("Address");
}
// PostFilterAttributes、PostFilterEvents、PreFilterAttributes、 PreFilterEvents、PreFilterProperties請大家自己研究。
/**//*
對Component設置默認屬性(過時,保持向下兼容),現在改為 InitializeNewComponent中進行初始化。
*/
public override void OnSetComponentDefaults()
{
base.OnSetComponentDefaults();
((Customer)(this.Component)).Age = 18;
}
}
public class ClassDocumentDisigner : ComponentDocumentDesigner
{
}
public class Class1Editor : ComponentEditor
{
public override bool EditComponent(ITypeDescriptorContext context, object component)
{
return true;
}
}
}
效果如下:
隨文源碼:http://www.bianceng.net/dotnet/201212/664.htm