5

很简单的问题,当列表视图的选定索引发生变化时,事件会触发两次,一次用于取消选择,第二次用于选择下一项。

我需要在不同时间选择或取消选择时使用该事件,但是如果取消选择只是稍后重新选择,它会使我的一半 ui 闪烁从启用到关闭再重新打开,它也会导致相当多的代码运行所以如果它是另一个被点击的项目而不是空格(用于取消选择),我只需要一种避免取消选择触发的方法

Dave R 说在这里使用 100 毫秒计时器:我的 ListView 选择事件处理是否遗漏了一些东西, 这听起来像是可以工作但看起来很不整洁,或者通常是一种不好的做法。

我唯一的另一个想法是使用点击事件,然后在该位置找到该项目?但我宁愿不去麻烦

提前致谢!

-编辑-

我只是认为单击事件会首先触发,因此我可以设置一个标志,如果单击事件发生在某个项目上,则跳过选择索引更改代码,然后在使用该标志后重置该标志,从而跳过取消选择?我现在看看,但再次感觉不是一种非常有效或简单的方法来做一些听起来很简单的事情?

4

4 回答 4

4

请改用ItemSelectionChanged事件 - ListViewItemSelectionChangedEventArgs可以告诉您哪个项目导致它触发,以及它是否被选中。

于 2012-09-26T13:47:43.267 回答
1

我刚刚尝试了另一种可能没有任何延迟的解决方案,它对我有用:

    If ListView1.Items(ListView1.FocusedItem.Index).Selected = False Then
        'This is the deselected value
        MsgBox("Deselected: " & ListView1.Items(ListView1.FocusedItem.Index).SubItems(0).Text)
    Else
        'This is the new selected value
        MsgBox("Selected: " & ListView1.Items(ListView1.FocusedItem.Index).SubItems(0).Text)
    End If
于 2014-02-04T19:26:02.330 回答
0

以下解决方案即使延迟 1 毫秒也有效。为了确保它有效,您可能可以选择更高的延迟,例如 10 毫秒,但 100 毫秒的延迟会使选择“无”时有点滞后。这是 C# 代码:

public class FixedListView : ListView
{
    private Timer _ItemSelectionChangedTimer = new Timer();
    private Timer _SelectedIndexChangedTimer = new Timer();

    private ListViewItemSelectionChangedEventArgs _ItemSelectionChangedEventArgs;
    private EventArgs _SelectedIndexChangedEventArgs;

    public FixedListView()
    {
        this._ItemSelectionChangedTimer.Interval = 1;
        this._SelectedIndexChangedTimer.Interval = 1;

        this._ItemSelectionChangedTimer.Tick += (sender, e) =>
        {
            this.OnItemSelectionChanged(this._ItemSelectionChangedEventArgs);
            this._ItemSelectionChangedEventArgs = null;
        };
        this._SelectedIndexChangedTimer.Tick += (sender, e) =>
        {
            this.OnSelectedIndexChanged(this._SelectedIndexChangedEventArgs);
            this._SelectedIndexChangedEventArgs = null;
        };
    }

    protected override void OnItemSelectionChanged(ListViewItemSelectionChangedEventArgs e)
    {
        if (this._ItemSelectionChangedTimer.Enabled)
        {
            this._ItemSelectionChangedTimer.Stop();
            base.OnItemSelectionChanged(e);
        }
        else
        {
            this._ItemSelectionChangedEventArgs = e;
            this._ItemSelectionChangedTimer.Start();
        }
    }

    protected override void OnSelectedIndexChanged(EventArgs e)
    {
        if (this._SelectedIndexChangedTimer.Enabled)
        {
            this._SelectedIndexChangedTimer.Stop();
            base.OnSelectedIndexChanged(e);
        }
        else
        {
            this._SelectedIndexChangedEventArgs = e;
            this._SelectedIndexChangedTimer.Start();                
        }
    }
}

这是VB代码:

Public Class FixedListBox

Inherits ListView

Public Sub New()

    Me._ItemSelectionChangedTimer.Interval = 1
    Me._SelectedIndexChangedTimer.Interval = 1

    AddHandler Me._ItemSelectionChangedTimer.Tick, _
        Sub(sender, e)
            Me.OnItemSelectionChanged(Me._ItemSelectionChangedEventArgs)
            Me._ItemSelectionChangedEventArgs = Nothing
        End Sub

    AddHandler Me._SelectedIndexChangedTimer.Tick, _
        Sub(sender, e)
            Me.OnSelectedIndexChanged(Me._SelectedIndexChangedEventArgs)
            Me._SelectedIndexChangedEventArgs = Nothing
        End Sub

End Sub

Private _ItemSelectionChangedTimer As New Timer()
Private _SelectedIndexChangedTimer As New Timer()

Private _ItemSelectionChangedEventArgs As ListViewItemSelectionChangedEventArgs
Private _SelectedIndexChangedEventArgs As EventArgs

Protected Overrides Sub OnItemSelectionChanged(e As ListViewItemSelectionChangedEventArgs)

    If Me._ItemSelectionChangedTimer.Enabled Then

        Me._ItemSelectionChangedTimer.Stop()
        MyBase.OnItemSelectionChanged(e)

    Else

        Me._ItemSelectionChangedEventArgs = e
        Me._ItemSelectionChangedTimer.Start()

    End If

End Sub

Protected Overrides Sub OnSelectedIndexChanged(e As EventArgs)

    If Me._SelectedIndexChangedTimer.Enabled Then

        Me._SelectedIndexChangedTimer.Stop()
        MyBase.OnSelectedIndexChanged(e)

    Else

        Me._SelectedIndexChangedEventArgs = e
        Me._SelectedIndexChangedTimer.Start()

    End If

End Sub

结束类

您可以像普通 ListView 一样使用该控件,但 SelectedIndexChanged 和 ItemSelectionChanged 只会触发一次。

玩得开心...

于 2013-04-03T07:18:35.873 回答
-1

只需在 SelectedIndexChanged 事件中检查焦点项目是否为空并退出。

ListView^ item = listView1-> FocusedItem;   //get selected item
if (item == nullptr){return;)  // this line exits when deselection event fires
String^ data1 = Convert::ToString (  item-> SubItems [0]    );   // get your data from columns like so
MessageBox::Show (data1);  // display

请注意,您可以通过更改 SubItems 中提供的索引来获取多个列下的数据,并且使用计时器和延迟只会产生开销,尤其是对于大型数据库会导致您的应用程序在 Visual C++ .NET 中减慢代码,但同样的理论适用于 C# 和其他

享受!!

于 2014-08-24T07:37:43.170 回答