惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cisco Talos Blog
Cisco Talos Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Martin Fowler
Martin Fowler
Recent Announcements
Recent Announcements
博客园 - 三生石上(FineUI控件)
月光博客
月光博客
博客园 - 聂微东
N
Netflix TechBlog - Medium
B
Blog RSS Feed
T
Tailwind CSS Blog
宝玉的分享
宝玉的分享
有赞技术团队
有赞技术团队
S
SegmentFault 最新的问题
The Register - Security
The Register - Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 司徒正美
J
Java Code Geeks
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
Engineering at Meta
Engineering at Meta
T
The Blog of Author Tim Ferriss
C
CXSECURITY Database RSS Feed - CXSecurity.com
AWS News Blog
AWS News Blog
The Hacker News
The Hacker News
Scott Helme
Scott Helme
MongoDB | Blog
MongoDB | Blog
C
CERT Recently Published Vulnerability Notes
L
Lohrmann on Cybersecurity
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
T
The Exploit Database - CXSecurity.com
S
Securelist
MyScale Blog
MyScale Blog
A
Arctic Wolf
V2EX - 技术
V2EX - 技术
The GitHub Blog
The GitHub Blog
Simon Willison's Weblog
Simon Willison's Weblog
H
Hacker News: Front Page
D
DataBreaches.Net
S
Secure Thoughts
腾讯CDC
TaoSecurity Blog
TaoSecurity Blog
Project Zero
Project Zero
H
Help Net Security
P
Privacy International News Feed
Cloudbric
Cloudbric
博客园_首页
Latest news
Latest news
小众软件
小众软件

博客园 - 刚刚

【转】Winform中textBox通过正则表达式限制只能输入数字且是两位小数 【转】WinForm中TextBox只能输入数字 【转】Visual Studio2019报错/plugin.vs.js,行:1074,错误:缺少标识符、字符串或数字的解决方法 奇虎360诉腾讯QQ垄断案之我见(3Q大战之我见) 超图软件(SuperMap)学习资料:桌面软件(Deskpro) ☠360与腾讯QQ的战争☠之我见 “密码人”越来越多将会出现“密码危机” SuperMap Objects开发——下载安装地址、许可配置和控件加载 决定将本博客技术知识从VS.Net转型SuperMap产品动态与开发 八零年代人的2009年 微软自打击盗版风波后推出了多种正版推广限时促销活动 【转】JavaScript写的Cookie类 ASP.NET开发在JavaScript有中文汉字时出现乱码时简单有效的解决方法 怀疑自己的笔记本电脑可能受到了网络攻击被人监视或操控 Visual Studio.Net 2005中用SqlDataSource处理数据库特殊数据类型 Visual Studio.Net 2005中验证控件的一个使用方法 对微软2008年10月20日后推行的打击盗版举措的个人看法 【转】娱乐八卦——关于孙悟空的授业师傅的分析 【转】GIS原理学习
【转】C# winform窗体间传值(使用委托或事件)
刚刚 · 2020-11-15 · via 博客园 - 刚刚

工程中总共介绍了三种方法:
###方法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