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


    窗体间传值

    今天得空,刚好看到网上好多人再找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

  • 相关阅读:
    CSDN博客QQ加群、微信
    Angularjs 中的 controller
    hdu 1728 逃离迷宫 bfs记转向
    【BLE】CC2541之加入自己定义任务
    asp.net给文件分配自己主动编号,如【20140710-1】
    <html>
    机器学习入门阶段程序猿易犯的5个错误
    时间复杂度
    Jackcard类似度和余弦类似度(向量空间模型)的java实现
    【分层图】分层图学习笔记
  • 原文地址:https://www.cnblogs.com/youmingkuang/p/7452891.html
Copyright © 2020-2023  润新知