您的位置:首页 > 其它

WinForm: Custom Control's Custom Designer and Smart Tag

2007-01-25 13:55 597 查看
要给自定义控件加上自定义的设计器, 首先得写个Designer类, 比如下面的StackPanelDesigner:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms.Design;
using System.ComponentModel.Design;

namespace Dah.Framework.Windows.Design
{
internal class StackPanelDesigner : ParentControlDesigner // 这个类在System.Design.dll里, 一般的控件Designer可以继承ControlDesigner..
{
DesignerActionListCollection _actionLists;

public override SelectionRules SelectionRules
{
get
{
if (TheStackPanel.AutoSize) // 如果AutoSize
{
return SelectionRules.Moveable; // 则只能移动, 不能手动改变大小
}
else // 否则可以改变大小
{
return SelectionRules.Moveable | SelectionRules.AllSizeable;
}
}
}

public override System.ComponentModel.Design.DesignerActionListCollection ActionLists
{
get
{
if (_actionLists == null)
{
_actionLists = new DesignerActionListCollection();
// 给 Smart Tag 添加 StackPanelActionList 里的选项
_actionLists.Add(new StackPanelActionList(this.Component));
// 给 Smart Tag 添加 LinearGradientPanelActionList 里的选项 , 因为 StackPanel 继承了 LinearGradientPanel
_actionLists.Add(new LinearGradientPanelActionList(this.Component));
}
return _actionLists;
}
}

private StackPanel TheStackPanel
{
get
{
return (StackPanel)Control; // Designer 所 Design 的 Control
}
}
}
}

如果要加上自己的SmartTag就还得写ActionList类, 如下面的StackPanelActionList:

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;

namespace Dah.Framework.Windows.Design
{
/// <summary>
/// 定义了 StackPanel 的 Smart Tag 选项
/// </summary>
internal class StackPanelActionList : DesignerActionList
{
private StackPanel _stackPanel;

public StackPanelActionList(IComponent component)
: base(component)
{
this._stackPanel = component as StackPanel;
}

private PropertyDescriptor GetPropertyByName(String propName)
{
PropertyDescriptor prop;
prop = TypeDescriptor.GetProperties(_stackPanel)[propName];
if (null == prop)
throw new ArgumentException("Matching StackPanel property not found!", propName);
else
return prop;
}

private void SetValue(string propertyName, object value)
{
GetPropertyByName(propertyName).SetValue(_panel, value);
}

//要有哪些属性的选项, 都得这样写一遍
public bool AutoSize
{
get { return _stackPanel.AutoSize; }
set { SetValue("AutoSize", value); }
}

public bool CenterAlign
{
get { return _stackPanel.CenterAlign; }
set { SetValue("CenterAlign", value); }
}

public StackPanelOrientation Orientation
{
get { return _stackPanel.Orientation; }
set { SetValue("Orientation", value); }
}

//这个方法在下面用到了, 可以用来调用控件的方法
public void RefreshChildrenPosition()
{
_stackPanel.RefreshChildrenPosition();
}

//这个方法指定了Smart Tag到底有哪些选项
public override DesignerActionItemCollection GetSortedActionItems()
{
DesignerActionItemCollection items = new DesignerActionItemCollection();

string headerName = "StackPanel Options";

//添加一个选项 Category
items.Add(new DesignerActionHeaderItem(headerName));

//下面的各种选项都属于这个Category, 用headerName来指定
items.Add(new DesignerActionPropertyItem("AutoSize", "Auto Size", headerName));
items.Add(new DesignerActionPropertyItem("CenterAlign", "Center Align", headerName));
items.Add(new DesignerActionPropertyItem("Orientation", "Orientation", headerName));

//上面三个都是控件属性的设置, 这个则可以给Smart Tag添加一个LinkButton来执行某些方法
//this, 说明了"RefreshChildrenPosition"这个方法在这个类中实现
items.Add(new DesignerActionMethodItem(this, "RefreshChildrenPosition", "Refresh children position", headerName));

return items;
}
}
}

准备工作完毕, 给自定义控件加个DesignerAttribute就O了~:

[Designer(typeof(Dah.Framework.Windows.Design.StackPanelDesigner))]
public class StackPanel : LinearGradientPanel
{
public event EventHandler ContentMarginChanged;

看看我们美丽的自定义Designer和Smart Tag吧~



久不发文... 仅此灌水一篇~
更多的有关如何扩展控件设计时行为的文章在MSDN Library:
http://msdn2.microsoft.com/en-us/library/37899azc.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