C# 如何防止列表框跳转到&#x;tem?

C# 如何防止列表框跳转到&#x;tem?,c#,.net,vb.net,winforms,listbox,C#,.net,Vb.net,Winforms,Listbox,假设在WinForms中,我有一个启用了multiselect的Listbox,Listbox包含50项,并且只选择了Listbox的第一项 …然后,如果我选择(使用SetSelected方法)最后一个项目,则列表框将跳转到底部(连同垂直滚动)以显示该项目 我只希望列表框保持原来的位置,当我使用SetSelected选择其他项目时,我不希望列表框每次都上下移动 那么我怎样才能防止Listbox和Listbox v。当我使用SetSelected方法时,是否使用滚动条跳转到ítem?(向上或向下两

假设在WinForms中,我有一个启用了multiselect的Listbox,Listbox包含50项,并且只选择了Listbox的第一项

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

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

那么我怎样才能防止Listbox和Listbox v。当我使用
SetSelected
方法时,是否使用滚动条跳转到ítem?(向上或向下两个方向)


我希望我可以使用WinAPI的函数来实现这一点。

您可以尝试使用
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,并使用
BeginUpdate
EndUpdate
来避免闪烁:

 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);
公共静态类ListBoxExtension{
公共静态void SetMultiSelectedWithoutJumping(此列表框lb,IEnumerable index,bool selected){
int i=磅指数;
lb.开始更新();
foreach(指数中的var指数)
lb.SetSelected(索引,selected);
lb.TopIndex=i;
lb.EndUpdate();
}
}   
//用法
SetMultiSelectedWithoutJumping(新列表{2,3,4},true);

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

我只想分享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

我正在暂停/恢复布局,也在使用beginupdate/endupdate,但闪烁对我来说不是问题,谢谢你的回答,我不知道Topindex属性,至少现在listbox返回到以前的位置,但仍然在移动(当listbox包含很多项时,我会更加感激)所以现在Listbox正在跳转,但跳转后它会返回到以前的位置,我希望如果存在一种方法来禁用此移动,而不是尝试做一些棘手的事情(跳转到那里并返回到这里),真的谢谢!@ElektroStudios这不是棘手的,应该这样做。本机
LB_setel
总是有这样的行为(跳转到所选项目),当您调用
SetSelected
时,实际上会发送
LB_setel
消息。因此,您没有任何问题。所谓的
直路
BeginUpdate
EndUpdate
就是为了解决此问题而设计的。在不需要时抑制每个图形,只需调用
EndUpdate
即可接受current
UI状态
。现在问题解决了是的,您的扩展可以与beginupdate/endupdate完美配合,它不会产生任何恶心的视觉效果(我的意思是跳跃),回答得很好!