.NET ListView:更改选择后的事件

时间:2009-07-28 04:19:37

标签: .net winforms listview

在ListView控件上,我需要在选择更改后触发事件,但每个用户操作只需要触发一次。如果我只是使用SelectedIndexChanged,那么在大多数情况下该事件会触发两次(一次取消选择前一个元素时,选择新元素时再触发一次)如果用户仅点击一次控件,则为事件。

这两个事件一个接一个地快速触发,但是当选择更改时我所做的计算需要花费时间(几乎一秒),因此它会完成两次并减慢界面。

我想要做的只是每次用户动作做一次(在选择新元素之前做它没用)但是我无法知道事件是否只是一对中的第一个(为了跳过第一个计算)因为如果用户刚刚取消选择了所选元素,它只会触发一次。

我无法使用Click或MouseClick事件,因为如果用户在列表外单击以删除选择,则根本不会触发这些事件。

感谢您的帮助。

4 个答案:

答案 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