C#的ListView ItemSelectionChanged事件多选择只得到最后一个项目选择 [英] C# ListView ItemSelectionChanged Event Multi Select get ONLY last item selected
问题描述
即时通讯使用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屋!