如何让ListView刷新后保持原状态(WinForms)

effun 2013-07-04 09:29:26
环境说明:
WinForms的窗体上有一个ListView,View为Details,它使用ListViewGroup对行进行分组。为方便用户查看,行的背景色交替设置,也就是说奇数行和偶数行采用不同的背景色。

业务说明:
后台有一个程序会不定时地刷新ListView的数据,刷新后行可能会增加,也可能会减少。数据源中的每一条记录都有一个唯一值。

要求:
刷新后ListView的状态尽可能保持与刷新前相同,也就是说让用户只觉得界面闪了一下,但没有发生太大的变化 。主要涉及到以下几个方面:
1、保持原横向和纵向滚动条位置
2、保持原来已经选择的项
3、行的背景色可以变化,但仍旧保持交替色。

虽然我自己已经解决,但对解决方案并不满意,期待达人给出更好的解决方案。
...全文
258 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
effun 2013-07-04
  • 打赏
  • 举报
回复
引用 9 楼 dongxinxi 的回复:
记得以前用datagridview做过一个类似的 大致是记下当前的排序规则(比如按ID)及selectedRowIndex 刷新时,“绑定数据”之前将选择行按照规则排列到记下的的Index处
ListViewItem.EnsureVisible可以让ListView滚动到这行,但仅仅只是让它可见,并不保证滚动量的多少,对于用户来说,ListView可能会发生较大的移动,会有瞬间错乱的感觉。
effun 2013-07-04
  • 打赏
  • 举报
回复
引用 8 楼 anodaniu 的回复:
AutoScrollOffset
这个属性在ListView里没有用的。
effun 2013-07-04
  • 打赏
  • 举报
回复
引用 7 楼 wyd1520 的回复:
错位?不会的吧,无非就是 隔行变色,也就是你在插入前 Items.Count%2==0 就能判断出你要插入的行用哪个颜色的拉。
因为启用了分组,行的排序并不会按添加到Items里的顺序排列,ListViewItem.Index属性只表示它处于Items集合中的顺序,并不表示显示时的顺序号。
  • 打赏
  • 举报
回复
记得以前用datagridview做过一个类似的 大致是记下当前的排序规则(比如按ID)及selectedRowIndex 刷新时,“绑定数据”之前将选择行按照规则排列到记下的的Index处
Anod 2013-07-04
  • 打赏
  • 举报
回复
AutoScrollOffset
本拉灯 2013-07-04
  • 打赏
  • 举报
回复
引用 3 楼 effun 的回复:
[quote=引用 1 楼 wyd1520 的回复:] 要保持原态,那就不能用数据源绑定方式。只能用 有新记录就Items.Add新记录,有记录更新 就Items[xxx].Text=xxx Items[xxx].SubItem[xxx].Text=xxx这样方式就可以做到你上面说的先择项也可以的。滚动条也不会动
你的方法不错,但遇到源数据有增减的时候,背景色就会错位。[/quote] 错位?不会的吧,无非就是 隔行变色,也就是你在插入前 Items.Count%2==0 就能判断出你要插入的行用哪个颜色的拉。
Regan-lin 2013-07-04
  • 打赏
  • 举报
回复
引用 3 楼 effun 的回复:
[quote=引用 1 楼 wyd1520 的回复:] 要保持原态,那就不能用数据源绑定方式。只能用 有新记录就Items.Add新记录,有记录更新 就Items[xxx].Text=xxx Items[xxx].SubItem[xxx].Text=xxx这样方式就可以做到你上面说的先择项也可以的。滚动条也不会动
你的方法不错,但遇到源数据有增减的时候,背景色就会错位。[/quote] 不绑定会错位的,真心纠结!
橘色的喵 2013-07-04
  • 打赏
  • 举报
回复
我感觉我的也不太好,顶一下,看看有没有好的方法
effun 2013-07-04
  • 打赏
  • 举报
回复
引用 2 楼 xiaozhi_5638 的回复:
我之前用datagridview实现过该类似的功能 每次记录原来滚动条的位置和选择行 我使用的绑定datasource 所以只是更行datasource中的数据
DataGridView不在考虑的范围内。
effun 2013-07-04
  • 打赏
  • 举报
回复
引用 1 楼 wyd1520 的回复:
要保持原态,那就不能用数据源绑定方式。只能用 有新记录就Items.Add新记录,有记录更新 就Items[xxx].Text=xxx Items[xxx].SubItem[xxx].Text=xxx这样方式就可以做到你上面说的先择项也可以的。滚动条也不会动
你的方法不错,但遇到源数据有增减的时候,背景色就会错位。
请叫我卷福 2013-07-04
  • 打赏
  • 举报
回复
我之前用datagridview实现过该类似的功能 每次记录原来滚动条的位置和选择行 我使用的绑定datasource 所以只是更行datasource中的数据
本拉灯 2013-07-04
  • 打赏
  • 举报
回复
引用 楼主 effun 的回复:
环境说明: WinForms的窗体上有一个ListView,View为Details,它使用ListViewGroup对行进行分组。为方便用户查看,行的背景色交替设置,也就是说奇数行和偶数行采用不同的背景色。 业务说明: 后台有一个程序会不定时地刷新ListView的数据,刷新后行可能会增加,也可能会减少。数据源中的每一条记录都有一个唯一值。 要求: 刷新后ListView的状态尽可能保持与刷新前相同,也就是说让用户只觉得界面闪了一下,但没有发生太大的变化 。主要涉及到以下几个方面: 1、保持原横向和纵向滚动条位置 2、保持原来已经选择的项 3、行的背景色可以变化,但仍旧保持交替色。 虽然我自己已经解决,但对解决方案并不满意,期待达人给出更好的解决方案。
要保持原态,那就不能用数据源绑定方式。只能用 有新记录就Items.Add新记录,有记录更新 就Items[xxx].Text=xxx Items[xxx].SubItem[xxx].Text=xxx这样方式就可以做到你上面说的先择项也可以的。滚动条也不会动
effun 2013-07-04
  • 打赏
  • 举报
回复
给出两个解决方案的思路供大家参考: 1、清除原先的所有行 先将当前滚动位置和选择项记下,再清除所有行,按新的数据重新生成行,最后恢复滚动位置和选择项。 选择项的处理不复杂就不说了,主要是滚动位置。托管的ListView没有提供这样的方法,只能直接调用API来实现。 LVM_GETORIGIN - 获得ListView的滚动位置 LVM_SCROLL - 滚动ListView 这个方案看起来不错,但却发生了一个很奇怪的问题。LVM_GETORIGIN在Windows XP里居然不成功(SendMessage返回FALSE),但在Win7里是没有问题的。 2、不要清除原先的行 将新的数据直接覆盖到现有的ListViewItem上,不够添加,多了删除。问题是,由于启用了分组,ListViewItem.Index属性获得的值并不是实际显示的顺序号,就会导致行的背景色错位。 (请版主将这条回复的内容合并到主帖当中,谢谢) PS:终于等到有人回复,破除了连续3个帖的魔咒。
qazxsw_111222 2013-07-04
  • 打赏
  • 举报
回复
绑定,我也关注这个

110,565

社区成员

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

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

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