C# 列表视图项选择更改的事件多选获取仅选择最后一个项
本文关键字:选择 获取 最后一个 事件 列表 视图 | 更新日期: 2023-09-27 18:33:03
Im 在 C# .NET 4.5 中使用多选列表视图选择多个项目(即。移位 + 结束或移位 + 单击等(当然,这些只是许多不同鼠标/键盘组合的几个例子,用于多项选择。
这是我在列表中选择项目时的事件处理程序:
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 查询。
如果我首先单击列表视图中的第 0 项,则可以运行查询,然后当您 shift+end 时,它会突出显示所有其他内容,我希望它仅在最后一个选定项目上运行查询。 相反,它运行在两者之间的每个项目上。
编辑:另一方面,事件也会在取消选择时触发,在这种情况下,它在取消选择时确实不应该做任何事情。
您是否考虑过在按下按钮时执行该操作?这样,他们还可以使用 Ctrl 并单击来选择他们想要的任何单个项目?
否则,您所要做的就是在触发动作之前等待一定时间,称为去抖动,您可以在此处阅读有关去抖动的更多信息:https://stackoverflow.com/a/4517995/984780
我创建了一个可用于去抖动的类:
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();
}
}
然后,您可以将代码更改为以下内容:
private void lvTitles_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
{
Debounce.Run(5, () => MessageBox.Show(e.Item.Text.ToString()));
}
无论他们如何选择项目,这都应该有效,它将在他们最后一次选择操作后 5 秒运行您的代码。
我刚刚写了这门课并做了一个快速测试,建议进行更彻底的测试。无论如何,希望得到这个想法就足够了。