智能标签,提供快捷的控件属性编辑。毋庸多说,见下图1:
如何在自定义的控件里也添加上SmartTag呢?本文作简单描述。
秘密就在自定义控件的Designer里面。
ControlDesigner. ActionLists 属性用以实现具体的SmartTag。
首先需要写一个从DesignerActionList派生的类用来实现我们的SmartTag,本文只在SmartTag上放了一个TextBox
{ … …
public override DesignerActionItemCollection GetSortedActionItems()
{
DesignerActionItemCollection item = new DesignerActionItemCollection();
item.Add(
new DesignerActionPropertyItem("Text",
"Text String", "Appearance",
"Sets the display text."));
return item;
}
… …
}
看到我们加了一个DesignerActionPropertyItem用以编辑Text,
public DesignerActionPropertyItem(
string memberName,
string displayName,
string category,
string description
)
参数memberName,变量名
参数displayName,显示的名称
参数category,类别名称
参数description,描述,在ToolTip中显示
注意到我给它的Category传的是Appearance,为了好看我想给它加个类别,怎么加呢?如下:
item.Add(new DesignerActionHeaderItem("Appearance"));
显然Text是个Property,我需要告诉SmartTag怎么得到Text的值,怎么把编辑的值送回去,在CustomControlActionList类中创建一个“Text”属性就可以了
{
get
{
return CustomControl.Text;
}
set
{
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(CustomControl)["Text"];
descriptor.SetValue(CustomControl, value);
this._service.Refresh(this.Component);
}
}
设值是通过反射去做的。
好了,接下来我们要做的事情就是把它添加到ControlDesigner中了
{
{
public override System.ComponentModel.Design.DesignerActionListCollection ActionLists
{
get
{
DesignerActionListCollection collection = new DesignerActionListCollection();
collection.Add( new CustomControlActionList(this.Component, this));
return collection;
}
}
}
很简单吧,好了看看我们的CustomControl效果:
给出所有的代码:
CustomControl1
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
[Designer( typeof( CustomControlDesigner))]
public partial class CustomControl1 : Control
{
public CustomControl1()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs pe)
{
// TODO: Add custom paint code here
pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), pe.ClipRectangle);
pe.Graphics.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), pe.ClipRectangle);
// Calling the base class OnPaint
base.OnPaint(pe);
}
public new string Text
{
get { return base.Text; }
set { base.Text = value; this.Refresh(); }
}
}
}
CustomControlDesigner及CustomControlActionList
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms.Design;
using System.Windows.Forms.Design.Behavior;
using System.ComponentModel.Design;
using System.ComponentModel;
namespace WindowsApplication1
{
public class CustomControlDesigner : ControlDesigner
{
public override System.ComponentModel.Design.DesignerActionListCollection ActionLists
{
get
{
DesignerActionListCollection collection = new DesignerActionListCollection();
collection.Add( new CustomControlActionList(this.Component, this));
return collection;
}
}
}
public class CustomControlActionList :
System.ComponentModel.Design.DesignerActionList
{
private DesignerActionUIService _service;
private CustomControlDesigner _designer;
public CustomControlActionList(IComponent c, CustomControlDesigner designer)
: base(c) {
this._designer = designer;
this._service = c.Site.GetService(typeof(DesignerActionUIService)) as DesignerActionUIService;
this.AutoShow = true;
}
public override DesignerActionItemCollection GetSortedActionItems()
{
DesignerActionItemCollection item = new DesignerActionItemCollection();
item.Add(new DesignerActionHeaderItem("Appearance"));
item.Add(
new DesignerActionPropertyItem("Text",
"Text String", "Appearance",
"Sets the display text."));
return item;
}
private CustomControl1 CustomControl
{
get
{
return this.Component as CustomControl1;
}
}
public string Text
{
get
{
return CustomControl.Text;
}
set
{
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(CustomControl)["Text"];
descriptor.SetValue(CustomControl, value);
this._service.Refresh(this.Component);
}
}
}
}