窗体间传值

今天得空,刚好看到网上好多人再找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、主窗体的部分代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace WinFrmDemo
{ public partial class MainForm : Form
{
#region 方法1(不推荐)--通过保存对象的引用调用的对象的公有方法实现窗体的传值
//当接收数据的窗体增加,需要修改发送消息的代码,并且增加相应数量的窗体引用 可扩展性差,耦合性较高
//public ObeserverFormA ChildFormA { get; set; }
//public ObeserverFormB ChildFormB { get; set; }
#endregion #region 方法2---委托方式传值
//定义发布消息的委托 委托是一个类型 委托可以在外部获得执行
public Action<string> SendMsg { get; set; }
#endregion #region 方法3(推荐)--事件方式
//增加event关键字
//定 义消息发布的事件 事件是委托的一个特殊实例 事件只能在类的内部触发执行
public event EventHandler SendMsgEvent; //使用默认的事件处理委托
#endregion public MainForm()
{
InitializeComponent();
} private void ParentFrm_Load(object sender, EventArgs e)
{ #region 方法1(不推荐)
//ObeserverFormA childFormA = new ObeserverFormA();
//ChildFormA = childFormA;
//childFormA.Show();
//ObeserverFormB childFormB = new ObeserverFormB();
//ChildFormB = childFormB;
//childFormB.Show();
#endregion #region 方法2---委托方式传值
//子窗体弹出来之前,为委托赋值,关注主窗体消息的变化,当有多个窗体需要接收信息,只需要在此修改即可
//ObeserverFormA childFormA = new ObeserverFormA();
//SendMsg += childFormA.SetText;//委托赋值
//childFormA.Show();
//ObeserverFormB childFormB = new ObeserverFormB();
//SendMsg += childFormB.SetText;
//childFormB.Show();
#endregion #region 方法3(推荐)--事件方式
//子窗体弹出来之前,注册事件,关注主窗体消息的变化,当有多个窗体需要接收信息,只需要在此修改即可
ObeserverFormA childFormA = new ObeserverFormA();
SendMsgEvent += childFormA.MainFormTxtChaned;//为子窗体注册事件,在子窗体中事件处理代码中设置文本
childFormA.Show();
ObeserverFormB childFormB = new ObeserverFormB();
SendMsgEvent += childFormB.MainFormTxtChaned;
childFormB.Show();
#endregion } //当MainForm中输入文本,点击发送消息,子窗体的文本框显示主窗体的数据
private void btnSendMsg_Click(object sender, EventArgs e)
{
#region 方法1(不推荐) //ChildFormA.SetText(this.txtMsg.Text);
//ChildFormB.SetText(this.txtMsg.Text); #endregion #region 方法2---委托方式传值
//if (SendMsg!=null)
//{
// SendMsg(this.txtMsg.Text);//执行所有注册的委托
//} #endregion #region 方法3(推荐)--事件方式
//触发事件
//EventArgs,写一个子类继承该类,子类中添加需要封装的数据信息,此处只需要传递string信息,详见MyEventArgs
SendMsgEvent(this,new MyEventArg(){Text=this.txtMsg.Text});
#endregion
}
}
}

2、子窗体A部分代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace WinFrmDemo
{
public partial class ObeserverFormA : Form
{
/// <summary>
/// 提供外部访问自己元素的方法
/// </summary>
/// <param name="txt"></param>
public void SetText(string txt)
{
this.txtMsg.Text = txt;
}
public ObeserverFormA()
{
InitializeComponent();
} public void AfterParentFrmTextChange(object sender, EventArgs e)
{
//拿到父窗体的传来的文本
MyEventArg arg = e as MyEventArg;
this.SetText(arg.Text);
} internal void MainFormTxtChaned(object sender, EventArgs e)
{
//取到主窗体的传来的文本
MyEventArg arg = e as MyEventArg;
this.SetText(arg.Text); }
}
}

3、子窗体B的部分代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace WinFrmDemo
{
public partial class ObeserverFormB : Form
{ public ObeserverFormB()
{
InitializeComponent();
} /// <summary>
/// 提供外部访问自己元素的方法
/// </summary>
/// <param name="txt"></param>
public void SetText(string txt)
{
this.txtMsg.Text = txt;
} internal void MainFormTxtChaned(object sender, EventArgs e)
{
//取到主窗体的传来的文本
MyEventArg arg = e as MyEventArg;
this.SetText(arg.Text);
}
}
}

来源:http://www.cnblogs.com/codeToUp/p/5371062.html

C# winform窗体间传值(使用委托或事件)的更多相关文章

  1. winform 窗体间传值

    WinForm 两窗体之间传值实例 2010-12-27 22:10:11|  分类: 学业|举报|字号 订阅     下载LOFTER我的照片书  |     窗体Form1和Form2 Form2 ...

  2. (C#)WinForm窗体间传值

      1.通过构造函数 特点:传值是单向的(不可以互相传值),实现简单 实现代码如下: 在窗体Form2中 int value1; string value2; public Form2 ( int v ...

  3. WinForm窗体间传值

    1.通过构造函数 特点:传值是单向的(不可以互相传值),实现简单 实现代码如下: 在窗体Form2中 int value1; string value2; public Form2 ( int val ...

  4. C#使用事件方式Winform窗体之间传值

    [摘自:http://www.cnblogs.com/codeToUp/p/5371062.html] 工程的源代码地址:https://github.com/yes-or-no/WinFormTra ...

  5. WinForm窗体间如何传值

    窗体间传递数据,无论是父窗体操作子窗体,还是子窗体操作符窗体,有以下几种方式: 公共静态变量: 使用共有属性: 使用委托与事件: 通过构造函数把主窗体传递到从窗体中: 一.通过静态变量 特点:传值是双 ...

  6. WinForm窗体间如何传值的几种方法

    (转) 窗体间传递数据,无论是父窗体操作子窗体,还是子窗体操作符窗体,有以下几种方式: 公共静态变量: 使用共有属性: 使用委托与事件: 通过构造函数把主窗体传递到从窗体中: 一.通过静态变量 特点: ...

  7. 【转】WinForm窗体显示和窗体间传值

    以前对WinForm窗体显示和窗体间传值了解不是很清楚 最近做了一些WinForm项目,把用到的相关知识整理如下 A.WinForm中窗体显示 显示窗体可以有以下2种方法: Form.ShowDial ...

  8. C#利用事件与委托进行窗体间传值简单小例子

    本篇博客是利用C#委托与事件进行窗体间传值的简单小例子 委托与事件的详细解释大家可以参照张子阳的博客: http://www.tracefact.net/CSharp-Programming/Dele ...

  9. C#窗体间传值的简便方法/工具

    一.问题:窗体间传值必须需要窗体之间有联系,具体有如下方式 窗体间传值涉及到窗体A必须拥有窗体B,这样才可以实现A-B之间传值 窗体A与窗体B在窗体/实例C中,A-B可互相通讯 其他方式,不细讨论,复 ...

随机推荐

  1. 102.自己实现ArrayList

    package collection; import java.util.ArrayList; import java.util.List; /** * 自己实现一个ArrayList,帮助理解底层结 ...

  2. 关于nginx配置虚拟主机

    前提:我的虚拟主机的外网ip为111.231.226.228(是云服务器哈)     本地测试环境为windows7(修改本地的hosts文件) 步骤:(安装nginx可以看看我文章“linux ng ...

  3. 使用Selenium+firefox抓取网页指定firefox_profile后的问题

    from: https://blog.csdn.net/chufazhe/article/details/51145834 摘要:在使用selenium和firefox抓取网页指定firefox_pr ...

  4. P1383 高级打字机

    P1383 高级打字机 主席树 一发主席树解决. 插入操作十分显然. 撤销操作复制前面的版本就行. 询问操作十分显然. #include<iostream> #include<cst ...

  5. 《论vue在前后端分离项目中的实践之年终总结》

    我是2014年的时候开始了解知道的vue,当时vue还不太成熟,想用但是又怕自己hold不住,况且那时候vue还没有成熟的(路由.验证.ui组件)插件,社区也是不温不火的,再说也没有合适的机遇让我去项 ...

  6. 【题解】bzoj 4327 JSOI2012 玄武密码

    原题传送门 我们先对所有询问串建立AC自动机(今天洛咕上有人分不清AC自动机和自动AC机) 然后将母串在AC自动机上跑,每走到一个点x,从x点出发沿着fail指针所能到的所有前缀都是匹配成功的,暴力向 ...

  7. mvc 遇到的问题

    VS2010无法加载项目,此安装不支持该项目类型. 错误产生的原因是以前是用2010建的,后来用2012打开,可能是经过转换后,2010又打不开了. 用VS2010无法加载项目,提示:无法打开项目文件 ...

  8. socket之 select模型

    前段时间一直想学习网络编程的select模型,看了<windows网络编程>的介绍,参考了别人的博客. 这里的资料主要来自http://www.cnblogs.com/RascallySn ...

  9. [c/c++] programming之路(2)、kill QQ,弹出系统对话框,吃内存等

    一.删除文件 二.盗取密码的原理 #include<stdlib.h> //杀掉QQ,然后提示网络故障,请重新登陆,弹出高仿界面,获取账号密码,然后打开QQ进行登录 void main() ...

  10. centos7 update network time

    yum install -y ntp crontab -e */5 * * * * /usr/bin/ntpdate ntp.api.bz ###   ntp.api.bz 是一组NTP集群服务器,之 ...