【发布时间】:2013-07-09 11:50:21
【问题描述】:
背景:
在我的 winforms 表单中,我有一个 Checked ListView 和一个名为 checkBoxAll 的“主”复选框。 master的行为如下:
如果 master 被选中或未选中,所有 ListViewItems 都必须相应更改。
如果用户取消选中 ListViewItem,则主视图必须相应更改。
如果用户检查了一个 ListViewItem,并且所有其他 ListViewItems 也都检查了,则 master 必须相应地更改。
我编写了以下代码来模仿这种行为:
private bool byProgram = false; //Flag to determine the caller of the code. True for program, false for user.
private void checkBoxAll_CheckedChanged(object sender, EventArgs e)
{
//Check if the user raised this event.
if (!byProgram)
{
//Event was raised by user!
//If checkBoxAll is checked, all listviewitems must be checked too and vice versa.
//Check if there are any items to (un)check.
if (myListView.Items.Count > 0)
{
byProgram = true; //Raise flag.
//(Un)check every item.
foreach (ListViewItem lvi in myListView.Items)
{
lvi.Checked = checkBoxAll.Checked;
}
byProgram = false; //Lower flag.
}
}
}
private void myListView_ItemChecked(object sender, ItemCheckedEventArgs e)
{
//Get the appropiate ListView that raised this event
var listView = sender as ListView;
//Check if the user raised this event.
if (!byProgram)
{
//Event was raised by user!
//If all items are checked, set checkBoxAll checked, else: uncheck him!
bool allChecked = true; //This boolean will be used to set the value of checkBoxAll
//This event was raised by an ListViewItem so we don't have to check if any exist.
//Check all items untill one is not checked.
foreach (ListViewItem lvi in listView.Items)
{
allChecked = lvi.Checked;
if (!allChecked) break;
}
byProgram = true; //Raise flag.
//Set the checkBoxAll according to the value determined for allChecked.
checkBoxAll.Checked = allChecked;
byProgram = false; //Lower flag.
}
}
在这个例子中,我使用一个标志 (byProgram) 来确定一个事件是否是由用户引起的,从而防止无限循环(一个事件可以触发另一个事件,它可以触发第一个再等等等等)。恕我直言,这是一个 hacky 解决方案。 我四处搜索,但找不到 MSDN 记录的方法来确定是否由于用户而直接触发了用户控制事件。这让我觉得很奇怪(再次,恕我直言)。
我知道 FormClosingEventArgs 有一个字段,我们可以使用它来确定用户是否正在关闭表单。但据我所知,这是唯一提供这种功能的 EventArg...
总之:
有没有办法(除了我的例子)来确定一个事件是否是由用户直接触发的?
请注意:我不是指事件的发送者!我编码 someCheckBox.Checked = true; 没关系或者手动设置someCheckBox,事件的发送者永远是someCheckBox。我想知道是否可以确定是通过用户(点击)还是通过程序(.Checked = true)。
另外: 30% 的时间写这个问题是为了正确地制定问题和标题。仍然不确定它是否 100% 清晰,所以如果你认为你可以做得更好,请编辑:)
【问题讨论】:
-
只是一个疯狂的猜测,但 EventArgs 中确实应该有一些东西。您是否在运行时检查过它们(调试)?
-
点击事件设置一个标志来知道这个调用是来自点击而不是代码?
-
@Romiox,检查我的问题,它说我没有那种功能(据我所知,只有 FormClosing 有这个)。
-
@MEYWD,我想过这个问题,但这仍然是一个标志,现在还有另一个事件。这似乎不是理想的解决方案。