利用委托技术实现多个子窗口与主窗口之间交互通信

【0目标】
实现多个子窗口与主窗口之间交互通信:即主窗口可以通过按钮往所有子窗口发送信息,同时,任何一子窗口也可以给主窗口发送信息;
【1新建工程项目】

命名项目名称,一般其他选项默认即可。

【2开始编码】
新建一个Form类:

命名为MainFrm.cs;这个就是主窗口。(子窗口同理,这里为了较少重复工作量,先把MainFrm编写差不多,在复制为ChildForm即可)
拖拽如下几个控件:

注意此控件设置为多行显示。





(注意,Form其实也是一个控件,理论上它与一个button都是控件;)
MainFrm.cs的代码如下:

点击查看代码
using System;
using System.Windows.Forms;

namespace DelegateTestForm
{
    public partial class MainFrm : Form
    {
        //定义委托
        public delegate void SendMsgDelegate(string msg);//【1】子窗口往主窗口发送消息的委托
        public delegate void GetNoDelegate(int value);

        public delegate void ChildReceiveDelegate(string data);//


        public ChildReceiveDelegate childRece = null;

        int openCount = 0;//定义记录子窗口实例化的次数
        public MainFrm()
        {
            InitializeComponent();

            this.Indicator.ScrollBars = ScrollBars.Both;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ChildForm childFrm = new ChildForm();//实例化一个子窗口的对象,此时委托变量sdn就会被定义
            openCount++;//每点击一次“button1”便新建一个子窗口,计数加一;
            childFrm.Text = $"ChildForm{openCount}";//修改打开的子窗口的标题,带上序号
            childFrm.sdn += MainReceMsg;//【3】绑定委托,sdn这个委托变量是在ChildForm.cs中定义的,这里在便绑定一个MainReceMsg(string data)方法
            childFrm.getNo +=GetNo;


            childRece += childFrm.RecChildMsg;


            childFrm.Show();
        }

        private void MainReceMsg(string data)//【2】委托方法
        {
            this.Indicator.Text += data + "\r\n";
        }
        private void GetNo(int num)
        {
            num--;
            openCount = num;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            childRece("[MainForm广播]-->" + this.textBox1.Text);
        }
        
        private void button3_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show("确定要清空显示吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (dr == DialogResult.OK)
            {
                this.Indicator.Clear();
            }
        }
    }
}

****子窗口的开发**** 几乎可以复制主窗口的代码。复制MainFrm.cs然后稍作修改,改改UI,改改代码;最后完成代码如下:
点击查看代码
using System;
using System.Windows.Forms;
using static DelegateTestForm.MainFrm;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;


namespace DelegateTestForm
{
    public partial class ChildForm : Form
    {
       public SendMsgDelegate sdn = null;//【4】定义委托变量
        public GetNoDelegate getNo = null;

        MessageBoxEx messageBoxEx = new MessageBoxEx();

        public ChildForm()
        {
            InitializeComponent();
            this.Indicator.ScrollBars = ScrollBars.Both;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            sdn($"[{this.Text}]<--"+this.textBox1.Text);//【5】使用委托,使用时 sdn 这个委托变量在MainFrm.cs的 37 行已经绑定了接受与显示 的方法;
        }

        private void ChildForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            string strNo = Regex.Replace(this.Text,@"[^0-9]+","");
            int openNo = Convert.ToInt32(strNo);
            getNo(openNo);
        }
        public void RecChildMsg(string data)
        {
            this.Indicator.Text += data + "\r\n";
           String tempData = data.Substring(15,2);
            //IWin32Window hwnd = ;
            IntPtr hWnd = FindWindow(null,this.Text);
            switch (tempData)
            {
                case "警告":
                    MessageBox.Show("警告:响应弹出框", "信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    break;
                case "问题":
                    MessageBox.Show("问题:响应弹出框", "信息", MessageBoxButtons.OK, MessageBoxIcon.Question);
                    break;
                case "错误":
                   MessageBoxEx.Show(this, "错误:响应弹出框", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                default:
                    break;
            }
        }
        private void button3_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show("确定要清空显示吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (dr == DialogResult.OK)
            {
                this.Indicator.Clear(); 
            }
            else
            {
            }
        }

        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    }
}
最终实现效果,如下图:

posted @ 2023-09-07 14:50  Stephen_Young  阅读(42)  评论(0编辑  收藏  举报