一、多窗口通信方式
C# WinForms 多窗口通信的方式有:
二、示例代码
C# WinForms中多窗口之间各种通信方式的示例。示例包含一个主窗口和多个子窗口,测试开发中常用的几种通信方式。
项目结构如下:

2.1 MessageCenter.cs 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MultiWindowCommunication.Message
{
public static class MessageCenter
{
public static event Action<string, string> MessageReceived;
public static void SendMessage(string sender, string message)
{
MessageReceived?.Invoke(sender, message);
}
}
}
2.2 ChildForm1.cs 代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MultiWindowCommunication.Forms
{
public interface IMainForm
{
void ReceiveMessageFromChild1(string message);
}
public partial class ChildForm1 : Form
{
public ChildForm1()
{
InitializeComponent();
}
private string _receivedMessage;
public string ReceivedMessage
{
get => _receivedMessage;
set
{
_receivedMessage = value;
txtReceived.Text = $"收到主窗口消息: {value}";
}
}
private readonly IMainForm _mainForm;
public ChildForm1(string initialMessage, IMainForm mainForm)
{
InitializeComponent();
_mainForm = mainForm;
txtReceived.Text = initialMessage;
}
private void btnSendToMain_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtMessage.Text) && _mainForm != null)
{
_mainForm.ReceiveMessageFromChild1(txtMessage.Text);
txtMessage.Clear();
}
}
}
}
2.3 ChildForm2.cs 代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MultiWindowCommunication.Forms
{
public partial class ChildForm2 : Form
{
public event EventHandler<string> SendMessageToMain;
public ChildForm2()
{
InitializeComponent();
}
public void ReceiveMessage(string message)
{
txtReceived.Text = $"收到主窗口消息: {message}";
}
private void btnSendToMain_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtMessage.Text))
{
SendMessageToMain?.Invoke(this, txtMessage.Text);
txtMessage.Clear();
}
}
}
}
2.4 ChildForm3.cs 代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MultiWindowCommunication.Forms
{
public partial class ChildForm3 : Form
{
private Action<string> _callback;
public ChildForm3()
{
InitializeComponent();
}
public void SetCallback(Action<string> callback)
{
_callback = callback;
}
private void btnSendToMain_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtMessage.Text) && _callback != null)
{
_callback(txtMessage.Text);
txtMessage.Clear();
}
}
}
}
2.5 ChildForm4.cs 代码
using MultiWindowCommunication.Message;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MultiWindowCommunication.Forms
{
public partial class ChildForm4 : Form
{
public ChildForm4()
{
InitializeComponent();
MessageCenter.MessageReceived += OnMessageReceived;
}
private void btnSendToAll_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtMessage.Text))
{
MessageCenter.SendMessage("ChildForm4", txtMessage.Text);
txtMessage.Clear();
}
}
private void OnMessageReceived(string sender, string message)
{
if (sender != "ChildForm4")
{
txtReceived.Text = $"从{sender}收到消息: {message}";
}
}
private void ChildForm4_FormClosing(object sender, FormClosingEventArgs e)
{
MessageCenter.MessageReceived -= OnMessageReceived;
}
}
}
2.6 MainForm.cs 代码

using MultiWindowCommunication.Forms;
using MultiWindowCommunication.Message;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MultiWindowCommunication
{
public partial class MainForm : Form, IMainForm
{
private ChildForm1 _childForm1;
private ChildForm2 _childForm2;
private ChildForm3 _childForm3;
private ChildForm4 _childForm4;
public MainForm()
{
InitializeComponent();
MessageCenter.MessageReceived += OnMessageFromMessageCenter;
}
#region 打开子窗口的方法
private void btnOpenForm1_Click(object sender, EventArgs e)
{
if (_childForm1 == null || _childForm1.IsDisposed)
{
_childForm1 = new ChildForm1("来自主窗口的初始消息", this);
_childForm1.Show();
}
else
{
_childForm1.BringToFront();
}
}
private void btnOpenForm2_Click(object sender, EventArgs e)
{
if (_childForm2 == null || _childForm2.IsDisposed)
{
_childForm2 = new ChildForm2();
_childForm2.SendMessageToMain += OnMessageFromChildForm2;
_childForm2.Show();
}
else
{
_childForm2.BringToFront();
}
}
private void btnOpenForm3_Click(object sender, EventArgs e)
{
if (_childForm3 == null || _childForm3.IsDisposed)
{
_childForm3 = new ChildForm3();
_childForm3.SetCallback(OnMessageFromChildForm3);
_childForm3.Show();
}
else
{
_childForm3.BringToFront();
}
}
private void btnOpenForm4_Click(object sender, EventArgs e)
{
if (_childForm4 == null || _childForm4.IsDisposed)
{
_childForm4 = new ChildForm4();
_childForm4.Show();
}
else
{
_childForm4.BringToFront();
}
}
#endregion
#region 接收来自子窗口的消息
public void ReceiveMessageFromChild1(string message)
{
AddMessageToLog($"从ChildForm1收到: {message}");
}
private void OnMessageFromChildForm2(object sender, string e)
{
AddMessageToLog($"从ChildForm2收到: {e}");
}
private void OnMessageFromChildForm3(string message)
{
AddMessageToLog($"从ChildForm3收到: {message}");
}
private void OnMessageFromMessageCenter(string sender, string message)
{
AddMessageToLog($"从{sender}通过消息中心收到: {message}");
}
#endregion
#region 向子窗口发送消息
private void btnSendToForm1_Click(object sender, EventArgs e)
{
if (_childForm1 != null && !_childForm1.IsDisposed)
{
_childForm1.ReceivedMessage = txtMessage.Text;
}
else
{
MessageBox.Show("请先打开ChildForm1");
}
}
private void btnSendToForm2_Click(object sender, EventArgs e)
{
if (_childForm2 != null && !_childForm2.IsDisposed)
{
_childForm2.ReceiveMessage(txtMessage.Text);
}
else
{
MessageBox.Show("请先打开ChildForm2");
}
}
private void btnSendToALL_Click(object sender, EventArgs e)
{
MessageCenter.SendMessage("MainForm", txtMessage.Text);
}
#endregion
private void AddMessageToLog(string message)
{
txtLog.AppendText($"[{DateTime.Now:HH:mm:ss}] {message}{Environment.NewLine}");
txtLog.ScrollToCaret();
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
MessageCenter.MessageReceived -= OnMessageFromMessageCenter;
if (_childForm1 != null && !_childForm1.IsDisposed)
_childForm1.Close();
if (_childForm2 != null && !_childForm2.IsDisposed)
{
_childForm2.SendMessageToMain -= OnMessageFromChildForm2;
_childForm2.Close();
}
if (_childForm3 != null && !_childForm3.IsDisposed)
_childForm3.Close();
if (_childForm4 != null && !_childForm4.IsDisposed)
_childForm4.Close();
}
}
}
2.7 通信方式详解
WinForms中的几种常用的多窗口通信方式:
三、测试结果
四、建议
- 无论使用哪种方式,都要注意在窗口关闭时清理事件订阅,避免内存泄漏
可以根据实际项目需求选择合适的通信方式,也可以结合多种方式使用。
阅读原文:原文链接
该文章在 2025/10/20 10:25:29 编辑过