DataGridView 用法教程:从入门到精通
DataGridView 是 Windows Forms 中功能最强大、最灵活的数据显示控件,它以表格形式展示数据,并支持丰富的交互功能,如排序、筛选、编辑和删除。

第一部分:基础入门
添加 DataGridView 控件
- 在 Visual Studio 中,打开或创建一个 Windows 窗体应用程序项目。
- 从“工具箱”中找到
DataGridView控件。 - 将其拖放到你的窗体上。
通过设计器绑定数据(最简单的方式)
这是最直观的方式,适合快速展示静态数据或来自数据库的数据。
示例:绑定一个数据表
假设你有一个名为 Products 的数据表,包含 ID, ProductName, Price, Stock 等列。
- 在窗体上选中
DataGridView控件。 - 在“属性”窗口中,找到
DataSource属性。 - 点击下拉箭头,选择“添加项目数据源...”。
- 在弹出的向导中,选择“数据库”,然后点击“下一步”。
- 选择你的数据连接(或新建一个),选择数据库对象,
Products表,点击“完成”。 DataGridView会自动生成列并填充数据。
优点:快速、可视化,无需编写代码。 缺点:灵活性较低,不适合动态数据。

通过代码绑定数据(最常用、最灵活的方式)
在实际开发中,我们通常在代码中动态地为 DataGridView 提供数据,最常见的数据源是 DataTable 和 BindingList。
示例 1:绑定 DataTable
using System;
using System.Data;
using System.Windows.Forms;
namespace DataGridViewTutorial
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
// 1. 创建一个 DataTable
DataTable productsTable = new DataTable("Products");
// 2. 定义列(列名和数据类型)
productsTable.Columns.Add("ID", typeof(int));
productsTable.Columns.Add("ProductName", typeof(string));
productsTable.Columns.Add("Price", typeof(decimal));
productsTable.Columns.Add("Stock", typeof(int));
// 3. 添加数据行
productsTable.Rows.Add(1, "笔记本电脑", 5999.99m, 50);
productsTable.Rows.Add(2, "无线鼠标", 99.50m, 200);
productsTable.Rows.Add(3, "机械键盘", 499.00m, 100);
productsTable.Rows.Add(4, "USB-C 扩展坞", 299.99m, 150);
// 4. 将 DataTable 绑定到 DataGridView
dataGridView1.DataSource = productsTable;
}
}
}
示例 2:绑定 BindingList
BindingList<T> 是一个实现了 IBindingList 接口的泛型列表,当列表中的数据发生变化时,DataGridView 会自动更新,非常适合用于数据绑定。

