c#软件开发学习笔记--Winform窗体第二期

WinForm 学习总结 - 第二十三天


一、登录功能与窗体切换

1.1 应用程序入口

namespace _01_登录
{
    internal static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            
            LoginFrm loginFrm = new LoginFrm();
            
            // 使用 ShowDialog() 以模态方式显示登录窗体
            if (loginFrm.ShowDialog() == DialogResult.OK)
            {
                // 登录成功后显示主窗体
                Application.Run(new BankCustormerFrm("admin"));
            }
        }
    }
}

1.2 登录窗体实现

public partial class LoginFrm : Form
{
    public LoginFrm()
    {
        InitializeComponent();
    }

    private void btnLogin_Click(object sender, EventArgs e)
    {
        // 验证账号
        if (string.IsNullOrWhiteSpace(txtAccount.Text))
        {
            label3.Text = "账号不能为空白!";
            return;
        }

        // 验证密码
        if (string.IsNullOrWhiteSpace(txtPassword.Text))
        {
            MessageBox.Show("密码不能为空白!");
            return;
        }

        // 验证账号密码
        if (!(txtAccount.Text == "admin" && txtPassword.Text == "admin"))
        {
            MessageBox.Show("账号或密码出错,请重新输入!");
            return;
        }

        // 登录成功,设置返回结果
        DialogResult = DialogResult.OK;
    }
}

1.3 主窗体接收参数

public partial class BankCustormerFrm : Form
{
    public BankCustormerFrm(string value)
    {
        InitializeComponent();
        label1.Text = $"欢迎{value}进入";
    }
}

二、模态对话框与非模态对话框

2.1 概念对比

特性模态对话框 (ShowDialog())非模态对话框 (Show())
窗口层级独占顶层,阻止操作其他窗口与主窗口平级,可自由切换
关闭方式Close() 关闭并销毁Hide() 隐藏(仍存在)
返回值返回 DialogResult无返回值
典型场景登录框、确认框工具栏、属性面板

2.2 关闭应用程序的方式

// 1. 关闭当前窗口(非主窗口无法退出程序)
this.Close();

// 2. 退出所有窗体(无法处理非托管线程)
Application.Exit();

// 3. 退出调用线程上的所有消息
Application.ExitThread();

// 4. 最彻底的退出方式(强制退出所有线程)
System.Environment.Exit(0);

推荐做法:在主窗体的 FormClosed 事件中使用:

private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
{
    if (tip != null)
    {
        tip.Dispose();
    }
    Dispose();
    System.Environment.Exit(0);
}

三、Controls 集合

3.1 遍历控件集合

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        
        // 遍历窗体上所有控件
        foreach (Control c in Controls)
        {
            Console.WriteLine(c);
            
            // 筛选特定类型控件
            if (c is Button)
            {
                Console.WriteLine(c.Text);
            }
        }
        
        // 通过索引访问控件
        Console.WriteLine(Controls[0]);
        Console.WriteLine(Controls[1]);
    }
}

四、消息提示框 (MessageBox)

4.1 基本用法

// 基本消息提示
MessageBox.Show("提示信息");

// 带标题
MessageBox.Show("提示信息", "窗口标题");

// 带按钮类型和图标
MessageBox.Show("提示信息", "窗口标题", 
    MessageBoxButtons.YesNo, 
    MessageBoxIcon.Stop, 
    MessageBoxDefaultButton.Button2);

4.2 MessageBoxButtons 枚举

枚举值按钮组合
OK确定
OKCancel确定、取消
YesNo是、否
YesNoCancel是、否、取消
RetryCancel重试、取消
AbortRetryIgnore中止、重试、忽略

4.3 MessageBoxIcon 枚举

枚举值图标样式
Information信息图标 (i)
Warning警告图标 (!)
Error错误图标 (X)
Question疑问图标 (?)
Asterisk信息图标
Exclamation警告图标
Hand错误图标
Stop错误图标

4.4 处理用户选择

DialogResult res = MessageBox.Show("确认删除吗", "删除", MessageBoxButtons.OKCancel);
if (res == DialogResult.OK)
{
    // 用户点击确定
    Controls.Remove(label1);
}

五、RadioButton 控件(单选框)

