我们常常有这样一个需求,比如说在列表窗体(Master)有很多按钮,如增加,修改,删除,保存,取消等,不同的情况下,按钮的状态可能会不一样,比如说,只有在编辑状态时,保存,取消按钮才可用等等.
然后双击列表,会弹出一个明细窗体(Detail),这个窗体也有如增加,修改,删除,保存,取消等按钮,且功能和刷新条件也与Master窗体的功能差不多,我们常把各自的业务逻辑写在各自的窗体,但这样不是显得太冗余了吗,其实,我们有一种比较好的方法来解决这个问题.
用过DELPHI的人应该都知道,有个TACTION类解决的就是这个问题,下面我用.NET代码来模拟TACTION的实现:
1. 先设计一个命令Cmd类,主要定义操作的行为(如执行,刷新)及界面的绑定(此处假定绑定类为ToolStripMenuItem,如需绑定其它类,请自己扩展).其实现代码如下:
Code
internal class Cmd
{
private List<ToolStripMenuItem> cmds = new List<ToolStripMenuItem>();
private string Text = null;
private Image Image = null;
private Keys ShortKey = 0;
private EventHandler CallMethod = null;
internal Cmd(string Text, Keys ShortKey, Image Image, EventHandler CallMethod)
{
this.Text = Text;
this.ShortKey = System.Windows.Forms.Keys.Control | ShortKey;
this.Image = Image;
this.CallMethod = CallMethod;
}
internal void Refresh(bool IsEnabled)
{
foreach (ToolStripMenuItem cmd in cmds)
{
cmd.Enabled = IsEnabled;
}
}
internal void AddBind(ToolStripMenuItem mnu)
{
if (this.cmds.Contains(mnu)) return;
mnu.Text = this.Text;
mnu.Image = this.Image;
if (this.ShortKey != 0) mnu.ShortcutKeys = this.ShortKey;
mnu.Click += CallMethod;
this.cmds.Add(mnu);
}
}
internal class Cmd
{
private List<ToolStripMenuItem> cmds = new List<ToolStripMenuItem>();
private string Text = null;
private Image Image = null;
private Keys ShortKey = 0;
private EventHandler CallMethod = null;
internal Cmd(string Text, Keys ShortKey, Image Image, EventHandler CallMethod)
{
this.Text = Text;
this.ShortKey = System.Windows.Forms.Keys.Control | ShortKey;
this.Image = Image;
this.CallMethod = CallMethod;
}
internal void Refresh(bool IsEnabled)
{
foreach (ToolStripMenuItem cmd in cmds)
{
cmd.Enabled = IsEnabled;
}
}
internal void AddBind(ToolStripMenuItem mnu)
{
if (this.cmds.Contains(mnu)) return;
mnu.Text = this.Text;
mnu.Image = this.Image;
if (this.ShortKey != 0) mnu.ShortcutKeys = this.ShortKey;
mnu.Click += CallMethod;
this.cmds.Add(mnu);
}
}
2. 设计一个Act类,对Cmd进行封装
Code
public class Act
{
private Dictionary<string, Cmd> cmds = new Dictionary<string, Cmd>();
public void AddAction(string Name, string Text, Keys ShortKey, Image Image, EventHandler CallMethod)
{
if (cmds.ContainsKey(Name)) cmds.Remove(Name);
Cmd cmd = new Cmd(Text, ShortKey, Image, CallMethod);
cmds.Add(Name, cmd);
}
public void AddBind(string Name, ToolStripMenuItem mnu)
{
if (mnu == null) return;
if (!cmds.ContainsKey(Name)) throw new Exception("未设置名称为[" + Name + "]的动作,不能绑定!");
cmds[Name].AddBind(mnu);
}
public void Refresh(string Name, bool IsEnabled)
{
if (!cmds.ContainsKey(Name)) throw new Exception("未设置名称为[" + Name + "]的动作,不能刷新!");
cmds[Name].Refresh(IsEnabled);
}
}
public class Act
{
private Dictionary<string, Cmd> cmds = new Dictionary<string, Cmd>();
public void AddAction(string Name, string Text, Keys ShortKey, Image Image, EventHandler CallMethod)
{
if (cmds.ContainsKey(Name)) cmds.Remove(Name);
Cmd cmd = new Cmd(Text, ShortKey, Image, CallMethod);
cmds.Add(Name, cmd);
}
public void AddBind(string Name, ToolStripMenuItem mnu)
{
if (mnu == null) return;
if (!cmds.ContainsKey(Name)) throw new Exception("未设置名称为[" + Name + "]的动作,不能绑定!");
cmds[Name].AddBind(mnu);
}
public void Refresh(string Name, bool IsEnabled)
{
if (!cmds.ContainsKey(Name)) throw new Exception("未设置名称为[" + Name + "]的动作,不能刷新!");
cmds[Name].Refresh(IsEnabled);
}
}
1public 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动作及绑定代码
Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
MZ.CT.Act act = new MZ.CT.Act();
public Form1()
{
InitializeComponent();
//定义动作行为
act.AddAction("Add", "增加", Keys.A, null, delegate { this.Refresh(true); });
act.AddAction("Edit", "修改", Keys.E, null, delegate { this.Refresh(true); });
act.AddAction("Delete", "删除", Keys.D, null, delegate { this.Refresh(true); });
act.AddAction("Save", "保存", Keys.S, null, delegate { this.Refresh(false); });
act.AddAction("Cancel", "取消", Keys.C, null, delegate { this.Refresh(false); });
act.AddAction("Show", "打开子窗体", Keys.S, null,
delegate
{
using (Form2 frm = new Form2(act))
{
frm.ShowDialog();
}
}
);
//绑定动作
act.AddBind("Add", this.btnAdd);
act.AddBind("Edit", this.btnEdit);
act.AddBind("Delete", this.btnDelete);
act.AddBind("Save", this.btnSave);
act.AddBind("Cancel", this.btnCancel);
act.AddBind("Show", this.btnShow);
}
private void Refresh(bool IsEnabled)
{
this.act.Refresh("Add", !IsEnabled);
this.act.Refresh("Edit", !IsEnabled);
this.act.Refresh("Delete", !IsEnabled);
this.act.Refresh("Save", IsEnabled);
this.act.Refresh("Cancel", IsEnabled);
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
MZ.CT.Act act = new MZ.CT.Act();
public Form1()
{
InitializeComponent();
//定义动作行为
act.AddAction("Add", "增加", Keys.A, null, delegate { this.Refresh(true); });
act.AddAction("Edit", "修改", Keys.E, null, delegate { this.Refresh(true); });
act.AddAction("Delete", "删除", Keys.D, null, delegate { this.Refresh(true); });
act.AddAction("Save", "保存", Keys.S, null, delegate { this.Refresh(false); });
act.AddAction("Cancel", "取消", Keys.C, null, delegate { this.Refresh(false); });
act.AddAction("Show", "打开子窗体", Keys.S, null,
delegate
{
using (Form2 frm = new Form2(act))
{
frm.ShowDialog();
}
}
);
//绑定动作
act.AddBind("Add", this.btnAdd);
act.AddBind("Edit", this.btnEdit);
act.AddBind("Delete", this.btnDelete);
act.AddBind("Save", this.btnSave);
act.AddBind("Cancel", this.btnCancel);
act.AddBind("Show", this.btnShow);
}
private void Refresh(bool IsEnabled)
{
this.act.Refresh("Add", !IsEnabled);
this.act.Refresh("Edit", !IsEnabled);
this.act.Refresh("Delete", !IsEnabled);
this.act.Refresh("Save", IsEnabled);
this.act.Refresh("Cancel", IsEnabled);
}
}
}
增加entry绑定代码
Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Test
{
public partial class Form2 : Form
{
public Form2(MZ.CT.Act act)
{
InitializeComponent();
//重复绑定
act.AddBind("Add", this.btnAdd);
act.AddBind("Edit", this.btnEdit);
act.AddBind("Delete", this.btnDelete);
act.AddBind("Save", this.btnSave);
act.AddBind("Cancel", this.btnCancel);
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Test
{
public partial class Form2 : Form
{
public Form2(MZ.CT.Act act)
{
InitializeComponent();
//重复绑定
act.AddBind("Add", this.btnAdd);
act.AddBind("Edit", this.btnEdit);
act.AddBind("Delete", this.btnDelete);
act.AddBind("Save", this.btnSave);
act.AddBind("Cancel", this.btnCancel);
}
}
}
最终效果演示:
master中点击增加后的刷新效果:
打开entry后,联动的刷新效果:
由于本人比较忙且太过懒散,很久没有更新BLOG了,过年时如果有时间的话,我准备写一系列分布式框架设计的文章,望广大园友支持及指正!