C# 中实现 DataGridView 数据的自动刷新

在 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); // 刷新显示
}

关键点说明:

  1. 自动刷新原理

    • BindingList<T> + INotifyPropertyChanged:双向通知机制
    • DataTable:内置变更通知支持
    • BindingSource.ResetBindings():手动强制刷新
  2. 性能优化

    • 大数据量时使用虚拟模式(VirtualMode=true

    • 批量更新时暂停绘制:

      dataGridView1.SuspendLayout();
      // 批量操作...
      dataGridView1.ResumeLayout();
      
  3. 线程安全

    if (dataGridView1.InvokeRequired)
    {
        dataGridView1.Invoke(() => { /* 更新UI操作 */ });
    }
    else
    {
        // 直接更新
    }
    
  4. 数据库实时刷新

    // 使用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

注意事项

  1. 确保数据对象实现 INotifyPropertyChanged

  2. 多线程操作必须通过 Control.Invoke

  3. 大数据量更新时使用双缓冲防止闪烁:

    dataGridView1.DoubleBuffered(true);
    
  4. 定时器刷新间隔不宜过短(建议 >500ms)

posted @ 2025-08-25 11:45  yijg9998  阅读(256)  评论(0)    收藏  举报