Winform DataGridView实时刷新数据问题

雪狼孤竹 2016-10-11 07:29:58
问题描述:

目前,Winform中的DataGridView中的数据需要实时刷新,刷新方式为重新加载数据源。
但存在的问题是,如果数据行数,列数都超出屏幕,当用户在浏览屏幕外数据的时候(在浏览n行n列的数据),刷新数据,会导致回到0行0列,如果刷新的频率过快,n行的数据很难操作,n列的数据很难看到。

不知道有什么好的方法,能够在刷新之后,还是保持在用户操作的区域,给用户的感官是除了数据的变更之外,没有其它变化。

望大牛能给点意见,或简单实现方式。

在此,先谢谢了!!

...全文
11551 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
crookshanks_ 2018-04-24
  • 打赏
  • 举报
回复
你把数据源重新赋值一遍: 数据源 = new List; 然后再使用 DataGridView.DataSource = 数据源; 就可以啦~
雪狼孤竹 2016-10-13
  • 打赏
  • 举报
回复
引用 11 楼 stherix 的回复:
如果是新增和删除,可能就要通过Invalidate()重画整个DataGridView的客户区 因为判断删除和插入的位置是比较麻烦的 尤其是还有排序的情况下, 这个最大的问题是如果频率很高 可能会造成界面闪烁
非常感谢你的帮助!!
stherix 2016-10-12
  • 打赏
  • 举报
回复
引用 5 楼 Snowwolf_119 的回复:
[quote=引用 1 楼 stherix 的回复:] 重新加载数据源 这种方式不好 效率太低 你更改数据源后 通过DataGridView.InvalidateRow刷新你更新的行不就好了
您提出的方式,我试了,不知道是我的实现方式问题,还是什么原因。未能实现刷新。 我的DataGridView中有自定义列(DataGridViewCheckBoxColumn)。 我的实现方式: 1、定义一个窗体的局部变量DataSet ds 2、在窗体加载的时候,将ds取值,并将DataGridView的数据源定位ds.Tables[0] 3、在刷新方法中,从数据库总获取新的ds,并循环DataGridView的行,执行DataGridView.InvalidateRow方法。 结果: DataGridView无反应,不刷新。 不知道是不是我实现的不对,还是哪的问题?[/quote] 因为你刷新取出来的ds.Table[0] 已经不是加载设的那个DataSource了 对象不是同一个 建议不要直接用Table当数据源 而是自己封装一个类当数据源 刷新的时候比较新老数据 ,只有不同的地方才Invalidate 减少界面重画操作
雪狼孤竹 2016-10-12
  • 打赏
  • 举报
回复
引用 3 楼 FoxDave 的回复:
分页,把获取的数据做小些
我只想刷新数据,对用户无影响。 这个和分页关系不大,好像。
雪狼孤竹 2016-10-12
  • 打赏
  • 举报
回复
引用 1 楼 stherix 的回复:
重新加载数据源 这种方式不好 效率太低 你更改数据源后 通过DataGridView.InvalidateRow刷新你更新的行不就好了
您提出的方式,我试了,不知道是我的实现方式问题,还是什么原因。未能实现刷新。 我的DataGridView中有自定义列(DataGridViewCheckBoxColumn)。 我的实现方式: 1、定义一个窗体的局部变量DataSet ds 2、在窗体加载的时候,将ds取值,并将DataGridView的数据源定位ds.Tables[0] 3、在刷新方法中,从数据库总获取新的ds,并循环DataGridView的行,执行DataGridView.InvalidateRow方法。 结果: DataGridView无反应,不刷新。 不知道是不是我实现的不对,还是哪的问题?
圣殿骑士18 2016-10-12
  • 打赏
  • 举报
回复
用BingList作数据源
Justin-Liu 2016-10-12
  • 打赏
  • 举报
回复
分页,把获取的数据做小些
stherix 2016-10-12
  • 打赏
  • 举报
回复
引用 10 楼 Snowwolf_119 的回复:
[quote=引用 9 楼 stherix 的回复:] conlistold = conlistnew; //更新数据???? 是不需要写的 其他地方看上去也没什么错误啊 你调试看看conlistold的数据是否正确更新了 conlistold[m] = conlistnew[m];是不是执行了并且数据改变了
嗯,int ic = Convert.ToInt32(dataGridView1.Rows[i].Cells["con_id"]);少了点东西,所以异常了,我捕捉异常那块没写东西,就没看到。 我上面写的这段,是更新数据与显示数据 条目相等的,我可以处理了。谢谢! 另外对于新增和删除,应该是怎么个处理方式? 删除,将DataGridView中对应的行删除,数据源中同样删除。 新增,DataGridView的处理是怎么个方式? [/quote] 如果是新增和删除,可能就要通过Invalidate()重画整个DataGridView的客户区 因为判断删除和插入的位置是比较麻烦的 尤其是还有排序的情况下, 这个最大的问题是如果频率很高 可能会造成界面闪烁
雪狼孤竹 2016-10-12
  • 打赏
  • 举报
