C#WinForm 窗体切换与窗体传值(登录跳转案例)+WinForm 窗体传值(从上往下传、从下往上传)

一、知识点简介

在WinForm项目开发中,一个项目里面会有多个窗体,例如登录窗体、注册窗体、主窗体。本节课主要学习:程序入口Program文件作用、两种窗体弹出方式Show()和ShowDialog()、模态与非模态窗口区别、DialogResult对话框返回值、实现登录窗体跳转主窗体。

本案例业务逻辑:程序启动先打开登录界面,输入账号密码admin登录成功,自动关闭登录窗口,直接进入主窗体。

二、项目结构

1、Program.cs:程序入口文件,整个项目最先执行

2、FormLogin.cs:登录窗体(启动页面)

3、FormMain.cs:项目主窗体(登录成功跳转页面)

三、全部源代码

1、Program.cs 入口代码

复制代码
namespace _2窗体切换和窗体传值
{
    internal static class Program
    {
        //应用程序的主入口点,程序运行最先执行Main方法
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            //1.创建登录窗体对象
            FormLogin login = new FormLogin();
            //以模态对话框方式弹出登录窗体,接收窗体关闭的返回值
            DialogResult r = login.ShowDialog();

            //判断登录窗体返回值是否为OK
            if (r == DialogResult.OK)
            {
                //关闭登录窗口,启动主窗体作为程序主页面
                Application.Run(new FormMain());
            }
        }
    }
}

2、FormLogin.cs 登录窗体代码

复制代码
namespace _2窗体切换和窗体传值
{
    public partial class FormLogin : Form
    {
        public FormLogin()
        {
            InitializeComponent();
        }

        //登录按钮点击事件
        private void button1_Click(object sender, EventArgs e)
        {
            //校验账号和密码
            if (textBox1.Text == "admin" && textBox2.Text == "admin")
            {
                //给当前登录窗体设置对话框结果为OK
                this.DialogResult = DialogResult.OK;
            }
        }
    }
}

3、FormMain.cs 主窗体代码

复制代码
namespace _2窗体切换和窗体传值
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }
    }
}

四、整体执行流程

1、程序启动,执行Program里面的Main()方法;

2、创建FormLogin登录窗体,使用ShowDialog()模态弹出;

3、程序阻塞,等待登录窗体关闭;

4、用户输入账号密码admin/admin,点击登录按钮;

5、验证成功,设置 this.DialogResult = OK,登录窗体自动关闭;

6、Program接收返回值OK,关闭登录进程,开启主窗体FormMain。


五、逐行详细解析

(一)Program.cs 解析

1、基础初始化代码

Application.EnableVisualStyles(); 开启控件可视化样式,让界面更加美观。

Application.SetCompatibleTextRenderingDefault(false); 设置文本渲染格式,系统默认固定代码,禁止删除。

2、FormLogin login = new FormLogin();

在内存当中创建登录窗体对象,此时窗体不会显示。

3、DialogResult r = login.ShowDialog();

模态对话框的方式弹出登录窗体。

特点:代码阻塞,弹出新窗口后,后面代码暂停执行,必须关闭当前窗口,代码才会继续往下执行。

ShowDialog() 拥有返回值,返回类型为DialogResult(对话框结果)。

4、if (r == DialogResult.OK)

DialogResult是枚举,常用值:OK、Cancel、Yes、No。

判断用户是否登录成功,如果返回OK代表登录成功。

5、Application.Run(new FormMain());

Application.Run() 代表运行主窗体,一旦执行这句代码,程序的主进程绑定为主窗体,登录窗体进程直接结束,完美实现页面切换。

(二)FormLogin 登录窗体解析

1、账号密码判断

获取两个文本框的内容,判断账号和密码是否全部等于admin。

2、this.DialogResult = DialogResult.OK;

this代表当前登录窗体。

给窗体设置对话框结果为OK,设置完成后,当前登录窗体自动关闭,并且将OK返回给Program。


六、Show() 和 ShowDialog() 核心区别(必考)

1、Show() 非模态窗口

① 非模态弹出,多个窗体之间可以自由切换、互相操作;

② 不会阻塞代码,打开窗体的同时,后面代码立刻执行;

③ 没有返回值,无法获取窗体操作状态。

2、ShowDialog() 模态窗口

① 模态弹出,子窗口不关闭,无法操作父窗口;

② 阻塞代码执行,窗口不关闭,后续代码暂停;

③ 带有返回值(DialogResult),可以接收窗口状态;

④ 适合:登录框、弹窗、提示框、确认框。


