经过上一篇定义的两个接口,菜单与工具栏基本上符合了Command模式的样子,接下来应该可以在系统中加载了。但理论上照着模式是一回事,实实在在的写代码又是另一回事。
我们很遗憾地发现ToolBarButton这个类根本没有单击事件,甚至跟UI有关的事件都没有一个,因为它根本就不是从Control继承的,而是从Component继承的。工具栏按钮单击是从工具栏ToolBar的ButtonClick事件来的,就是说如果你要挂一段单击工具栏上单个按钮时发生动作的代码得挂在ToolBar的事件上,除些之外别无它法,很奇怪的设计。这种ToolBar只能用在静态的地方(其实即使是静态的地方,这个ButtonClick事件也是很糟糕的,以后会看到静态工具栏的这个变态事件),对于动态工具栏.Net Framework自带的这个ToolBar实在是无能为力。
没辙了,改吧。我们自己放个单击事件出来。下面是ToolBarButton的完整代码:
为了让ToolBar能认识这个Button,我们还得对ToolBar作点小小的改造,要让它可以触发ToolBarButton的单击事件。
protected override void WndProc(ref Message m) {
if (m.Msg == 0x2111){
int index = ((int) m.WParam) & 0xffff;
ToolBarButton button = this.Buttons[index];
if (button != null) {
CommandToolBarButton commandBtn = button as CommandToolBarButton;
if (commandBtn != null){
commandBtn.DoOnClick();
}else{
ToolBarButtonClickEventArgs args1 = new ToolBarButtonClickEventArgs(button);
this.OnButtonClick(args1);
}
}
}else
base.WndProc (ref m);
base.ResetMouseEventArgs();
}
上面代码里有个Magic Number,它在Win32 API里表示进入菜单循环消息(WM_ENTERMENULOOP,注意不是写在单击消息里的),因为项目里这种Message常量用得不多,就偷懒一下直接写了。