为控件添加智能标记

在使用系统控件的时候我们经常看见和使用控件的右上角的一个三角型的图标([img]http://i.msdn.microsoft.com/9ew6tzdt.Local_1283043494_vs_winformsmttagglyph(zh-cn,VS.80).gif[/img]),点击之后弹出一个菜单,标题是“XXXX 任务”,里面提供了好多方便有用的设置。但是我们自己写的自定义控件中却没有,那如何让自己的UserControl中也有这个功能呢?
[img]http://dl.iteye.com/upload/attachment/198681/4f13cd43-a62b-317e-9707-c26148589af8.bmp[/img]

想实现功能首先要知道功能的名称吧,不然想去Google一下都不知道要用什么关键字 :D
这个功能叫做“智能标记 smart tag panel“。

今天以最常见的”在父容器中停靠“功能来演示一下如何让自定义控件实现智能标记功能。

一、正所谓”工欲善其事,必先利其器“,首先要引入一个库文件”System.Design“。

二、在自定义控件的命名空间下定义一个类,集成ControlDesigner类。(我自定义的控件叫做AdSchedule,所以给类起名AdScheduleDesigner)

public class AdScheduleDesigner : System.Windows.Forms.Design.ControlDesigner

这个类的作用是”扩展 Control 的设计模式行为“,类中需要定义一个DesignerActionListCollection类型的属性。

private DesignerActionListCollection actionLists;
public override DesignerActionListCollection ActionLists
{
get
{
if (null == actionLists)
{
actionLists = new DesignerActionListCollection();
actionLists.Add(new AdScheduleActionList(this.Component));
}
return actionLists;
}
}


三、在创建一个编写逻辑程序的类

public class AdScheduleActionList :
System.ComponentModel.Design.DesignerActionList
{
private AdSchedule adSchedule;
private DesignerActionUIService designerActionUISvc = null;

public AdScheduleActionList(IComponent component)
: base(component)
{
this.adSchedule = component as AdSchedule;

this.designerActionUISvc =
GetService(typeof(DesignerActionUIService))
as DesignerActionUIService;
}
}


四、在AdScheduleActionList类中重写GetSortedActionItems方法。

public override DesignerActionItemCollection GetSortedActionItems()
{
DesignerActionItemCollection items = new DesignerActionItemCollection();
items.Add(new DesignerActionMethodItem(this, "ParentComponentStop", "在父容器中停靠"));
return items;
}


其中DesignerActionMethodItem的构造方法有三个参数:
1、ActionList
2、要通过面板项调用的方法的名称,此方法是从 DesignerActionList 派生的类中的一个方法,其方法名区分大小写。
3、此项的面板文本。

这个函数写好之后就在AdScheduleActionList类中添加需要调用的方法。

public void ParentComponentStop()
{
componentLocation = adSchedule.Location;
componentSize = adSchedule.Size;

adSchedule.Dock = System.Windows.Forms.DockStyle.Fill;
adSchedule.Location = new System.Drawing.Point(0, 0);
}


五、就这么简单,智能标记已经可以用了
[img]http://dl.iteye.com/upload/attachment/198744/b0964a4e-3edc-32ca-bf0e-bbb91757a5d1.bmp[/img]

点击以后窗口就可以在父容器中停靠,但是问题来了,如何取消停靠呢?
很简单就是修改GetSortedActionItems方法中的DesignerActionItemCollection。
这里我们还需要创建两个变量,在ParentComponentStop函数中赋值用来保存控件停靠前的位置和大小,以便取消的时候返回原来的样子。

public override DesignerActionItemCollection GetSortedActionItems()
{
DesignerActionItemCollection items = new DesignerActionItemCollection();
if (DockStyle.None == adSchedule.Dock)
items.Add(new DesignerActionMethodItem(this, "ParentComponentStop", "在父容器中停靠"));
else
items.Add(new DesignerActionMethodItem(this, "CancelParentComponentStop", "取消在父容器中停靠"));
return items;
}


public void CancelParentComponentStop()
{
if (null == componentLocation)
componentLocation = adSchedule.Location;
if (null == componentSize)
componentSize = adSchedule.Size;

adSchedule.Dock = DockStyle.None;
adSchedule.Location = componentLocation;
adSchedule.Size = componentSize;

designerActionUISvc.Refresh(this.Component);
}


还没有完,点击之后为什么还是“在父容器中停靠”?文字没有变化呢?
还记得designerActionUISvc这个变量吗?他用来缓存DesignerActionUIService,以实现DesigneractionList刷新功能。
在ParentComponentStop函数最后加上这句话

designerActionUISvc.Refresh(this.Component);

现在就大功告成了 :idea: ,喝杯咖啡自己欣赏一下 :arrow:


这只是个简单的应用,简单的文字链接形式实现调用函数,其实在智能标记中可以实现很多功能,大家可以参考一下MSDN,给DesignerActionItemCollection传入不同类型的值就会实现更多的操作。
[img]http://dl.iteye.com/upload/attachment/198753/c65fda35-28c6-3681-a2c2-347c05cd24ac.bmp[/img]

完整的代码可以从附件中下载。

参考MSDN文献:
[url=http://msdn.microsoft.com/zh-cn/library/ms171829(VS.80).aspx]演练:向 Windows 窗体组件添加智能标记[/url]
[url=http://msdn.microsoft.com/zh-cn/library/ms171830(VS.80).aspx]如何:向 Windows 窗体组件附加智能标记[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值