今天在写程序时发现要实现一个功能,就是需要一个树,然后当双击树的节点时弹出一个窗口。
这个看起来很简单,但是每个节点对应的窗口都不一样,如果窗口很多的话,需要写的代码就比较多。
后来想了一下,觉得可以把窗口相关的参数放到节点的tag属性中。最先想到的是放窗体类的名称,不过还要使用反射什么的,我不太喜欢,而且一不小心就写错类名了;类似的还有使用switch开关语句,在双击的时候根据类名或者其他枚举的方法判断打开的窗口,不过也比较麻烦;再然后就想能不能用委托实现,但是想了一下如果用委托的话还是需要把每个打开窗口的方法都写出来,也需要写很多代码。因为我比较胖,人也比较懒,对这些方法都不满意,最后就想能不能在tag里直接存在窗体类型呢?然后直接实例化该类型,得到窗口对象,直接打开就完了,经过一试果然可以:
1 /// <summary>
2 /// 主窗体加载事件,把需要打开的报表窗体都加进来
3 /// </summary>
4 /// <param name="sender"></param>
5 /// <param name="e"></param>
6 private void FrmMainLoad(object sender, EventArgs e)
7 {
8 TreeNode root = new TreeNode("报表演示");
9 tvMain.Nodes.Add(root);
10
11 TreeNode newNode = new TreeNode("表格报表");
12 newNode.Tag = typeof(FrmTableReport);
13 root.Nodes.Add(newNode);
14
15 newNode = new TreeNode("分组报表");
16 newNode.Tag = typeof(FrmGroupReport);
17 root.Nodes.Add(newNode);
18
19 }
20
21 /// <summary>
22 /// 双击树节点事件
23 /// </summary>
24 /// <param name="sender"></param>
25 /// <param name="e"></param>
26 private void TvMainNodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
27 {
28 if (e.Node != null && e.Node.Tag != null)
29 {
30 ShowTaleReport(e.Node.Tag as Type);
31 }
32 }
33
34 /// <summary>
35 /// 打开类型指定的窗体
36 /// </summary>
37 /// <param name="type"></param>
38 private void ShowTaleReport(Type type)
39 {
40 Form report = type.GetConstructor(System.Type.EmptyTypes).Invoke(new object[0]) as Form;
41 if (report == null) return;
42 report.MdiParent = this;
43 report.WindowState = FormWindowState.Maximized;
44 report.Show();
45 }
2 /// 主窗体加载事件,把需要打开的报表窗体都加进来
3 /// </summary>
4 /// <param name="sender"></param>
5 /// <param name="e"></param>
6 private void FrmMainLoad(object sender, EventArgs e)
7 {
8 TreeNode root = new TreeNode("报表演示");
9 tvMain.Nodes.Add(root);
10
11 TreeNode newNode = new TreeNode("表格报表");
12 newNode.Tag = typeof(FrmTableReport);
13 root.Nodes.Add(newNode);
14
15 newNode = new TreeNode("分组报表");
16 newNode.Tag = typeof(FrmGroupReport);
17 root.Nodes.Add(newNode);
18
19 }
20
21 /// <summary>
22 /// 双击树节点事件
23 /// </summary>
24 /// <param name="sender"></param>
25 /// <param name="e"></param>
26 private void TvMainNodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
27 {
28 if (e.Node != null && e.Node.Tag != null)
29 {
30 ShowTaleReport(e.Node.Tag as Type);
31 }
32 }
33
34 /// <summary>
35 /// 打开类型指定的窗体
36 /// </summary>
37 /// <param name="type"></param>
38 private void ShowTaleReport(Type type)
39 {
40 Form report = type.GetConstructor(System.Type.EmptyTypes).Invoke(new object[0]) as Form;
41 if (report == null) return;
42 report.MdiParent = this;
43 report.WindowState = FormWindowState.Maximized;
44 report.Show();
45 }
通过这种方式,我每增加一个需要管理的报表窗体,只需要在formlaod事件里加上三行代码就完了。
呵呵,够简单了。