窗体间传值

今天得空,刚好看到网上好多人再找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. eclipse格式化代码样式

    1.Window->Preferences //Java 格式化 2.Java->Code Style->Formatter->New->Edit->Line Wr ...

  2. Autel Maxisys MS908CV Description

    The new Autel MaxiSys CV Heavy Duty Diagnostic is built on the powerful MaxiSys 908 platform and pro ...

  3. python的一些遗漏用法

    一. 补充基础数据类型的相关知识点 1. str. join() 把列表变成字符串 li = ["李嘉诚", "麻花藤", "⻩海峰", & ...

  4. python 3.7 方向键乱码

    原因是缺少安装包libreadline-dev 第一步安装libreadline-dev包:sudo apt-get install libreadline-dev(centos安装:yum -y i ...

  5. Prometheus监控学习笔记之解读prometheus监控kubernetes的配置文件

    0x00 概述 Prometheus 是一个开源和社区驱动的监控&报警&时序数据库的项目.来源于谷歌BorgMon项目.现在最常见的Kubernetes容器管理系统中,通常会搭配Pro ...

  6. PHP图片裁剪与缩放示例(无损裁剪图片)

    <?php /* *exif_imagetype -- 判断一个图像的类型 *功能说明:函数功能是把一个图像裁剪为任意大小的图像,并保持图像不变形 *参数说明:输入 需要处理图片的 文件名,生成 ...

  7. mysql Column count doesn't match value count at row 1

    今天执行批量插入的操作,发现报了错 mysql Column count doesn't match value count at row 1. 后来发现原因:是由于写的SQL语句里列的数目和后面的值 ...

  8. Spring Boot(十二):spring boot如何测试打包部署

    Spring Boot(十二):spring boot如何测试打包部署 一.开发阶段 1,单元测试 在开发阶段的时候最重要的是单元测试了,springboot对单元测试的支持已经很完善了. (1)在p ...

  9. JSch : channel never closed or EOF 通道未关闭

    最近,我们的项目在开发远程节点管理的时候,使用了jsch库.在测试的时候发现有个节点在cmd执行完成之后,channel.isClosed()一直都是false,导致请求无法返回,但是其它有些节点就没 ...

  10. amqp 抓包

    1. wireshark 2. tcpick -yR -r  file.name