父窗体下的某个子窗体调用其他继承基类的子窗体,并在父窗体下建立按钮,作为动态选项卡

2019/03/12 01:07
阅读数 79

实现目标:

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 }

 

效果

              

正式投入使用时还需稍作修改

 

该内容来源于我正制作的一个小系统,一个小小的想法,给实现了下

 

 

 

 

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部