在 C# 中实现 DataGridView 数据的自动刷新,通常需要结合数据绑定和通知机制。
方法 1:使用 BindingList + INotifyPropertyChanged(推荐)
public class Product : INotifyPropertyChanged
{private string _name;private decimal _price;public string Name{get => _name;set{_name = value;OnPropertyChanged();}}public decimal Price{get => _price;set{_price = value;OnPropertyChanged();}}public event PropertyChangedEventHandler? PropertyChanged;protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}
}// 窗体代码
public partial class MainForm : Form
{private readonly BindingList<Product> _products = new();private readonly Random _random = new();public MainForm(){InitializeComponent();dataGridView1.DataSource = _products;// 设置自动刷新dataGridView1.AutoGenerateColumns = true;}private void btnAdd_Click(object sender, EventArgs e){// 添加新数据(自动刷新)_products.Add(new Product{Name = $"Product {_products.Count + 1}",Price = (decimal)(_random.NextDouble() * 100)});}private void btnUpdate_Click(object sender, EventArgs e){// 修改现有数据(自动刷新)if (_products.Count > 0){_products[0].Price *= 1.1m; // 价格增加10%}}private void timerRefresh_Tick(object sender, EventArgs e){// 定时更新所有商品价格foreach (var product in _products){product.Price *= (decimal)(0.95 + _random.NextDouble() * 0.1);}}
}
方法 2:使用 DataTable(适合数据库操作)
public partial class MainForm : Form
{private readonly DataTable _dataTable = new("Products");private readonly Timer _refreshTimer = new();public MainForm(){InitializeComponent();// 创建表结构_dataTable.Columns.Add("ID", typeof(int));_dataTable.Columns.Add("Name", typeof(string));_dataTable.Columns.Add("Price", typeof(decimal));dataGridView1.DataSource = _dataTable;// 设置定时刷新_refreshTimer.Interval = 2000; // 2秒_refreshTimer.Tick += RefreshData;_refreshTimer.Start();}private void RefreshData(object? sender, EventArgs e){// 模拟数据库更新if (_dataTable.Rows.Count > 0){// 随机更新价格var random = new Random();foreach (DataRow row in _dataTable.Rows){row["Price"] = (decimal)random.Next(10, 1000);}}}private void btnAdd_Click(object sender, EventArgs e){// 添加新数据_dataTable.Rows.Add(_dataTable.Rows.Count + 1,$"Product {_dataTable.Rows.Count + 1}",new Random().Next(10, 1000));}
}
方法 3:手动刷新(简单场景)
// 适用于小数据量或非绑定场景
private void RefreshGridView()
{dataGridView1.DataSource = null;dataGridView1.DataSource = yourDataSource; // 重新绑定更新后的数据源
}// 或者使用 BindingSource
private readonly BindingSource _bindingSource = new();public MainForm()
{InitializeComponent();_bindingSource.DataSource = yourDataSource;dataGridView1.DataSource = _bindingSource;
}private void UpdateData()
{// 更新数据后..._bindingSource.ResetBindings(false); // 刷新显示
}
关键点说明:
-
自动刷新原理:
BindingList<T>+INotifyPropertyChanged:双向通知机制DataTable:内置变更通知支持BindingSource.ResetBindings():手动强制刷新
-
性能优化:
-
大数据量时使用虚拟模式(
VirtualMode=true) -
批量更新时暂停绘制:
dataGridView1.SuspendLayout(); // 批量操作... dataGridView1.ResumeLayout();
-
-
线程安全:
if (dataGridView1.InvokeRequired) {dataGridView1.Invoke(() => { /* 更新UI操作 */ }); } else {// 直接更新 } -
数据库实时刷新:
// 使用SQL依赖(SQL Server) SqlDependency.Start(connectionString); var cmd = new SqlCommand("SELECT * FROM Products", conn); var dependency = new SqlDependency(cmd); dependency.OnChange += (s, e) => RefreshFromDatabase();
选择方案的建议:
- 对象集合场景 → 方法1(BindingList + INPC)
- 数据库表格场景 → 方法2(DataTable)
- 简单临时方案 → 方法3(手动刷新)
参考源码 C# datagridview 数据自动刷新 www.youwenfan.com/contentcne/92889.html
注意事项:
确保数据对象实现
INotifyPropertyChanged多线程操作必须通过
Control.Invoke大数据量更新时使用双缓冲防止闪烁:
dataGridView1.DoubleBuffered(true);定时器刷新间隔不宜过短(建议 >500ms)
