在ListView控件上,我需要在选择更改后触发事件,但每个用户操作只需要触发一次。如果我只是使用SelectedIndexChanged,那么在大多数情况下该事件会触发两次(一次取消选择前一个元素时,选择新元素时再触发一次)如果用户仅点击一次控件,则为事件。
这两个事件一个接一个地快速触发,但是当选择更改时我所做的计算需要花费时间(几乎一秒),因此它会完成两次并减慢界面。
我想要做的只是每次用户动作做一次(在选择新元素之前做它没用)但是我无法知道事件是否只是一对中的第一个(为了跳过第一个计算)因为如果用户刚刚取消选择了所选元素,它只会触发一次。
我无法使用Click或MouseClick事件,因为如果用户在列表外单击以删除选择,则根本不会触发这些事件。
感谢您的帮助。
答案 0 :(得分:3)
我发现这也很烦人,所以在ObjectListView(.NET WinForms ListView的开源包装器)中有一个SelectionChanged事件,每个用户操作只发生一次。
使用直接的.NET ListView,当任何项目的选择状态发生变化时,它会触发SelectedIndexChanged事件。因此,只需单击另一行,您将获得一个用于取消选择先前选定行的事件,另一个用于选择新行。
如果您选择了100行,并选择了不同的行,那么您将获得101个SelectedIndexChanged事件 - 这可能是一种巨大的痛苦。
无论如何,使用ObjectListView,无论选择或取消选择多少行,您只能获得一个SelectionChanged事件。
答案 1 :(得分:3)
这是我在VB.NET中的解决方案,使用ObjectListView建议的Grammarian中描述的技术:
Private idleHandlerSet As Boolean = False
Private Sub listview1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles listview1.SelectedIndexChanged
'' may fire more than once
If Not idleHandlerSet Then
idleHandlerSet = True
AddHandler Application.Idle, New EventHandler(AddressOf listview1_SelectionChanged)
End If
End Sub
Private Sub listview1_SelectionChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
'' will only fire once
idleHandlerSet = False
RemoveHandler Application.Idle, New EventHandler(AddressOf listview1_SelectionChanged)
DoSearch()
End Sub
答案 2 :(得分:0)
在使用ListViews的C#WinForms项目中,我遇到了与OP相同的问题,Laurent's answer正是我想要的。下面的代码是Laurent的答案,翻译为C#:
private bool IdleHandlerSet { get; set; }
private void ListView_SelectedIndexChanged(object sender, EventArgs e)
{
// this will fire every time items are selected or deselected.
if (!IdleHandlerSet)
{
IdleHandlerSet = true;
Application.Idle += ListView_SelectionChanged;
}
}
private void ListView_SelectionChanged(object sender, EventArgs e)
{
// this will only fire once only
IdleHandlerSet = false;
Application.Idle -= ListView_SelectionChanged;
DoStuff();
}
答案 3 :(得分:-2)
如果您希望计算仅在选择了新项目时运行,您可以检查新的SelectedIndex是否为!= -1