七、窗体关闭与隐藏的区别

1、Close():关闭窗体,释放内存,窗体彻底销毁;

2、Hide():隐藏窗体,窗体仍然存在内存中,只是用户看不见,可以随时再次调用Show()显示;

3、如果主窗体Close关闭,所有子窗体会跟着全部关闭。


八、本案例优点

1、利用DialogResult返回值判断登录状态;

2、登录窗体直接自动销毁,不占用内存;

3、通过Application.Run切换主进程,页面切换最干净、最正规;

4、是企业项目标准的登录跳转写法。


九、总结

1、程序入口Main方法最先执行,负责启动整个项目;

2、Show()非模态:不阻塞代码、可随意切换窗口;

3、ShowDialog()模态:阻塞代码、独占窗口、带返回值;

4、DialogResult可以给模态窗口设置返回状态;

5、设置this.DialogResult.OK 可以自动关闭当前弹窗;

6、登录跳转最优方案:模态窗口 + DialogResult + Application.Run切换主窗体。

WinForm 窗体传值(从上往下传、从下往上传)

一、知识点简介

在WinForm项目中,一个项目存在多个窗体,我们经常需要在不同窗体之间互相传递数据。本节课主要学习两种传值方式:

1、从上一个窗体传递数据到下一个窗体(向下传值):使用带参构造函数传值

2、从下一个窗体传递数据到上一个窗体(向上传值):使用静态全局变量传值

额外拓展:窗体遍历所有控件、MessageBox弹窗高级用法、四种窗体关闭方式、模态窗口跳转逻辑。

案例业务:登录页面输入账号密码,验证成功后,把账号传递给主窗体,主窗体标题显示欢迎XXX登录。


二、项目文件结构

1、Program.cs:程序入口,定义全局静态变量,控制窗体跳转

2、Form1.cs:登录窗体(起始窗体)

3、Form2.cs:主窗体(接收数据窗体)


三、完整全部源代码

1、Program.cs 入口文件

复制代码
namespace _3传值
{
    internal static class Program
    {
        //定义静态全局变量:用来接收登录页面传递过来的用户名
        public static string CurrentUsr = "";

        //应用程序主入口
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            //弹出登录窗体(模态窗口)
            Form1 form1 = new Form1();
            DialogResult r = form1.ShowDialog();

            //判断登录窗体是否返回OK(登录成功)
            if (r == DialogResult.OK)
            {
                //调用Form2的有参构造,把全局用户名传递给主窗体
                Application.Run(new Form2(CurrentUsr));
            }
        }
    }
}

2、Form1.cs 登录窗体

复制代码
namespace _3传值
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //遍历当前窗体所有控件,判断是否为按钮
            foreach (Control control in this.Controls)
            {
                //is关键字:判断对象是否属于指定类型
                if (control is System.Windows.Forms.Button)
                {
                    //强制类型转换
                    System.Windows.Forms.Button btn = (System.Windows.Forms.Button)control;
                }
            }
        }

        //登录按钮点击事件
        private void button1_Click(object sender, EventArgs e)
        {
            //校验账号密码
            if (textBox1.Text == "admin1" && textBox2.Text == "admin1")
            {
                //【向上传值】把输入的账号赋值给Program静态全局变量
                Program.CurrentUsr = textBox1.Text;

                //设置对话框结果为OK,自动关闭当前登录窗口
                this.DialogResult = DialogResult.OK;
            }
        }

        //高级弹窗按钮
        private void button3_Click(object sender, EventArgs e)
        {
            //弹出多功能提示框,接收用户点击的按钮
            DialogResult result = MessageBox.Show("确定要删除吗", "微信提示",
                MessageBoxButtons.OKCancel,
                MessageBoxIcon.Warning,
                MessageBoxDefaultButton.Button2);

            //判断用户点击的是确定还是取消
            if (result == DialogResult.OK)
            {
                MessageBox.Show("点击了确定键");
            }
            else
            {
                MessageBox.Show("点击了取消键");
            }
        }
    }
}

3、Form2.cs 主窗体

复制代码
namespace _3传值
{
    public partial class Form2 : Form
    {
        //自定义有参构造函数:接收从上一个页面传递过来的数据
        public Form2(string name)
        {
            InitializeComponent();
            //修改窗体标题,展示传递过来的用户名
            this.Text = "欢迎" + name + "进入系统";
        }
    }
}

四、两种窗体传值原理(必考)

1、向下传值(上窗体==>下窗体)

实现方式:自定义有参构造函数