回复
引用 9 楼 stherix 的回复:
conlistold = conlistnew; //更新数据???? 是不需要写的 其他地方看上去也没什么错误啊 你调试看看conlistold的数据是否正确更新了 conlistold[m] = conlistnew[m];是不是执行了并且数据改变了
嗯,int ic = Convert.ToInt32(dataGridView1.Rows[i].Cells["con_id"]);少了点东西,所以异常了,我捕捉异常那块没写东西,就没看到。 我上面写的这段,是更新数据与显示数据 条目相等的,我可以处理了。谢谢! 另外对于新增和删除,应该是怎么个处理方式? 删除,将DataGridView中对应的行删除,数据源中同样删除。 新增,DataGridView的处理是怎么个方式?
stherix 2016-10-12
  • 打赏
  • 举报
回复
引用 8 楼 Snowwolf_119 的回复:
[quote=引用 7 楼 stherix 的回复:] 因为你刷新取出来的ds.Table[0] 已经不是加载设的那个DataSource了 对象不是同一个 建议不要直接用Table当数据源 而是自己封装一个类当数据源 刷新的时候比较新老数据 ,只有不同的地方才Invalidate 减少界面重画操作
整得有点迷糊了,感觉应该可以,但是就是不刷新。帮我看看更新部分代码吧。 其中conlistold和conlistnew为对象集合 DataGridView的数据源为conlistold
//*******************************************
            conlistnew = fub.GetConMEntity(); //获取新的数据            

            for (int m = 0; m < conlistold.Count; m++)
            {
               if (conlistold[m].Con_id == conlistnew[m].Con_id)  //主键相等
               {
                  if (conlistold[m].Lightstate != conlistnew[m].Lightstate)  //更新部分不等向下执行
                  {
                     for (int i = 0; i < dataGridView1.Rows.Count; i++)
                     {
                        int ic = Convert.ToInt32(dataGridView1.Rows[i].Cells["con_id"]);
                        if (conlistold[m].Con_id == ic)   //确认主键
                        {
                           conlistold[m] = conlistnew[m];  //数据更新 ????
                           dataGridView1.InvalidateRow(i); 
                        }
                     }
                  }
               }
            }
            conlistold = conlistnew; //更新数据????
            //********************************************
[/quote] conlistold = conlistnew; //更新数据???? 是不需要写的 其他地方看上去也没什么错误啊 你调试看看conlistold的数据是否正确更新了 conlistold[m] = conlistnew[m];是不是执行了并且数据改变了
雪狼孤竹 2016-10-12
  • 打赏
  • 举报
回复
引用 7 楼 stherix 的回复:
因为你刷新取出来的ds.Table[0] 已经不是加载设的那个DataSource了 对象不是同一个 建议不要直接用Table当数据源 而是自己封装一个类当数据源 刷新的时候比较新老数据 ,只有不同的地方才Invalidate 减少界面重画操作
整得有点迷糊了,感觉应该可以,但是就是不刷新。帮我看看更新部分代码吧。 其中conlistold和conlistnew为对象集合 DataGridView的数据源为conlistold
//*******************************************
            conlistnew = fub.GetConMEntity(); //获取新的数据            

            for (int m = 0; m < conlistold.Count; m++)
            {
               if (conlistold[m].Con_id == conlistnew[m].Con_id)  //主键相等
               {
                  if (conlistold[m].Lightstate != conlistnew[m].Lightstate)  //更新部分不等向下执行
                  {
                     for (int i = 0; i < dataGridView1.Rows.Count; i++)
                     {
                        int ic = Convert.ToInt32(dataGridView1.Rows[i].Cells["con_id"]);
                        if (conlistold[m].Con_id == ic)   //确认主键
                        {
                           conlistold[m] = conlistnew[m];  //数据更新 ????
                           dataGridView1.InvalidateRow(i); 
                        }
                     }
                  }
               }
            }
            conlistold = conlistnew; //更新数据????
            //********************************************
大鱼> 2016-10-11
  • 打赏
  • 举报
回复
如楼上所说,你这样做效率太低了。
stherix 2016-10-11
  • 打赏
  • 举报
回复
重新加载数据源 这种方式不好 效率太低 你更改数据源后 通过DataGridView.InvalidateRow刷新你更新的行不就好了

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