WinForm之dataGridView 控件

在 WinForm 中,DataGridView是功能最强大的表格控件之一,用于显示、编辑、操作结构化数据(如数据库表、集合、DataTable 等)。它支持自定义列类型、数据绑定、单元格编辑、排序、筛选等功能,是数据管理类应用(如管理系统、数据报表)的核心控件。

一、控件核心功能与特点

  • 支持多种数据来源:可绑定DataTableList<T>、数据库查询结果等;

  • 灵活的列类型:内置文本列、复选框列、下拉框列、按钮列等,也可自定义列;

  • 丰富的交互:支持单元格编辑、行选择、排序、筛选、复制粘贴等;

  • 高度可定制:可自定义样式(颜色、字体)、单元格行为、编辑规则等。

二、核心属性与事件(表格整理)

类别名称说明
数据绑定DataSource绑定的数据源(如DataTableList<T>BindingSource等)
DataMember当数据源包含多个列表时,指定要显示的列表名称
AutoGenerateColumns是否自动根据数据源生成列(默认truefalse时需手动添加列)
交互控制AllowUserToAddRows是否允许用户添加新行(默认true,最后一行显示 “*” 表示可添加)
AllowUserToDeleteRows是否允许用户删除行(默认false
ReadOnly整个控件是否只读(true时禁止编辑所有单元格)
MultiSelect是否允许选择多行(默认truefalse时仅能选择一行)
SelectionMode选择模式(如FullRowSelect整行选择、CellSelect单元格选择等)
外观样式RowHeadersVisible是否显示行标题(左侧的行号列,默认true
ColumnHeadersVisible是否显示列标题(表头,默认true
AlternatingRowsDefaultCellStyle交替行的样式(用于区分相邻行,如隔行变色)
DefaultCellStyle单元格默认样式(字体、颜色、对齐方式等)
核心事件CellClick点击单元格时触发(可获取点击的单元格位置和值)
CellValueChanged单元格值修改后触发(用于实时保存或校验)
RowHeaderMouseClick点击行标题(行号)时触发(常用于选择行操作)
CellValidating单元格失去焦点时触发(用于输入校验,如限制数值范围、格式等)
DataBindingComplete数据绑定完成后触发(用于绑定后初始化样式或数据)

三、基础用法:绑定数据并显示

场景:展示学生信息列表

从工具箱中拉入事件

可以通过右键点击属性进行列添加,也可以直接点击dataGridView 控件上的箭头进行编辑

自定义样式(交替行颜色、表头样式)

再添加列的时候,可以添加不同样式的表格属性

1. 界面设计

在窗体中添加DataGridView控件(命名为dataGridView1),可适当调整大小以显示完整内容。

2. 代码实现(绑定 DataTable)
using System;
using System.Data;
using System.Windows.Forms;
​
namespace DataGridViewDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            // 初始化表格
            InitDataGridView();
            // 绑定数据
            BindData();
        }
​
        private void InitDataGridView()
        {
            // 不自动生成列(手动定义列更灵活)
            dataGridView1.AutoGenerateColumns = false;
​
            // 1. 添加ID列(文本列)
            DataGridViewTextBoxColumn idColumn = new DataGridViewTextBoxColumn();
            idColumn.Name = "ID"; // 列名(用于关联数据字段)
            idColumn.HeaderText = "学号"; // 表头显示文本
            idColumn.DataPropertyName = "ID"; // 绑定的数据源字段名
            idColumn.Width = 80;
            dataGridView1.Columns.Add(idColumn);
​
            // 2. 添加姓名列(文本列)
            DataGridViewTextBoxColumn nameColumn = new DataGridViewTextBoxColumn();
            nameColumn.Name = "Name";
            nameColumn.HeaderText = "姓名";
            nameColumn.DataPropertyName = "Name";
            nameColumn.Width = 100;
            dataGridView1.Columns.Add(nameColumn);
​
            // 3. 添加年龄列(文本列,限制为数字)
            DataGridViewTextBoxColumn ageColumn = new DataGridViewTextBoxColumn();
            ageColumn.Name = "Age";
            ageColumn.HeaderText = "年龄";
            ageColumn.DataPropertyName = "Age";
            ageColumn.Width = 60;
            dataGridView1.Columns.Add(ageColumn);
​
            // 4. 添加是否住校列(复选框列)
            DataGridViewCheckBoxColumn boardColumn = new DataGridViewCheckBoxColumn();
            boardColumn.Name = "IsBoarding";
            boardColumn.HeaderText = "是否住校";
            boardColumn.DataPropertyName = "IsBoarding";
            boardColumn.Width = 80;
            dataGridView1.Columns.Add(boardColumn);
​
            // 其他设置:整行选择、禁止删除行、允许添加行
            dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dataGridView1.AllowUserToDeleteRows = false;
            dataGridView1.AllowUserToAddRows = true;
        }
​
        // 绑定数据到表格
        private void BindData()
        {
            // 创建数据源(DataTable)
            DataTable dt = new DataTable();
            // 添加与表格列对应的字段
            dt.Columns.Add("ID", typeof(int));
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Age", typeof(int));
            dt.Columns.Add("IsBoarding", typeof(bool));
​
            // 添加示例数据
            dt.Rows.Add(101, "张三", 18, true);
            dt.Rows.Add(102, "李四", 19, false);
            dt.Rows.Add(103, "王五", 17, true);
​
            // 绑定数据源
            dataGridView1.DataSource = dt;
        }
    }
}

四、进阶用法与场景

1. 绑定自定义对象集合(List<T>)

