|
日历
| | 日 | 一 | 二 | 三 | 四 | 五 | 六 |
|---|
| 26 | 27 | 28 | 29 | 30 | 1 | 2 | | 3 | 4 | 5 | 6 | 7 | 8 | 9 | | 10 | 11 | 12 | 13 | 14 | 15 | 16 | | 17 | 18 | 19 | 20 | 21 | 22 | 23 | | 24 | 25 | 26 | 27 | 28 | 29 | 30 | | 31 | 1 | 2 | 3 | 4 | 5 | 6 |
|
统计
- 随笔 - 15
- 文章 - 0
- 评论 - 110
- 引用 - 4
导航
常用链接
留言簿(7)
我参与的团队
随笔分类(16)
随笔档案(13)
相册
友情链接
最新随笔
积分与排名
最新评论

阅读排行榜
评论排行榜
|
首先从一个场景说起:
我们常常有这样一个需求,比如说在列表窗体(Master)有很多按钮,如增加,修改,删除,保存,取消等,不同的情况下,按钮的状态可能会不一样,比如说,只有在编辑状态时,保存,取消按钮才可用等等.
然后双击列表,会弹出一个明细窗体(Detail),这个窗体也有如增加,修改,删除,保存,取消等按钮,且功能和刷新条件也与Master窗体的功能差不多,我们常把各自的业务逻辑写在各自的窗体,但这样不是显得太冗余了吗,其实,我们有一种比较好的方法来解决这个问题.
用过DELPHI的人应该都知道,有个TACTION类解决的就是这个问题,下面我用.NET代码来模拟TACTION的实现:
1. 先设计一个命令Cmd类,主要定义操作的行为(如执行,刷新)及界面的绑定(此处假定绑定类为ToolStripMenuItem,如需绑定其它类,请自己扩展).其实现代码如下:
 
1 internal class Cmd
2 {
3 private List<ToolStripMenuItem> cmds = new List<ToolStripMenuItem>();
4
5 private string Text = null;
6 private Image Image = null;
7 private Keys ShortKey = 0;
8 private EventHandler CallMethod = null;
9
10 internal Cmd(string Text, Keys ShortKey, Image Image, EventHandler CallMethod)
11 {
12 this.Text = Text;
13 this.ShortKey = System.Windows.Forms.Keys.Control | ShortKey;
14 this.Image = Image;
15 this.CallMethod = CallMethod;
16 }
17
18 internal void Refresh(bool IsEnabled)
19 {
20 foreach (ToolStripMenuItem cmd in cmds)
21 {
22 cmd.Enabled = IsEnabled;
23 }
24 }
25
26 internal void AddBind(ToolStripMenuItem mnu)
27 {
28 if (this.cmds.Contains(mnu)) return;
29
30 mnu.Text = this.Text;
31 mnu.Image = this.Image;
32 if (this.ShortKey != 0) mnu.ShortcutKeys = this.ShortKey;
33 mnu.Click += CallMethod;
34 this.cmds.Add(mnu);
35 }
36 }
2. 设计一个Act类,对Cmd进行封装
 
1 public class Act
2 {
3 private Dictionary<string, Cmd> cmds = new Dictionary<string, Cmd>();
4
5 public void AddAction(string Name, string Text, Keys ShortKey, Image Image, EventHandler CallMethod)
6 {
7 if (cmds.ContainsKey(Name)) cmds.Remove(Name);
8
9 Cmd cmd = new Cmd(Text, ShortKey, Image, CallMethod);
10 cmds.Add(Name, cmd);
11 }
12
13 public void AddBind(string Name, ToolStripMenuItem mnu)
14 {
15 if (mnu == null) return;
16
17 if (!cmds.ContainsKey(Name)) throw new Exception("未设置名称为[" + Name + "]的动作,不能绑定!");
18 cmds[Name].AddBind(mnu);
19 }
20
21 public void Refresh(string Name, bool IsEnabled)
22 {
23 if (!cmds.ContainsKey(Name)) throw new Exception("未设置名称为[" + Name + "]的动作,不能刷新!");
24
25 cmds[Name].Refresh(IsEnabled);
26 }
27
28 }
3. 效果演示
增加master,entry窗体,随便增加一些按钮,命好名就行了


增加master的Action动作及绑定代码
 
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Text;
7 using System.Windows.Forms;
8
9 namespace Test
10  {
11 public partial class Form1 : Form
12 {
13 MZ.CT.Act act = new MZ.CT.Act();
14
15 public Form1()
16 {
17 InitializeComponent();
18
19 //定义动作行为
20 act.AddAction("Add", "增加", Keys.A, null, delegate { this.Refresh(true); });
21 act.AddAction("Edit", "修改", Keys.E, null, delegate { this.Refresh(true); });
22 act.AddAction("Delete", "删除", Keys.D, null, delegate { this.Refresh(true); });
23 act.AddAction("Save", "保存", Keys.S, null, delegate { this.Refresh(false); });
24 act.AddAction("Cancel", "取消", Keys.C, null, delegate { this.Refresh(false); });
25
26 act.AddAction("Show", "打开子窗体", Keys.S, null,
27 delegate
28 {
29 using (Form2 frm = new Form2(act))
30 {
31 frm.ShowDialog();
32 }
33 }
34 );
35
36 //绑定动作
37 act.AddBind("Add", this.btnAdd);
38 act.AddBind("Edit", this.btnEdit);
39 act.AddBind("Delete", this.btnDelete);
40 act.AddBind("Save", this.btnSave);
41 act.AddBind("Cancel", this.btnCancel);
42
43 act.AddBind("Show", this.btnShow);
44 }
45
46 private void Refresh(bool IsEnabled)
47 {
48 this.act.Refresh("Add", !IsEnabled);
49 this.act.Refresh("Edit", !IsEnabled);
50 this.act.Refresh("Delete", !IsEnabled);
51 this.act.Refresh("Save", IsEnabled);
52 this.act.Refresh("Cancel", IsEnabled);
53 }
54 }
55 }
增加entry绑定代码
 
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Text;
7 using System.Windows.Forms;
8
9 namespace Test
10  {
11 public partial class Form2 : Form
12 {
13 public Form2(MZ.CT.Act act)
14 {
15 InitializeComponent();
16
17 //重复绑定
18 act.AddBind("Add", this.btnAdd);
19 act.AddBind("Edit", this.btnEdit);
20 act.AddBind("Delete", this.btnDelete);
21 act.AddBind("Save", this.btnSave);
22 act.AddBind("Cancel", this.btnCancel);
23 }
24 }
25 }
最终效果演示:
master中点击增加后的刷新效果:

打开entry后,联动的刷新效果:

由于本人比较忙且太过懒散,很久没有更新BLOG了,过年时如果有时间的话,我准备写一系列分布式框架设计的文章,望广大园友支持及指正!
评论:
-
#1楼
Posted @ 2006-12-22 13:36
不错,DELPHI里面的ActionList很好用
回复 引用
-
#2楼
Posted @ 2006-12-22 18:56
怀念delphi 的actionlist, codeproject 也有篇关于actionList的实现;不过你的这个简单实用,不错
回复 引用 查看
|