5.1 特性

  • 互斥性:同一容器内只能选择一个
  • Checked 属性true 表示选中,false 表示未选中
  • CheckedChanged 事件:选中状态改变时触发

5.2 代码示例

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        // 创建Panel作为容器
        Panel p1 = new Panel();
        p1.BackColor = Color.Red;
        p1.Size = new Size(100, 100);
        p1.Location = new Point(330, 0);

        // 创建单选框
        RadioButton r1 = new RadioButton();
        r1.Text = "男";
        r1.Location = new Point(30, 10);
        p1.Controls.Add(r1);

        RadioButton r2 = new RadioButton();
        r2.Text = "女";
        r2.Location = new Point(30, 30);
        r2.Checked = true; // 默认选中
        p1.Controls.Add(r2);

        // 添加事件处理
        r1.CheckedChanged += Fanfan;
        r2.CheckedChanged += Fanfan;

        this.Controls.Add(p1);
    }

    public void Fanfan(object o, EventArgs e)
    {
        RadioButton r = o as RadioButton;
        if (r.Checked)
        {
            Console.WriteLine("选择了" + r.Text);
        }
    }
}

5.3 关键要点

  1. 互斥性:同一容器内的 RadioButton 自动互斥
  2. 分组:不同容器(Panel/GroupBox)中的 RadioButton 互不影响
  3. 事件CheckedChanged 在选中状态改变时触发

六、CheckBox 控件(复选框)

6.1 特性

  • 独立选择:每个 CheckBox 独立,不互斥
  • Checked 属性true 表示勾选,false 表示未勾选
  • CheckedChanged 事件:勾选状态改变时触发

6.2 代码示例

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        
        // 动态创建 CheckBox
        CheckBox c1 = new CheckBox()
        {
            Text = "new出来的多选框",
            Location = new Point(180, 100),
            Checked = true, // 默认勾选
        };
        Controls.Add(c1);

        // 绑定事件
        checkBox2.CheckedChanged += checkBox1_CheckedChanged;
        checkBox3.CheckedChanged += checkBox1_CheckedChanged;
        c1.CheckedChanged += checkBox1_CheckedChanged;
    }

    private void checkBox1_CheckedChanged(object sender, EventArgs e)
    {
        CheckBox c = (CheckBox)sender;
        if (c.Checked)
        {
            Console.WriteLine(c.Text);
        }
    }
}

七、ListBox 控件(列表框)

7.1 选择模式

SelectionMode说明
None不可选择
One单选(默认)
MultiSimple多选(点击切换)
MultiExtended多选(支持 Ctrl/Shift)

7.2 代码示例

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        // 添加项
        listBox1.Items.Add("罗志祥");
        listBox1.Items.Add("李云迪");
        listBox1.Items.Add("蔡徐坤");

        // 动态创建 ListBox
        ListBox listBox = new ListBox();
        listBox.Location = new Point(100, 20);
        listBox.Size = new Size(100, 180);
        Controls.Add(listBox);

        // 批量添加
        string[] strings = new string[] { "111", "222", "333" };
        listBox.Items.AddRange(strings);

        // 设置多选模式
        listBox.SelectionMode = SelectionMode.MultiSimple;

        // 绑定事件
        listBox.SelectedIndexChanged += Xuanzhong;
    }

    public static void Xuanzhong(object sender, EventArgs e)
    {
        ListBox l1 = sender as ListBox;
        
        // 单选:获取选中项
        // Console.WriteLine(l1.SelectedItem);
        // Console.WriteLine(l1.SelectedIndex);

        // 多选:遍历所有选中项
        string ss = string.Empty;
        foreach (var item in l1.SelectedItems)
        {
            ss += item;
        }
        Console.WriteLine(ss);
    }
}

八、ComboBox 控件(下拉框)

8.1 特性

  • 结合文本框和列表框功能
  • 支持输入和选择
  • DropDownStyle 属性控制行为

8.2 代码示例

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        
        // 动态创建 ComboBox
        ComboBox cb = new ComboBox();
        cb.Size = new Size(60, 30);
        cb.Location = new Point(100, 100);
        Controls.Add(cb);

        // 添加项
        cb.Items.AddRange(new string[] { "吴亦凡", "罗志祥" });

        // 绑定事件
        cb.SelectedIndexChanged += Gaibian;
    }

    public static void Gaibian(object sender, EventArgs e)
    {
        ComboBox cb = sender as ComboBox;
        Console.WriteLine(cb.SelectedItem);   // 获取选中项
        Console.WriteLine(cb.SelectedIndex);  // 获取选中索引
    }
}

