不同窗体处于不同线程,相互之间需要通信时,需要用到​​委托​​​或​​事件​​。

​Form1.cs​​:

using System.Windows.Forms;

namespace SelfLianXiDelegate
{

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

public void ChangeLblText(string str)
{
this.lblCounter.Text = str;
}
}
}

​Form2.cs​​:

using System;
using System.Windows.Forms;

namespace SelfLianXiDelegate
{
//public delegate void AddCounter(string str);

public partial class Form2 : Form
{

//public AddCounter addCounter;
Action<string> addCounter;
public Form2()
{
InitializeComponent();
Form1 form1 = new Form1();
addCounter = form1.ChangeLblText;
form1.Show();
}

int count = 0;
private void btnCounter_Click(object sender, EventArgs e)
{
count++;
if (addCounter != null) {
addCounter(count.ToString());
}
}
}
}

​Program.cs​​:

using System.Windows.Forms;

namespace SelfLianXiDelegate
{
class Program
{
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form2());
}
}
}

输出:

C# WInform 通过委托跨窗体传值_ide

按照事件的写法,这样子可能更标准一点。

​FrmA.cs 发布者​​:

using System;
using System.Windows.Forms;

namespace SelfLianXiDelegate
{
public delegate void AddCounter(string str); // [1]声明委托

public partial class FrmA : Form
{

public AddCounter addCounter; // [2]创建委托
//public event Action<string> addCounter; // [2]创建事件
public FrmA()
{
InitializeComponent();
}

int count = 0;
private void btnCounter_Click(object sender, EventArgs e)
{
count++;
addCounter?.Invoke(count.ToString()); // [3]发布事件
}
}
}

​FrmB.cs 订阅者​​:

using System.Windows.Forms;

namespace SelfLianXiDelegate
{

public partial class FrmB : Form
{
public FrmB(FrmA frmA)
{
InitializeComponent();
frmA.addCounter = ChangeLblText; // [4]订阅事件
// frmA.addCounter += ChangeLblText; // [4]订阅事件
}

public void ChangeLblText(string str) // [5]事件处理程序
{
this.lblCounter.Text = str;
}
}
}

​主程序​​:

using System.Windows.Forms;

namespace SelfLianXiDelegate
{
class Program
{
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

FrmA frmA = new FrmA();
FrmB frmB = new FrmB(frmA);
frmB.Show();

Application.Run(frmA);
}
}
}

输出:

C# WInform 通过委托跨窗体传值_ide_02

事件本质上就是委托的运用。但是直接用委托有种情况不安全,在订阅者中可以让​​委托 = null​​​,全部失效。事件就不一样,只允许​​+=​​​和​​-+​​​,除非自己的内部可以使用​​=​​。