原理:默认窗体只有无参构造,我们手动写一个带参数的构造函数,在new窗体对象的时候直接把数据传入。

执行:new Form2(CurrentUsr);

优点:简单、安全、最常用,专门用于页面跳转传值。

2、向上传值(下窗体==>上窗体)

实现方式:静态全局变量传值

原理:在Program类中定义static静态变量,静态变量属于类不属于对象,所有窗体都能直接访问。

赋值:Program.CurrentUsr = textBox1.Text;

取值:直接在任意窗体读取 Program.CurrentUsr


五、逐行代码详细解析

1、Program静态全局变量

复制代码
public static string CurrentUsr = "";

static静态变量,全局共享,所有窗体都可以直接读写,专门用来接收登录页面传上来的数据。

2、模态窗口跳转

复制代码
DialogResult r = form1.ShowDialog();

以模态方式弹出登录窗口,代码阻塞,窗口不关闭不会执行下面代码。

3、带参构造跳转主窗体

复制代码
Application.Run(new Form2(CurrentUsr));

调用Form2的有参构造,把全局储存的用户名传给主窗体,实现向下传值。

4、遍历窗体所有控件

复制代码
foreach (Control control in this.Controls)
{
    if (control is System.Windows.Forms.Button)
    {
        System.Windows.Forms.Button btn = (System.Windows.Forms.Button)control;
    }
}

1、this.Controls:当前窗体所有控件的集合;

2、所有控件父类都是Control;

3、is关键字:判断当前控件是不是Button类型;

4、判断成功后强制转换为Button类型,即可使用按钮专属属性。

5、四种关闭窗体的方式

① this.Close():关闭窗体,释放资源;

② 点击窗体右上角叉号关闭;

③ Dispose():销毁窗体资源;

④ this.DialogResult=DialogResult.OK:设置对话框状态,自动关闭(本案例使用)。

6、MessageBox高级弹窗

复制代码
MessageBox.Show("内容","标题",按钮类型,图标,默认按钮);

参数1:提示内容;参数2:弹窗标题;参数3:OK/取消按钮;参数4:警告图标;参数5:默认选中第二个按钮。

返回值DialogResult,用来判断用户点击的是确定还是取消。


六、完整运行流程

1、程序启动执行Program;

2、弹出Form1登录窗体;

3、输入账号admin1、密码admin1;

4、账号密码正确,把账号赋值给Program静态变量(向上传值);

5、设置DialogResult.OK,登录窗口自动关闭;

6、Program接收OK,调用Form2有参构造;

7、将用户名传递给Form2(向下传值);

8、主窗体标题显示:欢迎admin1进入系统。


七、总结

1、向下传值(跳转页面):重写带参构造函数 new Form2(数据)

2、向上传值(返回上一级):Program定义static全局变量

3、Controls可以遍历窗体所有控件,配合is做类型判断;

4、ShowDialog模态窗口带返回值,适合登录、弹窗;

5、MessageBox可以自定义按钮、图标、默认选项并接收用户操作。


八、易错点

1、普通变量无法全局共享,必须使用static静态变量才能跨窗体传值;

2、向下传值必须手写有参构造,不能直接赋值;

3、遍历控件时父类是Control,必须强制类型转换才能使用子类属性;

4、DialogResult只对ShowDialog()模态窗口生效,Show窗口无效。

相关推荐
allway22 小时前
How to Echo Multiline to a File in Bash [3 Methods]
开发语言·chrome·bash
Dontla2 小时前
git bash打开Claude code报错:Claude Code on Windows requires git-bash.(别把git装其他位置,严格按照默认安装)找不到claude code
windows·git·bash
weixin_462446232 小时前
手把手教你用 Bash 脚本自动更新 /etc/hosts —— 自动绑定网卡 IP 与节点名
开发语言·tcp/ip·bash
一个梦醒了2 小时前
安装git bash选项推荐
开发语言·git·bash
ct9782 小时前
React 状态管理方案深度对比
开发语言·前端·react
数量技术宅3 小时前
2026量化前沿:从Reddit热帖到Python实战,如何用赫斯特指数(Hurst)狙击虚假突破?
开发语言·python
comcoo3 小时前
电脑自动干活不用值守!OpenClaw 本地部署完整实操流程
windows·开源·github·open claw部署·open claw部署包
华如锦3 小时前
面了很多 Java转AI Agent方向,一些面试题总结
java·开发语言·人工智能·python·ai
huangdong_3 小时前
电商商品SKU图自动分类技术实现:从DOM解析到智能归档
开发语言