环境说明:
WinForms的窗体上有一个ListView,View为Details,它使用ListViewGroup对行进行分组。为方便用户查看,行的背景色交替设置,也就是说奇数行和偶数行采用不同的背景色。业务说明:
后台有一个程序会不定时地刷新ListView的数据,刷新后行可能会增加,也可能会减少。数据源中的每一条记录都有一个唯一值。要求:
刷新后ListView的状态尽可能保持与刷新前相同,也就是说让用户只觉得界面闪了一下,但没有发生太大的变化 。主要涉及到以下几个方面:
1、保持原横向和纵向滚动条位置
2、保持原来已经选择的项
3、行的背景色可以变化,但仍旧保持交替色。虽然我自己已经解决,但对解决方案并不满意,期待达人给出更好的解决方案。listviewwinforms

解决方案 »

  1.   


    要保持原态,那就不能用数据源绑定方式。只能用 有新记录就Items.Add新记录,有记录更新
    就Items[xxx].Text=xxx Items[xxx].SubItem[xxx].Text=xxx这样方式就可以做到你上面说的先择项也可以的。滚动条也不会动
      

  2.   

    我之前用datagridview实现过该类似的功能每次记录原来滚动条的位置和选择行
    我使用的绑定datasource  所以只是更行datasource中的数据
      

  3.   


    DataGridView不在考虑的范围内。
      

  4.   


    你的方法不错,但遇到源数据有增减的时候,背景色就会错位。错位?不会的吧,无非就是 隔行变色,也就是你在插入前 Items.Count%2==0 就能判断出你要插入的行用哪个颜色的拉。 
      

  5.   

    记得以前用datagridview做过一个类似的
    大致是记下当前的排序规则(比如按ID)及selectedRowIndex
    刷新时,“绑定数据”之前将选择行按照规则排列到记下的的Index处
      

  6.   


    因为启用了分组,行的排序并不会按添加到Items里的顺序排列,ListViewItem.Index属性只表示它处于Items集合中的顺序,并不表示显示时的顺序号。
      

  7.   


    这个属性在ListView里没有用的。
      

  8.   


    ListViewItem.EnsureVisible可以让ListView滚动到这行,但仅仅只是让它可见,并不保证滚动量的多少,对于用户来说,ListView可能会发生较大的移动,会有瞬间错乱的感觉。
      

  9.   

    给出两个解决方案的思路供大家参考:1、清除原先的所有行
    先将当前滚动位置和选择项记下,再清除所有行,按新的数据重新生成行,最后恢复滚动位置和选择项。
    选择项的处理不复杂就不说了,主要是滚动位置。托管的ListView没有提供这样的方法,只能直接调用API来实现。
    LVM_GETORIGIN - 获得ListView的滚动位置
    LVM_SCROLL - 滚动ListView
    这个方案看起来不错,但却发生了一个很奇怪的问题。LVM_GETORIGIN在Windows XP里居然不成功(SendMessage返回FALSE),但在Win7里是没有问题的。2、不要清除原先的行
    将新的数据直接覆盖到现有的ListViewItem上,不够添加,多了删除。问题是,由于启用了分组,ListViewItem.Index属性获得的值并不是实际显示的顺序号,就会导致行的背景色错位。(请版主将这条回复的内容合并到主帖当中,谢谢)PS:终于等到有人回复,破除了连续3个帖的魔咒。