线程内,动态刷新DataGridView

本文介绍了一种使用计时器在Windows Forms应用中定时刷新DataGridView控件的方法。通过创建两个计时器,一个用于获取数据,另一个用于每半次数据获取周期刷新DataGridView,解决了控件跨线程更新的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

业务:计时刷新DataGridView

Task.Factory.StartNew(() =>
                {
                    System.Timers.Timer timer = new System.Timers.Timer();
                    timer.Enabled = true;
                    timer.Interval = config.dowDataRate;                    // 执行间隔时间 
                    timer.Start();
                    timer.Elapsed += new System.Timers.ElapsedEventHandler(MachingDownInfo.DownMachingFile);
                });

开了一个线程,来获取DataGridView的数据。我的思路本来是直接在这个计时方法中绑定当前窗体的DataGridView控件的值。
这种方法并不可行,虽然没报错。但是值还是绑定不上。
此问题的原因,自己总结了一下:DataGridView控件不能在类中绑定数据。

最后反复测试,找到了解决方案。

Task.Factory.StartNew(() =>
                {
                    System.Timers.Timer timer = new System.Timers.Timer();
                    timer.Enabled = true;
                    timer.Interval = config.dowDataRate;                    // 执行间隔时间 
                    timer.Start();
                    timer.Elapsed += new System.Timers.ElapsedEventHandler(MachingDownInfo.DownMachingFile);

                    // 动态刷新列表数据
                    System.Timers.Timer timer1 = new System.Timers.Timer();
                    timer1.Enabled = true;
                    timer1.Interval = (config.dowDataRate / 2);             // 执行间隔时间 
                    timer1.Start();
                    timer1.Elapsed += new System.Timers.ElapsedEventHandler(BindGridListTimer);
                });

声明了两个计时器,第二个是刷新列表的。绑定列表的时间间隔设置的为取列表数据时间间隔的一半。

private void BindGridListTimer(object source, ElapsedEventArgs e)
        {
            try
            {
                SetGridData();
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }

        // 声明委托
        private delegate void SetGridDelegate();
        /// <summary>
        /// 委托将参数与方法传递给控件所在的线程,并由控件所在的线程执行
        /// </summary>
        public void SetGridData()
        {
            if (this.InvokeRequired)
                this.Invoke(new SetGridDelegate(SetGridData));
            else
                BindGrid();
        }

        static DataTable dtCsvGrid = new DataTable();
        /// <summary>
        /// CSV列表,在执行**MachingDownInfo.DownMachingFile**方法时会给此变量赋值。![在这里插入图片描述]
        /// </summary>
        public DataTable _dtCsvGrid
        {
            get { return dtCsvGrid; }
            set { dtCsvGrid = value; }
        }

        /// <summary>
        /// 绑定设备保养信息grid列表数据
        /// </summary>
        /// <returns></returns>
        public void BindGrid()
        {
            dataGridView1.DataSource = dtCsvGrid;
        }


以上经过测试,可行! 虽然有点笨拙。但是我看到列表刷新的那一刻,超级激动啊!!!!

<think>好的,用户的问题是关于在WinForms中如何实现DataGridView动态刷新。他们提到了数据绑定和实时更新,可能需要具体的步骤和方法。首先,我需要回忆一下相关的WinForms知识,尤其是数据绑定和刷新机制。 根据用户提供的引用,特别是引用[4]提到的BindingList,这应该是一个关键点。因为普通的List不支持通知,所以当数据变化时,DataGridView不会自动刷新。而BindingList实现了IBindingList接口,支持数据变更通知,这样在添加或修改数据时,DataGridView会自动更新。 接下来要考虑的是数据绑定的正确步骤。用户可能已经尝试过直接绑定List,但发现无法刷新。因此,需要指导他们使用BindingList作为数据源,并正确设置DataGridView的DataSource属性。 然后,关于实时更新,可能涉及到后台线程的问题。WinForms的控件不是线程安全的,所以当在后台线程中更新数据时,必须通过Invoke方法来同步到UI线程。这一点在引用[3]中提到过,可能需要结合例子说明如何使用定时器和跨线程更新。 用户还可能遇到添加数据后界面不刷新的问题,如引用[1]和[2]所述。这时候可能需要手动刷新,比如调用Refresh方法或者重新绑定数据源。不过使用BindingList通常可以避免这种情况,但有时候可能需要ResetBindings方法。 另外,引用[4]中的模型类示例也是重要的,用户需要正确创建数据模型,并绑定到DataGridView的列上。可能需要检查DataGridView的AutoGenerateColumns属性是否设置正确,或者手动配置列以确保数据显示正常。 最后,用户可能需要具体的代码示例来演示整个过程,包括创建BindingList、绑定数据源、处理后台线程更新等。需要确保代码示例正确,并且涵盖常见的用例,如添加数据、修改数据和定时刷新。 总结步骤应该是:1. 使用BindingList作为数据源;2. 处理跨线程更新;3. 必要时调用刷新方法。同时,提醒用户常见问题,如线程安全和通知机制的正确实现。</think>在WinForms中实现DataGridView动态刷新数据,主要依赖数据绑定机制和集合类型的正确选择。以下是具体实现方法: ### 一、核心实现步骤 1. **使用支持通知的集合类型** 采用$BindingList<T>$替代$List<T>$作为数据源容器,其实现了$IBindingList$接口支持数据变更通知: ```csharp private BindingList<MyData> _dataSource = new BindingList<MyData>(); dataGridView1.DataSource = _dataSource; // 绑定到控件 ``` 2. **实现跨线程更新(适用于异步场景)** 当后台线程修改数据时,必须通过UI线程同步: ```csharp void UpdateData(MyData newItem) { if (dataGridView1.InvokeRequired) { dataGridView1.BeginInvoke(new Action(() => _dataSource.Add(newItem))); } else { _dataSource.Add(newItem); } } ``` 3. **实时刷新控制** - 添加数据自动刷新:$BindingList.Add()$会触发界面更新[^4] - 修改数据需实现$INotifyPropertyChanged$接口: ```csharp public class MyData : INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; private string _name; public string Name { get => _name; set { _name = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name))); } } } ``` ### 二、特殊场景处理 当遇到滚动条异常或界面未更新时,可强制刷新: ```csharp _dataSource.ResetBindings(); // 重置绑定关系[^1] // 或 dataGridView1.Refresh(); ``` ### 三、定时刷新示例(每2秒) ```csharp Timer timer = new Timer(); timer.Interval = 2000; timer.Tick += (s,e) => { var newData = GetUpdateData(); _dataSource.Add(newData); }; timer.Start(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值