【发布时间】:2010-03-05 19:00:02
【问题描述】:
如何防止触发由单个操作触发的多个相同类型的事件?
例如,我有一个 ListView 包含一些项目。当我选择或取消选择所有项目时,每个项目都会触发一次 SelectedIndexChanged 事件。相反,我希望接收单个事件指示用户的操作(选择/取消选择项目),而不考虑项目的数量。
有什么办法可以做到吗?
【问题讨论】:
如何防止触发由单个操作触发的多个相同类型的事件?
例如,我有一个 ListView 包含一些项目。当我选择或取消选择所有项目时,每个项目都会触发一次 SelectedIndexChanged 事件。相反,我希望接收单个事件指示用户的操作(选择/取消选择项目),而不考虑项目的数量。
有什么办法可以做到吗?
【问题讨论】:
您无法更改 ListView 代码,并且对其进行子类化并不能提供很多选择。
我建议您只需在代码中添加一个小延迟(200 毫秒或类似) - 即您只在上次更新后的一小段时间进行计算。比如:
using System;
using System.Windows.Forms;
static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
ListView list;
TextBox txt;
Timer tmr = new Timer();
tmr.Interval = 200;
Form form = new Form {
Controls = {
(txt = new TextBox { Dock = DockStyle.Fill, Multiline = true}),
(list = new ListView { Dock = DockStyle.Right, View = View.List,
Items = { "abc", "def" , "ghi", "jkl", "mno" , "pqr"}})
}
};
list.SelectedIndexChanged += delegate {
tmr.Stop();
tmr.Start();
};
tmr.Tick += delegate {
tmr.Stop();
txt.Text += "do work on " + list.SelectedItems.Count + " items"
+ Environment.NewLine;
};
Application.Run(form);
}
}
【讨论】:
只有从稍微不同的方向来解决问题。例如。订阅失去焦点。
最后,应用程序或运行时无法在“所有选择更改完成”时引发事件,而无需实际使用其他东西,因为应用程序无法预测用户是否会在控件保留时再次单击该控件重点。
即使使用焦点,用户也可以切换回该控件。
【讨论】:
如果您的 ListView 在 virtual mode 中,您可以使用
VirtualItemsSelectionRangeChanged event。对于用户的操作(选择/取消选择),该事件只会触发一次。
【讨论】: