C#的ListView ItemSelectionChanged事件多选择只得到最后一个项目选择 [英] C# ListView ItemSelectionChanged Event Multi Select get ONLY last item selected

查看:2814
本文介绍了C#的ListView ItemSelectionChanged事件多选择只得到最后一个项目选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即时通讯使用C#.NET 4.5多选的ListView
选择多个项目时会发生此问题(即Shift + End或Shift +点击等),这些是当然的多选择许多不同的鼠标/键盘组合的几个例子。

Im using a multi-select ListView in C# .NET 4.5 The issue occurs when selecting multiple items (ie. Shift + End or Shift + Click, etc.) These are just a few examples of many different mouse/keyboard combinations for multi-selecting of course..

这是我在列表中选择项目时的事件处理程序:

This is my event handler for when selecting items in a list:

private void lvTitles_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
    MessageBox.Show(e.Item.Text.ToString());
    //MessageBox just for testing I am actually running a SQL query here
}

我的问题是,如果我选择500项事件被触发500次。这样做的目的是为了得到最后一个项目选择(通过上面提到的键盘/鼠标组合)用户,并用它做什么...在我的情况,我需要对其运行SQL查询。

My problem is that if I select 500 items the event is triggered 500 times. The intent is to get that last item the user selected (via keyboard/mouse combinations mentioned above), on and do something with it ... in my case I need to run a SQL query against it.

如果我点击第一个项目0在ListView它是确定运行查询,那么当你SHIFT + END它强调所有的休息,我希望它仅在选定的最后一个项目运行查询。相反,它是在每一个项目中运行的。

If I click first on item 0 in the listview it is ok to run the query, then when you shift+end it highlights all the rest, and I want it to run the query only on the last item selected. Instead it is running on every item in between.

编辑:在另一方面,事件触发,因为它取消选择为好,在这种情况下取​​消时,它真的不应该做任何事情

推荐答案

你有没有考虑上的一个按钮preSS而不是执行的行动?这样,他们也可以使用Ctrl单击选择他们想要的任何单个项目?

Have you considered performing the action on a button press instead? That way they can also use Ctrl-Click to select any individual items they want?

否则,你必须做射击动作,被称为反跳之前等待一定的时间的,你可以阅读更多关于防抖动这里:的 http://stackoverflow.com/a/4517995/984780

Otherwise what you would have to do is wait a certain amount of time before firing the action, known as debouncing, you can read a more about debouncing here: http://stackoverflow.com/a/4517995/984780

我创建可用于消除抖动的类:

I created a class you can use for debouncing:

public class Debounce {
    private Action _action;
    private bool _isThreadRunning;
    private Thread _thread;
    private DateTime _runAt;
    private double _waitSeconds;

    private Debounce(double waitSeconds, Action action) {
        _action = action;
        _waitSeconds = waitSeconds;
    }

    private void Invoke() {
        _runAt = DateTime.Now.AddSeconds(_waitSeconds);

        lock(this) {
            if(!_isThreadRunning) {
                _isThreadRunning = true;

                _thread = new Thread(() => {
                    while(true) {
                        Thread.Sleep(100);

                        lock(this) {
                            if(DateTime.Now > _runAt) {
                                _action();
                                _isThreadRunning = false;
                                _thread = null;
                                break;
                            }
                        }
                    }
                });

                _thread.Start();
            }
        }
    }

    private static Dictionary<Action, Debounce> __debounces;
    private static Dictionary<Action, Debounce> _debounces {
        get {
            if(__debounces == null) {
                __debounces = new Dictionary<Action, Debounce>();
            }

            return __debounces;
        }
    }

    public static void Run(double waitSeconds, Action action) {
        Debounce debounce;

        if(!_debounces.TryGetValue(action, out debounce)) {
            debounce = new Debounce(waitSeconds, action);
            _debounces.Add(action, debounce);
        }

        debounce._waitSeconds = waitSeconds;
        debounce.Invoke();
    }
}

然后你就可以改变你的code这样:

Then you can change your code to this:

private void lvTitles_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
    Debounce.Run(5, () => MessageBox.Show(e.Item.Text.ToString()));
}

这应该工作,无论他们如何选择项目,将5秒后他们最后的选择操作运行code。

This should work no matter how they select items, it will run your code 5 seconds after their last selection action.

我刚写了这个类,并做了一个快速测试,更彻底的测试将被告知。在任何情况下,希望它足以让这个想法。

I just wrote this class and did a quick test, a more thorough test would be advised. In any case hopefully it's enough to get the idea.

这篇关于C#的ListView ItemSelectionChanged事件多选择只得到最后一个项目选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