定义一个产品类:
public class Product
{
public int ID { get; set; }
public string ProductName { get; set; }
public decimal Price { get; set; }
public int Stock { get; set; }
}
然后在窗体代码中绑定数据:
using System;
using System.ComponentModel; // 需要引入这个命名空间
using System.Windows.Forms;
namespace DataGridViewTutorial
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
// 1. 创建一个 BindingList<Product>
BindingList<Product> productList = new BindingList<Product>();
// 2. 添加产品对象
productList.Add(new Product { ID = 1, ProductName = "笔记本电脑", Price = 5999.99m, Stock = 50 });
productList.Add(new Product { ID = 2, ProductName = "无线鼠标", Price = 99.50m, Stock = 200 });
productList.Add(new Product { ID = 3, ProductName = "机械键盘", Price = 499.00m, Stock = 100 });
productList.Add(new Product { ID = 4, ProductName = "USB-C 扩展坞", Price = 299.99m, Stock = 150 });
// 3. 将 BindingList 绑定到 DataGridView
dataGridView1.DataSource = productList;
}
}
}
第二部分:常用属性与自定义
列的属性
在 DataGridView 上点击智能标签(右上角的小箭头),选择“编辑列...”或在属性窗口中找到 Columns 属性,可以打开“编辑列”对话框。
| 属性名 | 说明 |
|---|---|
Name |
列的编程名称,用于在代码中引用该列。 |
HeaderText |
列在表头中显示的文本。 |
Visible |
true/false,控制列是否可见。 |
ReadOnly |
true/false,控制该列的单元格是否可编辑。 |
ValueType |
指定该列单元格的数据类型(如 typeof(int), typeof(string))。 |
AutoSizeMode |
设置列的自动调整大小模式,常用值: - None: 不自动调整。- AllCells: 根据所有单元格内容调整。- Fill: 列宽填充可用空间(常用)。 |
DefaultCellStyle |
设置单元格的默认样式(字体、颜色、对齐方式等)。 |
代码示例:
// 通过代码添加和配置列
dataGridView1.AutoGenerateColumns = false; // 禁止自动生成列,以便我们手动控制
DataGridViewTextBoxColumn idColumn = new DataGridViewTextBoxColumn();
idColumn.Name = "ID";
idColumn.HeaderText = "产品ID";
idColumn.DataPropertyName = "ID"; // 绑定到数据源的哪个属性
idColumn.ReadOnly = true;
DataGridViewTextBoxColumn nameColumn = new DataGridViewTextBoxColumn();
nameColumn.Name = "ProductName";
nameColumn.HeaderText = "产品名称";
nameColumn.DataPropertyName = "ProductName";
DataGridViewTextBoxColumn priceColumn = new DataGridViewTextBoxColumn();
priceColumn.Name = "Price";
priceColumn.HeaderText = "价格";
priceColumn.DataPropertyName = "Price";
priceColumn.DefaultCellStyle.Format = "C2"; // 格式化为货币,保留两位小数
// 将列添加到 DataGridView
dataGridView1.Columns.AddRange(new DataGridViewColumn[] { idColumn, nameColumn, priceColumn });
行和单元格的属性
| 属性名 | 说明 |
|---|---|
AllowUserToAddRows |
true/false,是否允许用户通过底部的空白行添加新数据。 |
AllowUserToDeleteRows |
true/false,是否允许用户通过右键菜单或 Delete 键删除行。 |
MultiSelect |
true/false,是否允许选择多行或多列。 |
SelectionMode |
选择模式,如 FullRowSelect(整行选中)、CellSelect(单个单元格选中)。 |
BackgroundColor |
控件的背景色。 |
AlternatingRowsDefaultCellStyle |
设置奇数行或偶数行的不同样式,以增强可读性。 |
第三部分:处理事件
事件是 DataGridView 交互的核心,以下是几个最重要的事件:
CellClick / CellDoubleClick
当用户点击或双击单元格时触发。
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
// e.RowIndex 是被点击的行索引
// e.ColumnIndex 是被点击的列索引
// 检查是否点击了行头(无效点击)
if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
{
// 获取被点击的单元格
DataGridViewCell clickedCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
MessageBox.Show($"你点击了: 行 {e.RowIndex}, 列 {e.ColumnIndex}\n内容: {clickedCell.Value}");
}
}
CellFormatting (单元格格式化)
在单元格显示内容之前触发,可以用来动态改变单元格的样式或显示值。
示例:将“Stock”列小于100的单元格背景色标红
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
// 我们只关心 "Stock" 这一列
if (dataGridView1.Columns[e.ColumnIndex].Name == "Stock")
{
// 确保值是整数
if (e.Value is int stock)
{
if (stock < 100)
{
// 将单元格的背景色设置为红色
e.CellStyle.BackColor = Color.LightCoral;
}
}
}
}
CellValueChanged (单元格值已更改)
当用户编辑单元格并按下 Enter 或离开单元格后,值发生变化时触发。
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0)
{
// 获取被修改的行
DataGridViewRow row = dataGridView1.Rows[e.RowIndex];
MessageBox.Show($"第 {e.RowIndex + 1} 行的数据已更新!");
// 在这里可以添加代码,将更新后的数据保存回数据库
}
}
UserAddedRow / UserDeletedRow (用户添加/删除行)
当用户通过界面添加或删除行时触发。
private void dataGridView1_UserAddedRow(object sender, DataGridViewRowEventArgs e)
{
MessageBox.Show("用户添加了一行新数据。");
// 在这里可以生成新ID,或执行其他初始化操作
}
private void dataGridView1_UserDeletedRow(object sender, DataGridViewRowEventArgs e)
{
MessageBox.Show("用户删除了一行数据。");
// 在这里可以从数据库中删除对应记录
}
第四部分:高级技巧
添加按钮列
允许在每一行添加一个按钮,用于执行特定操作(如编辑、删除)。
// 在设计器或代码中添加一个 DataGridViewButtonColumn DataGridViewButtonColumn deleteButtonColumn = new DataGridViewButtonColumn(); deleteButtonColumn.Name = "DeleteButton"; deleteButtonColumn.HeaderText = "操作"; deleteButtonColumn.Text = "删除"; // 按钮上显示的文本 deleteButtonColumn.UseColumnTextForButtonValue = true; // 所有按钮都使用 Text 属性的值 dataGridView1.Columns.Add(deleteButtonColumn);
然后处理 CellClick 事件:
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
// 检查是否点击了“删除”按钮列
if (e.RowIndex >= 0 && dataGridView1.Columns[e.ColumnIndex] is DataGridViewButtonColumn)
{
// 获取要删除的行
DataGridViewRow rowToDelete = dataGridView1.Rows[e.RowIndex];
// 显示确认对话框
DialogResult result = MessageBox.Show("确定要删除这条记录吗?", "确认删除", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
// 从数据源中移除
if (dataGridView1.DataSource is BindingList<Product> productList)
{
// 找到并移除对应的对象
Product productToDelete = productList[rowToDelete.Index];
productList.Remove(productToDelete);
}
// 如果是DataTable, 使用 rowToDelete.DataGridView.Rows.Remove(rowToDelete);
}
}
}
添加复选框列
用于实现“全选/反选”功能。
// 添加一个 DataGridViewCheckBoxColumn DataGridViewCheckBoxColumn selectColumn = new DataGridViewCheckBoxColumn(); selectColumn.Name = "Selected"; selectColumn.HeaderText = "选择"; selectColumn.TrueValue = true; selectColumn.FalseValue = false; selectColumn.IndeterminateValue = null; dataGridView1.Columns.Insert(0, selectColumn); // 插入到第一列
实现全选功能
在窗体上添加一个 CheckBox 控件,命名为 chkSelectAll。
private void chkSelectAll_CheckedChanged(object sender, EventArgs e)
{
bool isChecked = chkSelectAll.Checked;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
// 注意:跳过新行(如果允许用户添加)
if (!row.IsNewRow)
{
row.Cells["Selected"].Value = isChecked;
}
}
}
获取选中的行
private void btnGetSelected_Click(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count > 0)
{
string selectedInfo = "选中的产品:\n";
foreach (DataGridViewRow row in dataGridView1.SelectedRows)
{
// 跳过用户正在编辑的新行
if (!row.IsNewRow)
{
Product p = row.DataBoundItem as Product;
if (p != null)
{
selectedInfo += $"- {p.ProductName}\n";
}
}
}
MessageBox.Show(selectedInfo);
}
else
{
MessageBox.Show("没有选中任何行。");
}
}
第五部分:性能优化
当处理大量数据(例如成千上万行)时,DataGridView 的性能可能会下降。
-
使用虚拟模式 (
VirtualMode) 这是最有效的优化方法,启用虚拟模式后,DataGridView不会在内存中保存所有数据,而是只在需要时(如滚动、绘制)向你的代码请求数据。- 设置
dataGridView1.VirtualMode = true; - 处理
CellValueNeeded事件,当DataGridView需要某个单元格的值时,它会向你索要。 - 处理
CellValuePushed事件,当用户编辑单元格并确认后,DataGridView会将新值推送给你的代码,以便你更新数据源。
- 设置
-
延迟加载 如果数据来自数据库,不要一次性加载所有数据,可以实现分页或滚动加载。
-
避免在循环中频繁操作 UI 不要在一个循环中逐行添加数据到
DataGridView,最好是先准备好整个数据集(如DataTable或List<T>),然后一次性绑定。
DataGridView 是一个功能极其强大的控件,掌握它的核心用法是每个 Windows Forms 开发者的必备技能。
- 入门:从
DataSource属性开始,学会绑定DataTable和BindingList<T>。 - 进阶:通过属性和事件自定义外观和行为,处理用户交互。
- 精通:掌握按钮列、复选框列等高级用法,并了解性能优化技巧。
希望这份详细的教程能帮助你熟练使用 DataGridView!
