• 利用委托实现winform多个窗体间的传值


    最近用C#做上位机程序开发,要实现这样一个功能:
    父窗体创建了两个子窗体——子窗体1和子窗体2,子窗体1产生的数据要在子窗体2中显示出来。
    因为这两个子窗体本身之间并没有直接关联,他们都是由父窗体new出来的,所以就想着1的数据先发给父窗体,父窗体再发给2。这样结构上比较清晰,也符合松耦合的模式。结构如下:
    请添加图片描述

    窗体间数据传递的方法有多种,这里我们直接选择最被推荐的方法:委托(delegate)和事件(event)。

    子窗体1发送消息给父窗体

    在子窗体1中定义一个委托

    public delegate void SendMsg(string msg);
    
    • 1

    再定义一个事件

    public event SendMsg send;
    
    • 1

    点击发送按钮时,触发事件

        private void button1_Click(object sender, EventArgs e)
        {
            send(textBox1.Text);
        }
    
    • 1
    • 2
    • 3
    • 4

    完整代码

        public partial class Form_Child1 : Form
        {
            public delegate void SendMsg(string msg);
            public event SendMsg send;
    
            public Form_Child1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                send(textBox1.Text);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    委托可以理解为方法的代理,当我需要调用方法时可以直接调用委托,而事件是绑定到委托上的。当事件被触发,就会运行我们最终想要执行的方法。

    上面子窗体1已经注册好了委托和事件,接下来需要父窗体订阅该事件。

            private Form_Child1 form_Child1;            
            public Form1()
            {
                InitializeComponent();
    
                form_Child1 = new Form_Child1();    // 实例化子窗体1    
                form_Child1.send += new Form_Child1.SendMsg(receiveChild1Msg);  // 订阅子窗体1的send事件
                // 也可以简写成如下格式
                // form_Child1.send += receiveChild1Msg;
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    其中receiveChild1Msg是委托代理的方法,也就是要最终执行的方法,需要定义并实现

            private void receiveChild1Msg(string msg)
            {
                transfer(msg);  //此处写具体要做的事情
            }
    
    • 1
    • 2
    • 3
    • 4

    因为父窗体接收到子窗体1的消息后要转发给子窗体2,所以我们这里transfer(msg)做的事情就是把信息再转发出去,具体见后面解析。

    父窗体转发消息给子窗体2

    这回等于是父窗体给子窗体发消息,所以我们在父窗体中定义委托和事件,然后让子窗体2去订阅,代码如下,我们先去掉关于窗体1的那部分以方便观察。

            private Form_Child2 form_Child2;
    
            public delegate void TransferMsg(string msg);   // 定义转发消息的委托
            public event TransferMsg transfer;              // 定义事件
            public Form1()
            {
                InitializeComponent();
    
                form_Child2 = new Form_Child2();                    // 实例化子窗体2 
                transfer += new TransferMsg(form_Child2.getMsg);    // 子窗体2订阅transfer事件
                // 也可以简写成如下格式
                //transfer += form_Child2.getMsg;
    
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    所以上面父窗体接收到子窗体1消息后的那个transfer(msg)就是为了触发transfer事件。这时候transfer事件被触发,子窗体2中的getMsg就会被执行

            public void getMsg(string str)
            {
                BeginInvoke(new MethodInvoker(delegate {
                    listBox2.Items.Add(str);
                }));
    
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    信息就被接收到了,这样就完成了整个消息的传递过程。

    效果:
    在这里插入图片描述

  • 相关阅读:
    .NET验收
    Kafka高性能高吞吐的原因总结
    vue框架之插槽,组件的自定义,网络代理配置,网络公共路径配置
    2022年,真的是90%岗位需要自动化测试?
    fiddler在软件测试中的使用(详细版)
    floyd, 潜意识等
    Chrome开发者工具课程
    原来栈和队列之间其实也是可以互相转换的啊
    Android 理解/生成/使用/查看 签名(V1-V4)
    【Qt】Qt定时器类QTimer
  • 原文地址:https://blog.csdn.net/m0_67402914/article/details/124874789