开发环境:VS2012,c#,.net framework 4.7.2
前言,我们在开发winform类型的应用程序的时候,经常需要在父子窗口之间传递信息,比如在主窗口显示子窗口的操作动作信息,关闭子窗口的时候需要把选择的信息带回主窗口等等。
由于父子窗口并不在同一个线程运行,所以不能直接调用其方法传递信息,要实现这个功能,使用C#开发,最好的方法就是用委托来实现。
委托是一种安全的调用,系统会处理有关跨线程调用的一切问题,我们只需要按照步骤去实现既可。
委托的使用,我们分为5个步骤,可以对比C语言的函数指针来理解:
-
//第一步:声明委托类型(相当于定义一个函数指针的类型,是一个变量类型声明,和int,long类似)
public delegate void ShowMessage(string message); -
//第二步:定义委托变量(相当于定义一个函数指针变量)
public ShowMessage showTimeMsg = null; -
//第三步:实现将来被委托调用的方法(相当于实现一个动作的函数)
private void ShowCurrentTime(string time)
{
lblShowTime.Text = time;
} -
//第四步:给委托赋值(相当于给函数指针赋值)
SubFrm frm = new SubFrm();
frm.showTimeMsg = ShowCurrentTime; -
//第五步:通过委托调用,传递内容(相当于通过函数指针调用函数)
if (showTimeMsg != null)
this.Invoke(showTimeMsg, s);
实现demo效果如下:
父窗口代码:
namespace WindowsFormsDelegate
{
public partial class MainFrm : Form
{
public MainFrm()
{
InitializeComponent();
}
private void btnOpenWnd_Click(object sender, EventArgs e)
{
SubFrm frm = new SubFrm();
//第四步:给委托赋值(相当于给函数指针赋值)
frm.showTimeMsg = ShowCurrentTime;
frm.showListMsg = ShowListContent;
frm.ShowDialog();
}
/// <summary>
/// 显示当前时间
/// </summary>
/// <param name="time"></param>
//第三步:实现将来被委托调用的方法(相当于实现一个动作的函数)
private void ShowCurrentTime(string time)
{
lblShowTime.Text = time;
}
private void ShowListContent(string select)
{
lblListContent.Text = select;
}
}
}
子窗口代码
namespace WindowsFormsDelegate
{
public partial class SubFrm : Form
{
public SubFrm()
{
InitializeComponent();
timer_Clock.Interval = 1000;
timer_Clock.Start();
}
//第一步:声明委托类型(相当于定义一个函数指针的类型,是一个变量类型声明,和int,long类似)
public delegate void ShowMessage(string message);
//第二步:定义委托变量(相当于定义一个函数指针变量)
public ShowMessage showTimeMsg = null;
public ShowMessage showListMsg = null;
private void timer_Clock_Tick(object sender, EventArgs e)
{
DateTime dt = DateTime.Now;
string s = dt.ToLongTimeString();
lblShowTime.Text = s;
//第五步:通过委托调用,传递内容(相当于通过函数指针调用函数)
if (showTimeMsg != null)
this.Invoke(showTimeMsg, s);
}
private void lbItemList_SelectedIndexChanged(object sender, EventArgs e)
{
string s = lbItemList.GetItemText(lbItemList.SelectedIndex);
lblSelect.Text = $"选择了第{s}项:"+lbItemList.Text;
if (showListMsg != null)
this.Invoke(showListMsg, lblSelect.Text);
}
private void btnCloseWnd_Click(object sender, EventArgs e)
{
showTimeMsg = null;
showListMsg = null;
Close();
}
}
}
使用这个简单的例子,对照函数指针的原理来理解委托的使用,会比较容易理解透彻。
反过来,主窗口也是可以动态传递信息到子窗口的。