实现目标:
1、在主窗体上有菜单栏和状态栏,菜单栏的按钮可以随意打开子窗体,如果子窗体已经打开就激活,
2、子窗体打开后在主窗体的状态栏动态生成按钮,该按钮可激活相应的子窗体,子窗体关闭后,该按钮消失,状态栏功能类似windows的任务栏;
3、主窗体启动时自动打开一个子窗体,并同样在状态栏生成一个按钮,这个子窗体有按钮若干,这些按钮实现与主窗体的菜单栏的按钮一样的功能;
项目文件说明
父窗体容器 :Form1
子窗体: console.cs + form_m1.cs + form_m2.cs
基类窗体:menu.cs
关系:form_m1.cs + form_m2.cs继承自menu.cs
menu代码
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Threading.Tasks;
9 using System.Windows.Forms;
10
11 namespace 子窗口打开其他子窗口并在父窗口新建按钮
12 {
13 public partial class menu : Form
14 {
15 public menu()
16 {
17 InitializeComponent();
18 }
19 public delegate void FormMain_button(string name);
20 public event FormMain_button Button_event;
21 public event FormMain_button Button_event_Dispose;
22
23 public void load_display()
24 {
25 Button_event(Name);
26 // MessageBox.Show(Name);
27 }
28 public void close_dispose()
29 {
30 Button_event_Dispose(Name);
31 }
32
33
34
35 }
36 }
form_m1.cs代码
其中Form1.text = this.Text;是在子窗体启动时给父窗体的方法传参,让父窗体的状态栏生成的按钮的名字和这个子窗体显示的名字相同。
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Threading.Tasks;
9 using System.Windows.Forms;
10
11 namespace 子窗口打开其他子窗口并在父窗口新建按钮
12 {
13 public partial class form_m1 : menu
14 {
15 public form_m1()
16 {
17 InitializeComponent();
18 }
19 protected override void OnShown(EventArgs e)
20 {
21 Form1.text = this.Text;
22 base.load_display();
23 }
24 protected override void OnClosed(EventArgs e)
25 {
26 //base.OnClosed(e);
27
28 base.close_dispose();
29 }
30 }
31 }
form_m2.cs代码与form_m1.cs代码类似,不赘
1、在主窗体上有菜单栏和状态栏,菜单栏的按钮可以随意打开子窗体,如果子窗体已经打开就激活,
2、子窗体打开后在主窗体的状态栏动态生成按钮,该按钮可激活相应的子窗体,子窗体关闭后,该按钮消失,状态栏功能类似windows的任务栏;
先实现功能1和功能2
Form1.cs代码
解释:
15 行的 static public string text;给按钮命名用,在子窗口赋值;
16-27 产生按钮的方法 ①
用label做了一个按钮,这个按钮的名字是子窗口传递的和子窗体相同,后面需要使用按钮的名字来定位子窗口,显示的文字是子窗口给的,文字可以在子窗口任意指定;
生成的这个按钮有四条边,如24行。带了一个一个事件,如第25行
32-39 生成的按钮的事件 ,首先找一下是哪个按钮触发了这个事件,并获得这个按钮的名字,按钮的名字就是子窗体的名字,
所以可以在Application.OpenForms里面寻找这个名字的子窗体,找到后激活,并让这个窗体显示默认大小;这个窗体一定能找到吗?需不需要做异常检测呢?
这个按钮是伴随子窗体OnShow事件创建的,子窗体消失OnClose,则按钮消失,所以理论上不需要做异常检测。这个问题留着以后考虑吧,现在是2019-03-11 23:14:33
28-31 让按钮消失的方法②
给一个名字,让这个名字的按钮从状态栏消失
42-46 加载Form1的窗体,并让这个窗体成为MDI
48-66 传入继承自menu的窗体的实例并传入一个名字,传入名字是为了检查这个窗体有没有被打开,如果打开了就激活,我很多地方都用名字来定位窗体,好用!
Form test = Application.OpenForms[name];找找看有没有这个名字的窗体
f.Button_event += new menu.FormMain_button(button_form1);
f.Button_event_Dispose += new menu.FormMain_button(mess);监控一下有没有发生这两个事件,并分别调用产生按钮和释放按钮的方法
68-79 这几行,应该不会在某天不知道是啥意思吧,如果这都能忘了,那我应该老早没干这行了,实在不行了,只要还记得复制到编译器里面就行
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Threading.Tasks;
9 using System.Windows.Forms;
10
11 namespace 子窗口打开其他子窗口并在父窗口新建按钮
12 {
13 public partial class Form1 : Form
14 {
15 static public string text;
16 private System.Windows.Forms.ToolStripStatusLabel Lab;
17 public void button_form1(string name)
18 {
19 this.Lab = new System.Windows.Forms.ToolStripStatusLabel();
20 this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[]
21 {this.Lab});
22 this.Lab.Name = name;
23 this.Lab.Text = text;
24 this.Lab.BorderSides = ToolStripStatusLabelBorderSides.All;
25 this.statusStrip1.Items[name].Click += Form1_Click;
26
27 }
28 public void mess(string name)
29 {
30 this.statusStrip1.Items[name].Dispose();
31 }
32 private void Form1_Click(object sender, EventArgs e)
33 {
34 //throw new NotImplementedException();
35 string for_name = ((System.Windows.Forms.ToolStripStatusLabel)sender).Name;
36 Form test = Application.OpenForms[for_name];
37 test.Activate();
38 test.WindowState = FormWindowState.Normal;
39 }
40
41
42 public Form1()
43 {
44 InitializeComponent();
45 this.IsMdiContainer = true;
46 }
47
48 public void openform_menu(menu f, string name)
49 {
50 Form test = Application.OpenForms[name];
51 f.MdiParent = this;
52
53 if (test == null/* || test.IsDisposed*/)
54 {
55
56 f.WindowState = FormWindowState.Maximized;
57 f.Button_event += new menu.FormMain_button(button_form1);
58 f.Button_event_Dispose += new menu.FormMain_button(mess);
59 f.Show();
60
61 }
62 else
63 {
64 test.Activate();
65 }
66 }
67
68 private void toolStripButton1_Click(object sender, EventArgs e)
69 {
70 form_m1 f1 = new form_m1();
71 string name = f1.Name;
72 openform_menu(f1,name);
73 }
74
75 private void toolStripButton2_Click(object sender, EventArgs e)
76 {
77 form_m2 f2 = new form_m2();
78 string name = f2.Name;
79 openform_menu(f2, name);
80 }
81 }
82 }
好了,前两个功能完成 弄俩图片看下效果
3、主窗体启动时自动打开一个子窗体,并同样在状态栏生成一个按钮,这个子窗体有按钮若干,这些按钮实现与主窗体的菜单栏的按钮一样的功能;
这个功能有些麻烦,不过也只是把上面的东西复制粘贴了一遍
好吧,开启搬砖模式
分析 ①自动打开的这个子窗体要生成一个按钮,所以就要调用父窗体下的生成和释放功能,要想调用这俩功能就要用到menu中的那几行委托和事件声明代码,复制
②要想窗体创建时生成按钮,窗体关闭时释放按钮,那么form_m1中的 OnShown和OnClosed也必不可少,复制
这个子窗体的按钮的功能与主窗体的功能一样,这又该咋办呢,我想想。。。。。。。。。。嗯。。。子窗口的按钮触发的事件等于父窗口的按钮的事件,这个功能还真有些蛋疼。
那么就继续复制,
③复制Form1中的48-66行 记得将 f.MdiParent = this;改为 f.MdiParent = Form1 窗体 然后复制两个按钮的代码
好吧,看看复制好后的完整代码
19-21 复制代码,这里更改了下事件的名字,便于理解后面的代码
25行 给按钮起了个名字(text值)
29-40 窗体创建和关闭的事件触发了委托声明的事件
42-58 的重点在于
f.Button_event += new menu.FormMain_button(Button_event_console);
f.Button_event_Dispose += new menu.FormMain_button(Button_event_Dispose_console);
这两行代码有点难以理解,但是仔细看下,就会发现,是把这两个事件做了关联。还好我更改了事件的名字
60-72 同样的传参调用
console.cs代码
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Threading.Tasks;
9 using System.Windows.Forms;
10
11 namespace 子窗口打开其他子窗口并在父窗口新建按钮
12 {
13 public partial class console : Form
14 {
15 public console()
16 {
17 InitializeComponent();
18 }
19 public delegate void FormMain_button(string name);
20 public event FormMain_button Button_event_console;
21 public event FormMain_button Button_event_Dispose_console;
22
23 public void load_display()
24 {
25 Form1.text = "控制台";
26 Button_event_console(Name);
27
28 }
29 public void close_dispose()
30 {
31 Button_event_Dispose_console(Name);
32 }
33 protected override void OnShown(EventArgs e)
34 {
35 load_display();
36 }
37 protected override void OnClosed(EventArgs e)
38 {
39 close_dispose();
40 }
41
42 public void openform_menu(menu f, string name)
43 {
44 Form test = Application.OpenForms[name];
45 f.MdiParent = Form1.ActiveForm;
46
47 if (test == null/* || test.IsDisposed*/)
48 {
49 f.WindowState = FormWindowState.Maximized;
50 f.Button_event += new menu.FormMain_button(Button_event_console);
51 f.Button_event_Dispose += new menu.FormMain_button(Button_event_Dispose_console);
52 f.Show();
53 }
54 else
55 {
56 test.Activate();
57 }
58 }
59
60 private void button1_Click(object sender, EventArgs e)
61 {
62 form_m1 f1 = new form_m1();
63 string name = f1.Name;
64 openform_menu(f1, name);
65 }
66
67 private void button2_Click(object sender, EventArgs e)
68 {
69 form_m2 f2 = new form_m2();
70 string name = f2.Name;
71 openform_menu(f2, name);
72 }
73 }
74 }
在Form1窗体中为新的子窗体添加代码
1-4 在Form1启动时调用这个方法
9-10 子窗体console的两个事件订阅了Form1的两个方法,并将这两个方法给console下的两个委托调用
1 protected override void OnShown(EventArgs e)
2 {
3 console_f();
4 }
5
6 private void console_f()
7 {
8 console console_from = new console();
9 console_from.Button_event_console += new console.FormMain_button(button_form1);
10 console_from.Button_event_Dispose_console += new console.FormMain_button (mess);
11 string name = console_from.Name;
12 console_from.MdiParent = this;
13 console_from.Show();
14 }
所以整个Form1.cs的代码
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Threading.Tasks;
9 using System.Windows.Forms;
10
11 namespace 子窗口打开其他子窗口并在父窗口新建按钮
12 {
13 public partial class Form1 : Form
14 {
15 static public string text;
16 private System.Windows.Forms.ToolStripStatusLabel Lab;
17 public void button_form1(string name)
18 {
19 this.Lab = new System.Windows.Forms.ToolStripStatusLabel();
20 this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[]
21 {this.Lab});
22 this.Lab.Name = name;
23 this.Lab.Text = text;
24 this.Lab.BorderSides = ToolStripStatusLabelBorderSides.All;
25 this.statusStrip1.Items[name].Click += Form1_Click;
26
27 }
28 public void mess(string name)
29 {
30 this.statusStrip1.Items[name].Dispose();
31 }
32 private void Form1_Click(object sender, EventArgs e)
33 {
34 //throw new NotImplementedException();
35 string for_name = ((System.Windows.Forms.ToolStripStatusLabel)sender).Name;
36 Form test = Application.OpenForms[for_name];
37 test.Activate();
38 test.WindowState = FormWindowState.Normal;
39 }
40
41
42 public Form1()
43 {
44 InitializeComponent();
45 this.IsMdiContainer = true;
46 }
47
48 public void openform_menu(menu f, string name)
49 {
50 Form test = Application.OpenForms[name];
51 f.MdiParent = this;
52
53 if (test == null/* || test.IsDisposed*/)
54 {
55
56 f.WindowState = FormWindowState.Maximized;
57 f.Button_event += new menu.FormMain_button(button_form1);
58 f.Button_event_Dispose += new menu.FormMain_button(mess);
59 f.Show();
60
61 }
62 else
63 {
64 test.Activate();
65 }
66 }
67
68 private void toolStripButton1_Click(object sender, EventArgs e)
69 {
70 form_m1 f1 = new form_m1();
71 string name = f1.Name;
72 openform_menu(f1,name);
73 }
74
75 private void toolStripButton2_Click(object sender, EventArgs e)
76 {
77 form_m2 f2 = new form_m2();
78 string name = f2.Name;
79 openform_menu(f2, name);
80 }
81
82 protected override void OnShown(EventArgs e)
83 {
84 console_f();
85 }
86
87 private void console_f()
88 {
89 console console_from = new console();
90 console_from.Button_event_console += new console.FormMain_button(button_form1);
91 console_from.Button_event_Dispose_console += new console.FormMain_button (mess);
92 string name = console_from.Name;
93 console_from.MdiParent = this;
94 console_from.Show();
95 }
96
97
98 }
99 }
效果
正式投入使用时还需稍作修改
该内容来源于我正制作的一个小系统,一个小小的想法,给实现了下