测试用例 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 编辑过