窗体间传值
今天得空,刚好看到网上好多人再找winform窗体间传值的问题,由于昨天项目的优化的感觉不错,就写了个C# winform窗体间传值的demo,希望能给需要的人的带来帮助;
工程的源代码地址:https://github.com/yes-or-no/WinFormTransValueDemoByDelOrEvent.git
C#winform窗体间传值,三种方法示例,注释详细。使用方法:使用vs2013打开编译运行即可;
工程中总共介绍了三种方法:
###方法1:通过保存对象的引用调用其方法实现对子窗体的控制;
###方法2:通过委托,在子窗体显示之前,为委托赋值,关注主窗体的数据变化,当有当有多个窗体需要接收信息,只需要为委托继续赋值(+=)即可,实现了数据传递的解耦性;
###方法3:子窗体弹出来之前,注册事件,关注主窗体消息的变化,当有多个窗体需要接收信息,,只需要分别为窗体注册数据接收事件即可,实现了数据传递的解耦性;
方法2与方法3即为发布订阅模式(观察者模式)----我也是设计模式的初学者,如有问题欢迎大家email我,谢谢;
演示窗体的界面如下:
在MainForm中打开A、B窗体,在MainForm中输入文本数据,点击发送消息,A、B的文本框会显示对应的数据;
主窗体为消息的发布者,窗体A、B等等为消息的接收者;
部分代码如下(全部源代码参考上述链接):
1、主窗体的部分代码:
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 WinFrmDemo
12 {
13
14
15 public partial class MainForm : Form
16 {
17 #region 方法1(不推荐)--通过保存对象的引用调用的对象的公有方法实现窗体的传值
18 //当接收数据的窗体增加,需要修改发送消息的代码,并且增加相应数量的窗体引用 可扩展性差,耦合性较高
19 //public ObeserverFormA ChildFormA { get; set; }
20 //public ObeserverFormB ChildFormB { get; set; }
21 #endregion
22
23 #region 方法2---委托方式传值
24 //定义发布消息的委托 委托是一个类型 委托可以在外部获得执行
25 public Action<string> SendMsg { get; set; }
26 #endregion
27
28 #region 方法3(推荐)--事件方式
29 //增加event关键字
30 //定 义消息发布的事件 事件是委托的一个特殊实例 事件只能在类的内部触发执行
31 public event EventHandler SendMsgEvent; //使用默认的事件处理委托
32 #endregion
33
34
35
36 public MainForm()
37 {
38 InitializeComponent();
39 }
40
41 private void ParentFrm_Load(object sender, EventArgs e)
42 {
43
44 #region 方法1(不推荐)
45 //ObeserverFormA childFormA = new ObeserverFormA();
46 //ChildFormA = childFormA;
47 //childFormA.Show();
48 //ObeserverFormB childFormB = new ObeserverFormB();
49 //ChildFormB = childFormB;
50 //childFormB.Show();
51 #endregion
52
53 #region 方法2---委托方式传值
54 //子窗体弹出来之前,为委托赋值,关注主窗体消息的变化,当有多个窗体需要接收信息,只需要在此修改即可
55 //ObeserverFormA childFormA = new ObeserverFormA();
56 //SendMsg += childFormA.SetText;//委托赋值
57 //childFormA.Show();
58 //ObeserverFormB childFormB = new ObeserverFormB();
59 //SendMsg += childFormB.SetText;
60 //childFormB.Show();
61 #endregion
62
63
64 #region 方法3(推荐)--事件方式
65 //子窗体弹出来之前,注册事件,关注主窗体消息的变化,当有多个窗体需要接收信息,只需要在此修改即可
66 ObeserverFormA childFormA = new ObeserverFormA();
67 SendMsgEvent += childFormA.MainFormTxtChaned;//为子窗体注册事件,在子窗体中事件处理代码中设置文本
68 childFormA.Show();
69 ObeserverFormB childFormB = new ObeserverFormB();
70 SendMsgEvent += childFormB.MainFormTxtChaned;
71 childFormB.Show();
72 #endregion
73
74
75
76 }
77
78 //当MainForm中输入文本,点击发送消息,子窗体的文本框显示主窗体的数据
79 private void btnSendMsg_Click(object sender, EventArgs e)
80 {
81 #region 方法1(不推荐)
82
83 //ChildFormA.SetText(this.txtMsg.Text);
84 //ChildFormB.SetText(this.txtMsg.Text);
85
86 #endregion
87
88 #region 方法2---委托方式传值
89 //if (SendMsg!=null)
90 //{
91 // SendMsg(this.txtMsg.Text);//执行所有注册的委托
92 //}
93
94 #endregion
95
96 #region 方法3(推荐)--事件方式
97 //触发事件
98 //EventArgs,写一个子类继承该类,子类中添加需要封装的数据信息,此处只需要传递string信息,详见MyEventArgs
99 SendMsgEvent(this,new MyEventArg(){Text=this.txtMsg.Text});
100