九、NumericUpDown 控件(数字输入框)

9.1 主要属性

属性说明
Value当前数值(decimal 类型)
Minimum最小值
Maximum最大值
Increment增减步长
DecimalPlaces小数位数
ThousandsSeparator是否显示千位分隔符

9.2 代码示例

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        
        NumericUpDown num = new NumericUpDown();
        num.Value = 10;           // 初始值
        num.Minimum = 0;          // 最小值
        num.Maximum = 100;        // 最大值
        num.Increment = 2;        // 步长
        num.DecimalPlaces = 0;    // 小数位数

        Controls.Add(num);

        // 绑定值改变事件
        num.ValueChanged += new EventHandler(numValueChanged);
    }

    private void numValueChanged(object sender, EventArgs e)
    {
        NumericUpDown num = (NumericUpDown)sender;
        MessageBox.Show("当前的值是: " + num.Value.ToString());
    }
}

十、PictureBox 控件(图片框)

10.1 图片加载方式

// 方式1:从文件加载
pictureBox.Image = Image.FromFile(@"C:\Images\0001.PNG");

// 方式2:设置图片路径
pictureBox.ImageLocation = @"C:\Images\0001.PNG";

// 方式3:从资源加载
pictureBox.Image = Properties.Resources.background;

10.2 SizeMode 属性

SizeMode说明
Normal图片位于左上角,超出部分被剪切
StretchImage拉伸图片以适应控件(可能失真)
Zoom保持比例缩放,完整显示
AutoSize控件根据图片自动调整大小
CenterImage图片居中显示,超出部分被剪切

10.3 代码示例

pictureBox1.Size = new Size(200, 150);
pictureBox1.Location = new Point(10, 10);
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Image = Image.FromFile(@"C:\Images\0001.PNG");

// 点击事件
pictureBox1.Click += (sender, e) => 
{
    MessageBox.Show("图片被点击了!");
};

十一、ImageList 组件

11.1 特性

  • 存储和管理多个图像
  • 供其他控件共享使用(如 ListView、TreeView)
  • 减少内存占用

11.2 轮播图示例

public partial class Form1 : Form
{
    int index = 0;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        // 显示第一张图
        pictureBox1.Image = imageList1.Images[index];
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // 切换到下一张
        index++;
        if (index >= imageList1.Images.Count)
        {
            index = 0;
        }
        pictureBox1.Image = imageList1.Images[index];
    }
}

十二、核心概念总结

12.1 窗体生命周期

构造函数 → Load事件 → 显示 → 用户交互 → FormClosing → 关闭

12.2 事件处理模式

// 方式1:设计器绑定
private void button1_Click(object sender, EventArgs e) { }

// 方式2:代码绑定(Lambda)
btn.Click += (sender, e) => { MessageBox.Show("点击"); };

// 方式3:代码绑定(方法引用)
btn.Click += button1_Click;

// 移除事件
btn.Click -= button1_Click;

12.3 控件创建方式

// 方式1:设计器拖放(可视化)
// 方式2:代码动态创建
Control control = new ControlType();
control.Property = value;
this.Controls.Add(control);

十三、实用技巧

  1. 控件访问:通过 Name 属性或 Controls 集合访问控件
  2. 类型转换:使用 as 关键字安全转换 sender 对象
  3. 资源管理:使用 Properties.Resources 管理项目资源
  4. 线程安全:UI 更新应在 UI 线程执行,使用 Control.Invoke
  5. 内存优化:使用 ImageList 共享图像资源

十四、使用场景

  1. 模态对话框用于需要用户确认的操作(如登录、确认删除)
  2. 非模态对话框用于辅助功能(如工具栏、搜索框)
  3. Controls 集合用于批量操作或动态控件管理
  4. 消息提示应适度使用,避免频繁弹窗影响用户体验
  5. 单选框分组使用 PanelGroupBox 容器
  6. 图片显示根据需求选择合适的 SizeMode
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值