一、窗体弹出两种方式(Show / ShowDialog)
1. 非模态窗体 Show()
拆分代码(带考点注释)
// 考点:实例化新窗体对象,仅存在内存
FormMain main = new FormMain();
// 考点:非模态弹出,不阻塞主线程,前后窗体可自由切换操作
main.Show();
// 考点:隐藏当前窗体,窗体存活,只是不可见
this.Hide();
// 考点:关闭当前窗体,会连带关闭所有子窗体(慎用)
// this.Close();
核心特点
-
不阻塞代码:弹出瞬间,后续代码立刻执行
-
可多层操作:新旧窗体可以来回点击、切换焦点
-
独立窗口:多个窗体互不锁定
2. 模态窗体 ShowDialog()
拆分代码(带考点注释)
// 考点:实例化新窗体
FormMain main = new FormMain();
// 考点:模态弹出,阻塞当前线程,暂停执行后续代码
main.ShowDialog();
// 考点:必须等新窗体关闭后,该行代码才会执行
this.Close();
核心特点
-
阻塞代码执行:弹窗不关闭,后面代码全部暂停
-
锁定父窗体:新窗体不关闭,无法操作之前的窗体
-
自带返回值:可以获取 DialogResult 对话框结果
3. Show 与 ShowDialog 必考对比
|
代码阻塞 |
不阻塞,代码直接往下跑 |
阻塞,关闭弹窗才继续执行 |
|
窗体操作 |
多窗体可自由切换 |
锁定父窗体,只能操作新窗口 |
|
返回值 |
无返回值 |
有 DialogResult 对话框结果 |
|
适用场景 |
主页、多窗口并行页面 |
登录框、弹窗提示、确认框 |
二、登录窗体跳转主窗体(正统写法)
1. 登录页核心代码(Form1)
// 考点:账号密码校验逻辑
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text == "admin" && textBox2.Text == "admin")
{
// 考点:设置对话框返回结果为OK,告知主程序登录成功
this.DialogResult = DialogResult.OK;
}
}
2. 程序入口跳转逻辑(Program)
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// 考点:模态弹出登录框,阻塞主线程
Form1 login = new Form1();
DialogResult res = login.ShowDialog();
// 考点:登录框关闭后,根据结果判断是否进入主窗体
if (res == DialogResult.OK)
{
// 考点:重启应用主线程,替换主窗体
Application.Run(new FormMain());
}
}
3. 优势(必考)
-
解决 this.Close() 关闭主窗体导致程序退出 的问题
-
登录窗口彻底销毁,不再后台占用内存
-
真正实现:登录成功 → 主窗体成为程序新主窗口
三、窗体四种关闭方式(最全总结)
// 方式1:直接关闭当前窗体
this.Close();
// 方式2:释放所有资源,彻底销毁
this.Dispose();
// 方式3:点击窗体右上角关闭按钮(系统自带)
// 方式4:设置对话框结果,间接关闭弹窗
this.DialogResult = DialogResult.OK;
四、MessageBox 弹窗高级用法
// 考点:完整参数弹窗,可自定义按钮、图标、默认选中
DialogResult result = MessageBox.Show(
"确定要删除吗", // 提示内容
"微信提示", // 窗口标题
MessageBoxButtons.OKCancel, // 按钮样式
MessageBoxIcon.Warning, // 图标样式
MessageBoxDefaultButton.Button2 // 默认聚焦按钮
);
// 考点:接收弹窗返回值,判断用户点击
if (result == DialogResult.OK)
{
MessageBox.Show("点击了确定键");
}
else
{
MessageBox.Show("点击了取消键");
}
五、窗体双向传值(核心重难点)
1. 向下传值(上窗体 → 下窗体)
原理:通过子窗体带参构造函数传值
第一步:子窗体定义带参构造
public partial class Form2 : Form
{
// 考点:自定义构造函数,接收父窗体传递的数据
public Form2(string name)
{
InitializeComponent();
this.Text = "欢迎" + name + "进入系统";
}
}
第二步:父窗体跳转传值
// 考点:new对象时直接传参
Form2 form2 = new Form2("admin");
form2.ShowDialog();
2. 向上传值(下窗体 → 上窗体 / 全局传值)
原理:Program静态全局字段中转站传值
第一步:Program定义全局静态字段
internal static class Program
{
// 考点:静态全局变量,所有窗体均可访问
public static string CurrentUsr = "";
}
第二步:登录页给全局变量赋值
// 考点:把当前窗体数据存入全局静态变量
Program.CurrentUsr = textBox1.Text;
this.DialogResult = DialogResult.OK;
第三步:主窗体读取全局值
// 考点:程序入口根据全局值传参跳转
if (r == DialogResult.OK)
{
Application.Run(new Form2(CurrentUsr));
}
3. 双向传值总结
-
向下传值:子窗体构造函数传参(最正规、常用)
-
向上传值:Program静态全局字段中转
六、满分背诵口诀
-
Show弹窗不阻塞,前后窗体随便戳
-
Dialog弹窗会卡壳,关完窗口才干活
-
登录跳转改Result,主程序判果换新窗
-
向下传参构造带,向上传值全局载
-
静态字段全窗通,跨页传值最轻



