• 【转】C# winform窗体间传值(使用委托或事件)


    工程中总共介绍了三种方法:
    ###方法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
  • 相关阅读:
    小白初学iOS中OTA部署(适应iOS7.1)
    CocoaPods管理本地库简单步骤
    CocoaPods问题记录
    UIPanGestureRecognizer下方法
    2013年度总结(反思篇)
    iOS7中cell的分割线右移的解决方法
    接触CocoaPods遇到的问题
    iOS摄像头问题
    iPhone4激活出错,菜鸟试验!!!!!
    详解UIPickerView
  • 原文地址:https://www.cnblogs.com/lijigang/p/13978881.html
Copyright © 2020-2023  润新知