要给自定义控件加上自定义的设计器, 首先得写个Designer类, 比如下面的StackPanelDesigner:
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Windows.Forms.Design;
5
using System.ComponentModel.Design;
6
7
namespace Dah.Framework.Windows.Design
8

{
9
internal class StackPanelDesigner : ParentControlDesigner // 这个类在System.Design.dll里, 一般的控件Designer可以继承ControlDesigner..
10
{
11
DesignerActionListCollection _actionLists;
12
13
public override SelectionRules SelectionRules
14
{
15
get
16
{
17
if (TheStackPanel.AutoSize) // 如果AutoSize
18
{
19
return SelectionRules.Moveable; // 则只能移动, 不能手动改变大小
20
}
21
else // 否则可以改变大小
22
{
23
return SelectionRules.Moveable | SelectionRules.AllSizeable;
24
}
25
}
26
}
27
28
public override System.ComponentModel.Design.DesignerActionListCollection ActionLists
29
{
30
get
31
{
32
if (_actionLists == null)
33
{
34
_actionLists = new DesignerActionListCollection();
35
// 给 Smart Tag 添加 StackPanelActionList 里的选项
36
_actionLists.Add(new StackPanelActionList(this.Component));
37
// 给 Smart Tag 添加 LinearGradientPanelActionList 里的选项 , 因为 StackPanel 继承了 LinearGradientPanel
38
_actionLists.Add(new LinearGradientPanelActionList(this.Component));
39
}
40
return _actionLists;
41
}
42
}
43
44
private StackPanel TheStackPanel
45
{
46
get
47
{
48
return (StackPanel)Control; // Designer 所 Design 的 Control
49
}
50
}
51
}
52
}
53
如果要加上自己的SmartTag就还得写ActionList类, 如下面的StackPanelActionList:
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.ComponentModel;
5
using System.ComponentModel.Design;
6
using System.Drawing;
7
8
namespace Dah.Framework.Windows.Design
9

{
10
/**//// <summary>
11
/// 定义了 StackPanel 的 Smart Tag 选项
12
/// </summary>
13
internal class StackPanelActionList : DesignerActionList
14
{
15
private StackPanel _stackPanel;
16
17
public StackPanelActionList(IComponent component)
18
: base(component)
19
{
20
this._stackPanel = component as StackPanel;
21
}
22
23
private PropertyDescriptor GetPropertyByName(String propName)
24
{
25
PropertyDescriptor prop;
26
prop = TypeDescriptor.GetProperties(_stackPanel)[propName];
27
if (null == prop)
28
throw new ArgumentException("Matching StackPanel property not found!", propName);
29
else
30
return prop;
31
}
32
33
private void SetValue(string propertyName, object value)
34
{
35
GetPropertyByName(propertyName).SetValue(_panel, value);
36
}
37
38
//要有哪些属性的选项, 都得这样写一遍
39
public bool AutoSize
40
{
41
get
{ return _stackPanel.AutoSize; }
42
set
{ SetValue("AutoSize", value); }
43
}
44
45
public bool CenterAlign
46
{
47
get
{ return _stackPanel.CenterAlign; }
48
set
{ SetValue("CenterAlign", value); }
49
}
50
51
public StackPanelOrientation Orientation
52
{
53
get
{ return _stackPanel.Orientation; }
54
set
{ SetValue("Orientation", value); }
55
}
56
57
//这个方法在下面用到了, 可以用来调用控件的方法
58
public void RefreshChildrenPosition()
59
{
60
_stackPanel.RefreshChildrenPosition();
61
}
62
63
//这个方法指定了Smart Tag到底有哪些选项
64
public override DesignerActionItemCollection GetSortedActionItems()
65
{
66
DesignerActionItemCollection items = new DesignerActionItemCollection();
67
68
string headerName = "StackPanel Options";
69
70
//添加一个选项 Category
71
items.Add(new DesignerActionHeaderItem(headerName));
72
73
//下面的各种选项都属于这个Category, 用headerName来指定
74
items.Add(new DesignerActionPropertyItem("AutoSize", "Auto Size", headerName));
75
items.Add(new DesignerActionPropertyItem("CenterAlign", "Center Align", headerName));
76
items.Add(new DesignerActionPropertyItem("Orientation", "Orientation", headerName));
77
78
//上面三个都是控件属性的设置, 这个则可以给Smart Tag添加一个LinkButton来执行某些方法
79
//this, 说明了"RefreshChildrenPosition"这个方法在这个类中实现
80
items.Add(new DesignerActionMethodItem(this, "RefreshChildrenPosition", "Refresh children position", headerName));
81
82
return items;
83
}
84
}
85
}
看看我们美丽的自定义Designer和Smart Tag吧~
