Hintergrund gefeuert:Bestimmen Sie, wer ein Ereignis
In meiner WinForms Form, ich habe ein Karo Listview und eine "Master" Checkbox namens checkBoxAll. Das Verhalten des Masters ist wie folgt:
Wenn der Master aktiviert oder deaktiviert wird, müssen alle Listviewitem entsprechend ändern.
Wenn der Benutzer ein ListViewItem deaktiviert, muss der Master entsprechend geändert werden.
Wenn der Benutzer ein ListViewItem überprüft und alle anderen ListViewItems ebenfalls überprüft werden, muss der Master entsprechend geändert werden.
Ich habe den folgenden Code geschrieben, dieses Verhalten zu imitieren:
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.
}
}
In diesem Beispiel verwende ich eine Flagge (byProgram) ein Ereignis, um sicherzustellen, dass durch die Nutzer verursacht wurde oder nicht , wodurch eine Endlosschleife verhindert wird (ein Ereignis kann ein anderes auslösen, das wiederum das erste auslösen kann usw. usw.). IMHO, das ist eine Hacky-Lösung. Ich suchte, aber ich konnte keine dokumentierte MSDN-Methode finden, um festzustellen, ob ein User Control Event dank des Benutzers direkt ausgelöst wurde. Was mir seltsam vorkommt (wieder IMHO).
Ich weiß, dass das FormClosingEventArgs über ein Feld verfügt, mit dem wir ermitteln können, ob der Benutzer das Formular schließt oder nicht. Aber soweit ich weiß, ist, dass die einzige EventArg, die diese Art von Funktionalität bietet ...
Also zusammenfassend:
Gibt es eine Möglichkeit (außer meinem Beispiel), um zu bestimmen, ob ein Ereignis war direkt vom Benutzer gefeuert?
Bitte beachten Sie: Ich meine nicht den Absender eines Ereignisses! Es spielt keine Rolle, ob ich codeCheckBox.Checked = true; oder manuelles Setzen von someCheckBox, der Absender des Ereignisses wird immer someCheckBox sein. Ich möchte herausfinden, ob es möglich ist, festzustellen, ob es durch den Benutzer (klick) oder durch das Programm (.Checked = true) war.
Aaand auch: 30% der Zeit, die es dauerte, diese Frage zu schreiben, war, die Frage und den Titel richtig zu formulieren. Immer noch nicht sicher, ob es ein 100% clear ist, also bitte bearbeiten, wenn Sie denken, dass Sie es besser machen können :)
Nur eine wilde Vermutung, aber es sollte wirklich etwas in den EventArgs sein. Haben Sie sie zur Laufzeit überprüft (Debugging)? –
Ein Klick-Ereignis setzt eine Markierung, um zu wissen, dass dieser Anruf von einem Klick und nicht von einem Code kommt? – MEYWD
Verwenden Sie den 'Absender'? – DGibbs