测试用例 WinForms 多窗口应用示例,包含主窗口、子窗口、模态窗口和非模态窗口的创建和管理。
1. 项目结构和基础类
项目文件结构
MultiWindowApp/
├── Forms/
│ ├── MainForm.cs
│ ├── ChildForm.cs
│ ├── ModalDialogForm.cs
│ └── SettingsForm.cs
├── Models/
│ └── UserData.cs
└── Program.cs

窗口是空白窗口


数据模型类
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace MultiWindowApp.Models{ public class UserData { public string Name { get; set; } public int Age { get; set; } public string Email { get; set; } public DateTime CreatedAt { get; set; } = DateTime.Now; public override string ToString() { return $"{Name} (Age: {Age}, Email: {Email})"; } } public class AppSettings { public string Theme { get; set; } = "Light"; public bool AutoSave { get; set; } = true; public int MaxRecentFiles { get; set; } = 5; public string Language { get; set; } = "Chinese"; }}
2. 子窗口实现
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 MultiWindowApp.Forms{ public partial class ChildForm : Form { private MainForm mainForm; private TextBox textBoxContent; private Button btnSendToMain; private Button btnClose; public string Content => textBoxContent.Text; public ChildForm(string title, MainForm mainForm) { this.mainForm = mainForm; this.Text = title; InitializeComponent(); InitFormComponent(); } private void InitFormComponent() { this.Size = new Size(400, 300); this.StartPosition = FormStartPosition.CenterParent; this.FormBorderStyle = FormBorderStyle.SizableToolWindow; textBoxContent = new TextBox(); textBoxContent.Multiline = true; textBoxContent.Dock = DockStyle.Fill; textBoxContent.ScrollBars = ScrollBars.Vertical; textBoxContent.Text = $"这是 {this.Text} 的内容区域。\r\n您可以在这里输入文本..."; Panel buttonPanel = new Panel(); buttonPanel.Dock = DockStyle.Bottom; buttonPanel.Height = 40; buttonPanel.Padding = new Padding(5); btnSendToMain = new Button(); btnSendToMain.Text = "发送到主窗口"; btnSendToMain.Dock = DockStyle.Right; btnSendToMain.Width = 100; btnSendToMain.Click += BtnSendToMain_Click; btnClose = new Button(); btnClose.Text = "关闭"; btnClose.Dock = DockStyle.Right; btnClose.Width = 80; btnClose.Margin = new Padding(5, 0, 0, 0); btnClose.Click += (s, e) => this.Close(); buttonPanel.Controls.Add(btnClose); buttonPanel.Controls.Add(btnSendToMain); this.Controls.Add(textBoxContent); this.Controls.Add(buttonPanel); } private void BtnSendToMain_Click(object sender, EventArgs e) { if (mainForm != null) { MessageBox.Show($"已向主窗口发送消息: {textBoxContent.Text}", "子窗口消息", MessageBoxButtons.OK, MessageBoxIcon.Information); } } protected override void OnActivated(EventArgs e) { this.Opacity = 1.0; base.OnActivated(e); } protected override void OnDeactivate(EventArgs e) { this.Opacity = 0.8; base.OnDeactivate(e); } }}
3. 模态对话框实现
using MultiWindowApp.Models;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 MultiWindowApp.Forms{ public partial class ModalDialogForm : Form { private TextBox txtName; private NumericUpDown numAge; private TextBox txtEmail; private Button btnOK; private Button btnCancel; public UserData UserData { get; private set; } public ModalDialogForm() { InitializeComponent(); InitFormComponent(); UserData = new UserData(); } private void InitFormComponent() { this.Size = new Size(350, 200); this.StartPosition = FormStartPosition.CenterParent; this.FormBorderStyle = FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Text = "用户信息对话框"; TableLayoutPanel tableLayout = new TableLayoutPanel(); tableLayout.Dock = DockStyle.Fill; tableLayout.Padding = new Padding(10); tableLayout.RowCount = 4; tableLayout.ColumnCount = 2; tableLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 25F)); tableLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 25F)); tableLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 25F)); tableLayout.RowStyles.Add(new RowStyle(SizeType.Percent, 25F)); tableLayout.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 80F)); tableLayout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F)); Label lblName = new Label { Text = "姓名:", TextAlign = ContentAlignment.MiddleRight }; txtName = new TextBox { Dock = DockStyle.Fill }; Label lblAge = new Label { Text = "年龄:", TextAlign = ContentAlignment.MiddleRight }; numAge = new NumericUpDown { Dock = DockStyle.Fill, Minimum = 1, Maximum = 120, Value = 25 }; Label lblEmail = new Label { Text = "邮箱:", TextAlign = ContentAlignment.MiddleRight }; txtEmail = new TextBox { Dock = DockStyle.Fill }; txtEmail.Text = "example@domain.com"; Panel buttonPanel = new Panel { Dock = DockStyle.Fill }; buttonPanel.Controls.Add(CreateButtonPanel()); tableLayout.Controls.Add(lblName, 0, 0); tableLayout.Controls.Add(txtName, 1, 0); tableLayout.Controls.Add(lblAge, 0, 1); tableLayout.Controls.Add(numAge, 1, 1); tableLayout.Controls.Add(lblEmail, 0, 2); tableLayout.Controls.Add(txtEmail, 1, 2); tableLayout.Controls.Add(buttonPanel, 0, 3); tableLayout.SetColumnSpan(buttonPanel, 2); this.Controls.Add(tableLayout); } private Panel CreateButtonPanel() { Panel panel = new Panel(); panel.Height = 30; panel.Dock = DockStyle.Bottom; btnOK = new Button { Text = "确定", DialogResult = DialogResult.OK, Size = new Size(75, 25), Location = new Point(125, 0) }; btnOK.Click += BtnOK_Click; btnCancel = new Button { Text = "取消", DialogResult = DialogResult.Cancel, Size = new Size(75, 25), Location = new Point(205, 0) }; this.AcceptButton = btnOK; this.CancelButton = btnCancel; panel.Controls.Add(btnOK); panel.Controls.Add(btnCancel); return panel; } private void BtnOK_Click(object sender, EventArgs e) { if (string.IsNullOrWhiteSpace(txtName.Text)) { MessageBox.Show("请输入姓名", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Warning); txtName.Focus(); return; } if (string.IsNullOrWhiteSpace(txtEmail.Text) || !txtEmail.Text.Contains("@")) { MessageBox.Show("请输入有效的邮箱地址", "输入错误", MessageBoxButtons.OK, MessageBoxIcon.Warning); txtEmail.Focus(); return; } UserData.Name = txtName.Text.Trim(); UserData.Age = (int)numAge.Value; UserData.Email = txtEmail.Text.Trim(); } }}
4. 设置窗口实现
using MultiWindowApp.Models;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 MultiWindowApp.Forms{ public partial class SettingsForm : Form { private AppSettings currentSettings; private ComboBox comboTheme; private CheckBox checkAutoSave; private NumericUpDown numMaxRecentFiles; private ComboBox comboLanguage; private Button btnSave; private Button btnCancel; public event Action<AppSettings> SettingsChanged; public SettingsForm(AppSettings settings) { currentSettings = settings; InitializeComponent(); InitFormComponent(); LoadSettings(); } private void InitFormComponent() { this.Size = new Size(400, 300); this.StartPosition = FormStartPosition.CenterParent; this.FormBorderStyle = FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.MinimizeBox = false; this.Text = "应用设置"; CreateControls(); } private void CreateControls() { TableLayoutPanel mainTable = new TableLayoutPanel(); mainTable.Dock = DockStyle.Fill; mainTable.Padding = new Padding(15); mainTable.RowCount = 5; mainTable.ColumnCount = 2; Label lblTheme = new Label { Text = "主题:", TextAlign = ContentAlignment.MiddleRight, Dock = DockStyle.Fill }; comboTheme = new ComboBox { Dock = DockStyle.Fill, DropDownStyle = ComboBoxStyle.DropDownList }; comboTheme.Items.AddRange(new object[] { "Light", "Dark", "Blue", "Green" }); Label lblAutoSave = new Label { Text = "自动保存:", TextAlign = ContentAlignment.MiddleRight, Dock = DockStyle.Fill }; checkAutoSave = new CheckBox { Text = "启用自动保存", Dock = DockStyle.Fill }; Label lblMaxFiles = new Label { Text = "最近文件数量:", TextAlign = ContentAlignment.MiddleRight, Dock = DockStyle.Fill }; numMaxRecentFiles = new NumericUpDown { Dock = DockStyle.Fill, Minimum = 1, Maximum = 20, Value = 5 }; Label lblLanguage = new Label { Text = "语言:", TextAlign = ContentAlignment.MiddleRight, Dock = DockStyle.Fill }; comboLanguage = new ComboBox { Dock = DockStyle.Fill, DropDownStyle = ComboBoxStyle.DropDownList }; comboLanguage.Items.AddRange(new object[] { "Chinese", "English", "Japanese", "Spanish" }); Panel buttonPanel = new Panel { Dock = DockStyle.Fill, Height = 40 }; btnSave = new Button { Text = "保存", Size = new Size(80, 30), Location = new Point(150, 5) }; btnCancel = new Button { Text = "取消", Size = new Size(80, 30), Location = new Point(235, 5) }; btnSave.Click += BtnSave_Click; btnCancel.Click += (s, e) => this.Close(); buttonPanel.Controls.Add(btnSave); buttonPanel.Controls.Add(btnCancel); mainTable.Controls.Add(lblTheme, 0, 0); mainTable.Controls.Add(comboTheme, 1, 0); mainTable.Controls.Add(lblAutoSave, 0, 1); mainTable.Controls.Add(checkAutoSave, 1, 1); mainTable.Controls.Add(lblMaxFiles, 0, 2); mainTable.Controls.Add(numMaxRecentFiles, 1, 2); mainTable.Controls.Add(lblLanguage, 0, 3); mainTable.Controls.Add(comboLanguage, 1, 3); mainTable.Controls.Add(buttonPanel, 0, 4); mainTable.SetColumnSpan(buttonPanel, 2); for (int i = 0; i < 4; i++) { mainTable.RowStyles.Add(new RowStyle(SizeType.Percent, 20F)); } mainTable.RowStyles.Add(new RowStyle(SizeType.Percent, 20F)); mainTable.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 120F)); mainTable.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F)); this.Controls.Add(mainTable); } private void LoadSettings() { comboTheme.SelectedItem = currentSettings.Theme; checkAutoSave.Checked = currentSettings.AutoSave; numMaxRecentFiles.Value = currentSettings.MaxRecentFiles; comboLanguage.SelectedItem = currentSettings.Language; } private void BtnSave_Click(object sender, EventArgs e) { AppSettings newSettings = new AppSettings { Theme = comboTheme.SelectedItem?.ToString() ?? "Light", AutoSave = checkAutoSave.Checked, MaxRecentFiles = (int)numMaxRecentFiles.Value, Language = comboLanguage.SelectedItem?.ToString() ?? "Chinese" }; SettingsChanged?.Invoke(newSettings); this.DialogResult = DialogResult.OK; this.Close(); } }}
5. 主窗口实现
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;using MultiWindowApp.Forms;using MultiWindowApp.Models;namespace MultiWindowApp{ public partial class MainForm : Form { private List<Form> openChildForms = new List<Form>(); private List<UserData> userList = new List<UserData>(); private AppSettings settings = new AppSettings(); private MenuStrip mainMenu; private ToolStrip toolStrip; private StatusStrip statusStrip; private Panel contentPanel; private ListBox listBoxUsers; public MainForm() { InitializeComponent(); InitMainForm(); UpdateStatus("应用程序已启动"); } private void InitMainForm() { this.Text = "多窗口应用示例 - 主窗口"; this.Size = new Size(800, 600); this.StartPosition = FormStartPosition.CenterScreen; this.WindowState = FormWindowState.Maximized; CreateToolStrip(); CreateStatusStrip(); CreateContentArea(); } private void CreateMainMenu() { mainMenu = new MenuStrip(); ToolStripMenuItem fileMenu = new ToolStripMenuItem("文件(&F)"); fileMenu.DropDownItems.Add("新建(&N)", null, (s, e) => CreateNewUser()); fileMenu.DropDownItems.Add("打开(&O)", null, (s, e) => OpenUserData()); fileMenu.DropDownItems.Add("-"); fileMenu.DropDownItems.Add("退出(&X)", null, (s, e) => Application.Exit()); ToolStripMenuItem windowMenu = new ToolStripMenuItem("窗口(&W)"); windowMenu.DropDownItems.Add("新建子窗口(&N)", null, (s, e) => OpenChildForm()); windowMenu.DropDownItems.Add("模态对话框(&M)", null, (s, e) => OpenModalDialog()); windowMenu.DropDownItems.Add("-"); windowMenu.DropDownItems.Add("层叠(&C)", null, (s, e) => LayoutMdi(MdiLayout.Cascade)); windowMenu.DropDownItems.Add("水平平铺(&H)", null, (s, e) => LayoutMdi(MdiLayout.TileHorizontal)); windowMenu.DropDownItems.Add("垂直平铺(&V)", null, (s, e) => LayoutMdi(MdiLayout.TileVertical)); windowMenu.DropDownItems.Add("排列图标(&A)", null, (s, e) => LayoutMdi(MdiLayout.ArrangeIcons)); ToolStripMenuItem settingsMenu = new ToolStripMenuItem("设置(&S)"); settingsMenu.DropDownItems.Add("应用设置(&A)", null, (s, e) => OpenSettingsForm()); mainMenu.Items.AddRange(new ToolStripMenuItem[] { fileMenu, windowMenu, settingsMenu }); this.MainMenuStrip = mainMenu; this.Controls.Add(mainMenu); } private void CreateToolStrip() { toolStrip = new ToolStrip(); ToolStripButton newUserBtn = new ToolStripButton("新建用户", null, (s, e) => CreateNewUser()); ToolStripButton childFormBtn = new ToolStripButton("子窗口", null, (s, e) => OpenChildForm()); ToolStripButton modalBtn = new ToolStripButton("模态对话框", null, (s, e) => OpenModalDialog()); ToolStripButton settingsBtn = new ToolStripButton("设置", null, (s, e) => OpenSettingsForm()); toolStrip.Items.AddRange(new ToolStripItem[] { newUserBtn, childFormBtn, modalBtn, new ToolStripSeparator(), settingsBtn }); this.Controls.Add(toolStrip); } private void CreateStatusStrip() { statusStrip = new StatusStrip(); ToolStripStatusLabel statusLabel = new ToolStripStatusLabel("就绪"); statusLabel.Spring = true; statusLabel.TextAlign = ContentAlignment.MiddleLeft; ToolStripStatusLabel timeLabel = new ToolStripStatusLabel(); timeLabel.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); Timer timer = new Timer(); timer.Interval = 1000; timer.Tick += (s, e) => timeLabel.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); timer.Start(); statusStrip.Items.AddRange(new ToolStripItem[] { statusLabel, timeLabel }); this.Controls.Add(statusStrip); } private void CreateContentArea() { contentPanel = new Panel(); contentPanel.Dock = DockStyle.Fill; contentPanel.BackColor = SystemColors.Window; listBoxUsers = new ListBox(); listBoxUsers.Dock = DockStyle.Left; listBoxUsers.Width = 250; listBoxUsers.SelectedIndexChanged += ListBoxUsers_SelectedIndexChanged; userList.Add(new UserData { Name = "张三", Age = 25, Email = "zhangsan@example.com" }); userList.Add(new UserData { Name = "李四", Age = 30, Email = "lisi@example.com" }); userList.Add(new UserData { Name = "王五", Age = 28, Email = "wangwu@example.com" }); RefreshUserList(); contentPanel.Controls.Add(listBoxUsers); this.Controls.Add(contentPanel); } private void RefreshUserList() { listBoxUsers.Items.Clear(); foreach (var user in userList) { listBoxUsers.Items.Add(user); } } private void ListBoxUsers_SelectedIndexChanged(object sender, EventArgs e) { if (listBoxUsers.SelectedItem is UserData selectedUser) { UpdateStatus($"选中用户: {selectedUser.Name}"); } } private void UpdateStatus(string message) { if (statusStrip.Items.Count > 0) { statusStrip.Items[0].Text = message; } } private void CreateNewUser() { using (var form = new ModalDialogForm()) { if (form.ShowDialog() == DialogResult.OK) { userList.Add(form.UserData); RefreshUserList(); UpdateStatus($"已创建用户: {form.UserData.Name}"); } } } private void OpenUserData() { OpenFileDialog dialog = new OpenFileDialog(); dialog.Filter = "文本文件|*.txt|所有文件|*.*"; if (dialog.ShowDialog() == DialogResult.OK) { UpdateStatus($"已打开文件: {dialog.FileName}"); } } private void OpenChildForm() { ChildForm childForm = new ChildForm($"子窗口 {openChildForms.Count + 1}", this); childForm.FormClosed += (s, e) => openChildForms.Remove((Form)s); childForm.Show(); openChildForms.Add(childForm); UpdateStatus($"已打开子窗口: {childForm.Text}"); } private void OpenModalDialog() { using (var form = new ModalDialogForm()) { if (form.ShowDialog() == DialogResult.OK) { MessageBox.Show($"用户数据: {form.UserData}", "模态对话框结果", MessageBoxButtons.OK, MessageBoxIcon.Information); } } } private void OpenSettingsForm() { SettingsForm settingsForm = new SettingsForm(settings); settingsForm.SettingsChanged += (newSettings) => { settings = newSettings; UpdateStatus($"设置已更新 - 主题: {settings.Theme}, 语言: {settings.Language}"); ApplySettings(settings); }; settingsForm.ShowDialog(); } private void ApplySettings(AppSettings newSettings) { if (newSettings.Theme == "Dark") { this.BackColor = Color.FromArgb(32, 32, 32); this.ForeColor = Color.White; } else { this.BackColor = SystemColors.Control; this.ForeColor = SystemColors.ControlText; } } protected override void OnFormClosing(FormClosingEventArgs e) { if (openChildForms.Count > 0) { DialogResult result = MessageBox.Show( "还有子窗口未关闭,确定要退出吗?", "确认退出", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (result == DialogResult.No) { e.Cancel = true; return; } } base.OnFormClosing(e); } }}
6. 程序入口
using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace MultiWindowApp{ static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); ShowSplashScreen(); Application.Run(new MainForm()); } static void ShowSplashScreen() { Form splash = new Form(); splash.Size = new System.Drawing.Size(300, 200); splash.StartPosition = FormStartPosition.CenterScreen; splash.FormBorderStyle = FormBorderStyle.FixedSingle; splash.BackColor = System.Drawing.Color.LightBlue; splash.Text = "多窗口应用,启动中..."; splash.Show(); System.Threading.Thread.Sleep(10000); splash.Close(); } }}
7. 测试
8. 说明
窗口类型和用途
主窗口 (MainForm)
子窗口 (ChildForm)
模态对话框 (ModalDialogForm)
设置窗口 (SettingsForm)
窗口间通信方式
构造函数传参
ChildForm childForm =newChildForm("标题",this);
公共属性和方法
publicstring Content => textBoxContent.Text;
事件机制
publiceventAction<AppSettings> SettingsChanged;
SettingsChanged?.Invoke(newSettings);
DialogResult
if(form.ShowDialog()== DialogResult.OK)
{
// 处理结果
}
实践
资源管理
线程安全
用户体验
可维护性
阅读原文:原文链接
该文章在 2025/10/20 10:29:05 编辑过