利用委托技术实现多个子窗口与主窗口之间交互通信
【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();
}
}
}
}
点击查看代码
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);
}
}