刚刚.Net相关知识技术互动平台(绿色天堂)
.Net知识技术交流、探讨、请教与共享(Visual Studio.Net、Asp.Net、VB/C#、.NetWindows应用程序、Windows服务、Socket通信、GIS、ArcGIS、SuperMap、JavaScript、Sql Server和Oracle等)

工程中总共介绍了三种方法:
###方法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             #endregion
101         }
102     }
103 }
复制代码

 

2、子窗体A部分代码

复制代码
 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     public partial class ObeserverFormA : Form
14     {
15         /// <summary>
16         /// 提供外部访问自己元素的方法
17         /// </summary>
18         /// <param name="txt"></param>
19         public void SetText(string txt)
20         {
21             this.txtMsg.Text = txt;
22         }
23         public ObeserverFormA()
24         {
25             InitializeComponent();
26         }
27 
28         public void AfterParentFrmTextChange(object sender, EventArgs e)
29         {
30             //拿到父窗体的传来的文本
31             MyEventArg arg = e as MyEventArg;
32             this.SetText(arg.Text);
33         }
34 
35         internal void MainFormTxtChaned(object sender, EventArgs e)
36         {
37             //取到主窗体的传来的文本
38             MyEventArg arg = e as MyEventArg;
39             this.SetText(arg.Text);
40             
41         }
42     }
43 }
复制代码

3、子窗体B的部分代码

复制代码
 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     public partial class ObeserverFormB : Form
14     {
15 
16         public ObeserverFormB()
17         {
18             InitializeComponent();
19         }
20 
21         /// <summary>
22         /// 提供外部访问自己元素的方法
23         /// </summary>
24         /// <param name="txt"></param>
25         public void SetText(string txt)
26         {
27             this.txtMsg.Text = txt;
28         }
29 
30         internal void MainFormTxtChaned(object sender, EventArgs e)
31         {
32             //取到主窗体的传来的文本
33             MyEventArg arg = e as MyEventArg;
34             this.SetText(arg.Text);
35         }
36     }
37 }
复制代码

 

所有的道理都是相通的,我们所做的并非是创造性的工作,所有的问题前人都曾经解决,所以我们更是无所畏惧,更何况我们不只有书店,而且有互联网,动动手脚就能找到需要的资料,我们只要认真研究就够了。所以当遇到困难时,请静下心来慢慢研究,因为只要用心,没有学不会的东西。
 
补充:
在和窗体同一个项目中定义的MyEventArgs.cs文件
文件内容如下
************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WinFrmDemo
{
public class MyEventArg :EventArgs
{
//传递主窗体的数据信息
public string Text { get; set; }
}
}

************
 
本文转载自:https://www.cnblogs.com/codeToUp/p/5371062.html
posted on 2020-11-15 20:52  刚刚  阅读(443)  评论(0编辑  收藏  举报