背景:
在我的 winforms 表单中,我有一个Checked ListView和一个名为checkBoxAll的“主”复选框。主人的行为如下:
如果 master 被选中或未选中,则所有 ListViewItems 都必须相应更改。
如果用户取消选中 ListViewItem,则 master 必须相应更改。
如果用户检查了一个 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)。
Aaand 还有:写这个问题所花费的 30% 的时间是正确地制定问题和标题。仍然不确定它是否 100% 清晰,所以如果你认为你可以做得更好,请编辑:)