除了DataTableDataGridView也可直接绑定到自定义类的集合,更适合面向对象开发:

// 定义学生类
public class Student
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
    public bool IsBoarding { get; set; }
}
​
// 绑定List<Student>到表格
private void BindListData()
{
    List<Student> students = new List<Student>
    {
        new Student { ID = 101, Name = "张三", Age = 18, IsBoarding = true },
        new Student { ID = 102, Name = "李四", Age = 19, IsBoarding = false }
    };
    dataGridView1.DataSource = students;
}
2. 单元格编辑与校验(如限制年龄范围)

通过CellValidating事件校验输入,确保年龄在 1-100 之间:

private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
    // 仅校验“年龄”列(索引为2,对应前面定义的ageColumn)
    if (dataGridView1.Columns[e.ColumnIndex].Name == "Age")
    {
        // 尝试将输入转换为整数
        if (!int.TryParse(e.FormattedValue.ToString(), out int age) || age < 1 || age > 100)
        {
            // 校验失败:提示并取消编辑
            e.Cancel = true; // 阻止焦点离开单元格
            dataGridView1.Rows[e.RowIndex].ErrorText = "年龄必须是1-100之间的数字";
        }
        else
        {
            // 校验成功:清除错误提示
            dataGridView1.Rows[e.RowIndex].ErrorText = "";
        }
    }
}
3. 获取选中行数据(如双击行查看详情)

通过CellDoubleClick事件获取选中行的数据:

private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
    // 忽略标题行(行索引≥0)
    if (e.RowIndex < 0) return;
​
    // 获取选中行
    DataGridViewRow selectedRow = dataGridView1.Rows[e.RowIndex];
​
    // 读取行中各列的值(根据列名或索引)
    int id = (int)selectedRow.Cells["ID"].Value;
    string name = selectedRow.Cells["Name"].Value.ToString();
    int age = (int)selectedRow.Cells["Age"].Value;
    bool isBoarding = (bool)selectedRow.Cells["IsBoarding"].Value;
​
    // 显示详情
    MessageBox.Show($"选中学生:\nID:{id}\n姓名:{name}\n年龄:{age}\n是否住校:{isBoarding}");
}
4. 自定义样式(交替行颜色、表头样式)

通过样式设置提升表格可读性:

private void SetGridViewStyle()
{
    // 表头样式:蓝色背景、白色文字、居中对齐
    dataGridView1.ColumnHeadersDefaultCellStyle.BackColor = System.Drawing.Color.SteelBlue;
    dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor = System.Drawing.Color.White;
    dataGridView1.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
​
    // 单元格样式:居中对齐
    dataGridView1.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
​
    // 交替行颜色(隔行变色)
    dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = System.Drawing.Color.LightGray;
​
    // 取消默认选中样式(避免蓝色高亮)
    dataGridView1.DefaultCellStyle.SelectionBackColor = System.Drawing.Color.LightBlue;
}
5. 动态添加 / 删除行
// 添加新行(假设数据源是DataTable)
private void btnAddRow_Click(object sender, EventArgs e)
{
    if (dataGridView1.DataSource is DataTable dt)
    {
        dt.Rows.Add(104, "赵六", 20, true); // 新增一行数据
    }
}
​
// 删除选中行
private void btnDeleteRow_Click(object sender, EventArgs e)
{
    if (dataGridView1.SelectedRows.Count > 0 && dataGridView1.SelectedRows[0].Index != dataGridView1.NewRowIndex)
    {
        dataGridView1.Rows.RemoveAt(dataGridView1.SelectedRows[0].Index);
    }
    else
    {
        MessageBox.Show("请选择要删除的行!");
    }
}

五、常见问题与解决方案

1. 数据不显示
  • 原因:

    • 未设置DataSource或数据源为空;

    • AutoGenerateColumns = false但未手动添加列,或DataPropertyName与数据源字段不匹配。

  • 解决:检查数据源是否有效,确保列的DataPropertyName与数据源字段名一致。

2. 编辑后数据未保存到数据源
  • 原因DataGridView默认实时更新绑定的数据源(如DataTable),但需确保数据源支持修改(如List<T>需实现INotifyPropertyChanged接口)。

  • 解决:若使用List<T>,让实体类实现INotifyPropertyChanged以触发数据更新。

3. 列宽 / 行高自适应内容

设置列宽自动适应内容:

// 列宽自适应内容(包括表头和单元格)
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
// 行高自适应内容
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
4. 排序功能失效
  • 原因:默认仅对DataTableBindingSource等支持排序的数据源有效,List<T>需手动实现排序。

  • 解决

    :使用BindingSource包装List<T>,并启用排序:

    BindingSource bs = new BindingSource();
    bs.DataSource = students;
    bs.Sort = "Age ASC"; // 按年龄升序
    dataGridView1.DataSource = bs;

六、适用场景总结

场景类型实现方式示例
数据库数据展示绑定DataTable(从数据库查询)展示客户列表、订单记录
可编辑的数据表格启用AllowUserToAddRows+ 编辑校验学生信息录入、商品信息修改
数据筛选与排序结合BindingSource实现按条件筛选数据、按列排序
复杂交互表格自定义列(下拉框、按钮)+ 事件处理带操作按钮的列表(查看 / 编辑 / 删除)

总结

DataGridView是 WinForm 中处理表格数据的核心控件,通过灵活的数据绑定、自定义列类型和事件处理,可满足从简单数据展示到复杂交互编辑的各种需求。使用时需注意数据源匹配、编辑校验和样式优化,以提升数据管理效率和用户体验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张謹礧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值