gpt4 book ai didi

C# ListView ItemSelectionChanged Event Multi Select 仅获取最后选择的项目

转载 作者:行者123 更新时间:2023-11-30 17:51:47 24 4
gpt4 key购买 nike

我在 C# .NET 4.5 中使用多选 ListView选择多个项目(即 Shift + End 或 Shift + 单击等)时会出现问题。当然,这些只是用于多选的许多不同鼠标/键盘组合的几个示例。

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

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 查询。

如果我首先单击 ListView 中的第 0 项,则可以运行查询,然后当您 shift+end 时,它会突出显示所有其余项,我希望它仅对最后选择的项目运行查询。相反,它在中间的每个项目上运行。

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

最佳答案

您是否考虑过在按下按钮时执行操作?这样他们也可以使用 Ctrl-Click 来选择他们想要的任何单个项目?

否则你需要做的是在触发 Action 之前等待一定的时间,这被称为去抖动,你可以在这里阅读更多关于去抖动的信息: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 秒运行您的代码。

我刚刚编写了这个类并进行了快速测试,建议进行更彻底的测试。无论如何,希望这足以理解这个想法。

关于C# ListView ItemSelectionChanged Event Multi Select 仅获取最后选择的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19062474/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com