【问题标题】:How to prevent Listbox jumps to ítem?如何防止 Listbox 跳转到项目?
【发布时间】:2013-10-20 16:23:08
【问题描述】:

假设在 WinForms 中我有一个启用多选的列表框,列表框包含 50 个项目,并且仅选择了列表框的第一项...

...然后,如果我选择(使用SetSelected 方法)最后一项,那么列表框将跳到底部(连同垂直滚动)以显示该项目。

我只希望列表框保持在原来的位置,而我使用SetSelected 选择其他项目,我不希望列表框每次都上下移动。

那么当我使用SetSelected 方法时,如何防止列表框和列表框v.滚动条跳转到项目? (上下两个方向)

我希望也许我可以使用 WinAPI 的功能来做到这一点。

【问题讨论】:

    标签: c# .net vb.net winforms listbox


    【解决方案1】:

    您可以尝试使用TopIndex 设置顶部可见索引,如下所示:

    //Use this ListBox extension for convenience
    public static class ListBoxExtension {
       public static void SetSelectedWithoutJumping(this ListBox lb, int index, bool selected){
         int i = lb.TopIndex;
         lb.SetSelected(index, selected);
         lb.TopIndex = i;
       }
    }
    //Then just use like this
    yourListBox.SetSelectedWithoutJumping(index, true);
    

    您还可以尝试定义一些方法来为索引集合设置 selected 并使用 BeginUpdateEndUpdate 来避免闪烁:

     public static class ListBoxExtension {
       public static void SetMultiSelectedWithoutJumping(this ListBox lb, IEnumerable<int> indices, bool selected){
         int i = lb.TopIndex;
         lb.BeginUpdate();
         foreach(var index in indices)
            lb.SetSelected(index, selected);
         lb.TopIndex = i;
         lb.EndUpdate();
       }
    }   
    //usage
    yourListBox.SetMultiSelectedWithoutJumping(new List<int>{2,3,4}, true);
    

    注意:您也可以在SetSelectedWithoutJumping 中使用BeginUpdateEndUpdate,但是正如我所说,如果您必须同时选择多个索引,请实现一些扩展方法,例如SetMultiSelectedWithoutJumping 更好更方便(我们只使用一对BeginUpdateEndUpdate)。

    【讨论】:

    • 我正在暂停/恢复布局并使用 beginupdate/endupdate 但闪烁对我来说不是问题,感谢您的回答我不知道 Topindex 属性,至少现在列表框正在返回到之前的位置,但仍然在移动(当列表框包含很多项目时,它可以得到更多的欣赏)所以现在列表框正在跳跃,但在跳跃后它返回到之前的位置,我希望如果存在一种方法来禁用这个运动而不是尝试做棘手的事情(跳到这里然后返回),真的谢谢!
    • @ElektroStudios 这并不棘手,应该这样做。原生LB_SETSEL 总是有这样的行为(跳转到选定的项目),当你调用SetSelected 时,实际上发送了LB_SETSEL 消息。所以你没有所谓的Straight-wayBeginUpdateEndUpdate 就是为解决此类问题而设计的。当您不需要时禁止每张绘图,只需调用EndUpdate 以接受当前的UI state
    • 现在解决了,是的,您的扩展程序可以与 beginupdate/endupdate 一起完美完成工作,它不会产生任何令人作呕的视觉效果(我的意思是跳跃),很好的答案!
    【解决方案2】:

    我只想分享VB.NET版本:

    #Region " [ListBox] Select item without jump "
    
        ' [ListBox] Select item without jump
        '
        ' Original author of code is "King King"
        ' Url: stackoverflow.com/questions/19479774/how-to-prevent-listbox-jumps-to-item
        '
        ' // By Elektro H@cker
        '
        ' Examples :
        '
        ' Select_Item_Without_Jumping(ListBox1, 50, ListBoxItemSelected.Select)
        '
        ' For x As Integer = 0 To ListBox1.Items.Count - 1
        '    Select_Item_Without_Jumping(ListBox1, x, ListBoxItemSelected.Select)
        ' Next
    
        Public Enum ListBoxItemSelected
            [Select] = 1
            [Unselect] = 0
        End Enum
    
        Public Shared Sub Select_Item_Without_Jumping(lb As ListBox, index As Integer, selected As ListBoxItemSelected)
            Dim i As Integer = lb.TopIndex ' Store the selected item index
            lb.BeginUpdate() ' Disable drawing on control
            lb.SetSelected(index, selected) ' Select the item
            lb.TopIndex = i ' Jump to the previous selected item
            lb.EndUpdate() ' Eenable drawing
        End Sub
    
    #End Region
    

    【讨论】:

      猜你喜欢
      • 2013-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-06
      相关资源
      最近更新 更多