利用委托技术实现多个子窗口与主窗口之间交互通信——修订版
上次发的《利用委托技术实现多个子窗口与主窗口之间交互通信》存在如下几个问题:
1.没有详细注释说明采用了哪几个委托,分别是干什么的,委托的5要素没有清晰的标识出来————详细注释出来;
2.当子窗口先打开,再关闭了以后,程序仍然可以响应“警告”“问题”....等弹框。————通过判断字符串的IsDisposed属性值
3.其他一些细节,比如:显示框的垂直进度条不会自动滑动到最新一行;显示框可以直接输入,不防呆;————设置控件Readonly属性
4.ChildForm的唯一标识号,按顺序增加减少存在bug,导致频繁新建子窗口,关闭,时窗体tile将会出现重复;————此次改为6位随机数后缀实现唯一窗口标题
针对以上问题,修改代码如下:
MainForm:
点击查看代码
using System;
using System.Windows.Forms;
/*
说明:本实例演示了利用委托技术来实现跨类(Form)来传递信息
共用了2个委托:
一个【1】【2】【3】【4】【5】子窗体的信息给到主窗口
一个【a】【b】【c】【d】【e】子窗体接受来自主窗体的信息
*/
namespace DelegateTestForm
{
//定义委托
public delegate void SendMsgDelegate(string msg);//【1】定义委托1类型:子窗口往主窗口发送消息
public delegate string ChildReceiveDelegate(string data);//【a】定义委托2类型:接受来自主窗口的信息
public partial class MainFrm : Form
{
string child_frm_tile_append = null;//定义一个子窗口标题后缀的变量
ChildReceiveDelegate _childReceive = null;//【b】定义主发给你从的委托变量
public MainFrm()
{
InitializeComponent();
this.Indicator.ScrollBars = ScrollBars.Both;
Indicator.Enabled = true;
Indicator.ReadOnly = true;
}
private void button1_Click(object sender, EventArgs e)//新建子窗口的按钮按下事件
{
ChildForm childFrm = new ChildForm();//实例化一个子窗口的对象,此时委托变量sdn就会被定义
child_frm_tile_append = Random6String(6);
childFrm.Text = "ChildForm"+ child_frm_tile_append;//修改打开的子窗口的标题,带上序号
_childReceive += childFrm.RecMainMsg;//【d】绑定委托
childFrm.sdn += MainReceMsg;//【4】绑定委托,sdn这个委托变量是在ChildForm.cs中定义的,这里在便绑定一个MainReceMsg(string data)方法
childFrm.Show();
}
private void MainReceMsg(string data)//【3】委托方法
{
this.Indicator.Text += $"[{this.Text}]" + data;
}
private void button2_Click(object sender, EventArgs e)//发送按钮按下事件
{
if (this.textBox1.Text!="") {
Indicator.Text += "[MainForm广播]:" + this.textBox1.Text + "\r\n";//本地的发送直接显示在indicator上,无须用什么委托
if (_childReceive!=null)
{
_childReceive.Invoke("[MainForm广播]:" + this.textBox1.Text);//【e】使用委托
}
}
else{
MessageBox.Show("警告:发送的信息不能为空", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void button3_Click(object sender, EventArgs e)
{
DialogResult dr = MessageBox.Show("确定要清空显示吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
if (dr == DialogResult.OK)
{
this.Indicator.Clear();
}
}
private void Indicator_TextChanged(object sender, EventArgs e)
{
Indicator.SelectionStart = Indicator.Text.Length;//将光标位置设置到当前内容的末尾
Indicator.ScrollToCaret();//滚动到光标位置
}
/// <summary>
/// 产生一个定义长度的6位随机数字的字符串
/// </summary>
/// <param name="stringlen"></param要生成的字串长度>
/// <returns>str</returns>
private string Random6String(int stringlen)
{
// Creating object of random class
Random rand = new Random();
int randValue;
string str = "";
char letter;
for (int i = 0; i < stringlen; i++)
{
// Generating a random number.
randValue = rand.Next(0, 9);
// Generating random character by converting
// the random number into character.
letter = Convert.ToChar(randValue+48);// Appending the letter to string.
str = str + letter;
}
return str;
}
}
}
ChildForm代码:
点击查看代码
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;//【2】定义委托变量
MessageBoxEx messageBoxEx = new MessageBoxEx();
public ChildForm()
{
InitializeComponent();
this.Indicator.ScrollBars = ScrollBars.Both;
Indicator.ReadOnly = true;
}
private void button2_Click(object sender, EventArgs e)
{
if (this.textBox1.Text != String.Empty) {
string data_out = this.textBox1.Text + "\r\n";
sdn.Invoke($"<--[{this.Text}]:" + data_out);//【5】调用委托,是的MainFrm接受到ChildFrm发送的信息
Indicator.Text += $"[{this.Text}]-->" + "[MainForm]:" + data_out;
}
else {
MessageBox.Show("警告:发送的信息不能为空", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void ChildForm_FormClosed(object sender, FormClosedEventArgs e)
{
this.Dispose();
}
public string RecMainMsg(string data)//【c】定义委托方法
{
if (!this.IsDisposed)//判断窗口是否被关闭了;
{
this.Indicator.Text += data + "\r\n";
String tempData = data.Substring(13, 2);
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;
}
}
return data;//委托的有返回string类型,这里也必须有
}
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);
private void ChildForm_Load(object sender, EventArgs e)
{
}
private void Indicator_TextChanged(object sender, EventArgs e)
{
Indicator.SelectionStart = Indicator.Text.Length;//将光标位置设置到当前内容的末尾
Indicator.ScrollToCaret();//滚动到光标位置
}
}
}
最终实现的效果: