一、多窗口通信方式
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 编辑过