.NET组件编程(6) Component Designer
这章主要讲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;
}
}
}
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;
}
}
}
效果如下: