J'ai une liste déroulante en haut d'un formulaire qui charge des données modifiables dans les champs ci-dessous. Si l'utilisateur a apporté des modifications, mais qu'il n'a pas été enregistré, et qu'il tente de sélectionner une option différente dans la liste déroulante, je souhaite les avertir et leur donner la possibilité d'annuler ou de sauvegarder.
J'ai besoin d'un événement "BeforeValueChange" avec un argument d'événement annulable.
Un conseil sur la façon d'accomplir?
Enregistrez le SelectedIndex de la ComboBox quand box si vous l'avez entré pour la première fois, puis restaurez sa valeur lorsque vous devez annuler la modification.
cbx_Example.Enter += cbx_Example_Enter;
cbx_Example.SelectionChangeCommitted += cbx_Example_SelectionChangeCommitted;
...
private int prevExampleIndex = 0;
private void cbx_Example_Enter(object sender, EventArgs e)
{
prevExampleIndex = cbx_Example.SelectedIndex;
}
private void cbx_Example_SelectionChangeCommitted(object sender, EventArgs e)
{
// some custom flag to determine Edit mode
if (mode == FormModes.EDIT)
{
cbx_Example.SelectedIndex = prevExampleIndex;
}
}
Voici le correctif le plus simple: -
bool isSelectionHandled = true;
void CmbBx_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (isSelectionHandled)
{
MessageBoxResult result = MessageBox.Show("Do you wish to continue selection change?", this.Title, MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.No)
{
ComboBox combo = (ComboBox)sender;
isSelectionHandled = false;
if (e.RemovedItems.Count > 0)
combo.SelectedItem = e.RemovedItems[0];
return;
}
}
isSelectionHandled = true;
}
Enregistrez la valeur actuelle sur l'événement Enter
. Implémentez la logique BeforeValueChange
dans l'événement ValueChanged
, avant la logique ValueChanged
réelle. Si l'utilisateur annule, définissez la valeur stockée et ne continuez pas dans la méthode (return
).
Si vous comptez beaucoup utiliser ce système, je vous conseillerais d'hériter ComboBox et d'y implémenter votre événement BeforeValuechange
.
L'événement de validation peut être utilisé pour ce scénario
http://msdn.Microsoft.com/en-us/library/system.windows.forms.control.validating.aspx
Vous n'obtenez pas un événement approprié par défaut. Vous pouvez mettre en cache la valeur précédente et la redéfinir sur cette valeur si l'utilisateur souhaite annuler.
Qu'en est-il des événements Validation/Validé?
Cela fonctionne bien si l’événement qui se produit sur LostFocus au lieu de Change vous convient.
Sinon, que diriez-vous
public void Combobox_ValueChanged(object sender, EventArgs e) {
if (!AskUserIfHeIsSureHeWantsToChangeTheValue())
{
// Set previous value
return;
}
// perform rest of onChange code
}
Vous pouvez utiliser un message filter pour intercepter les clics et les appuis sur les touches, ce qui vous permettrait d’empêcher le comportement normal de la zone de liste déroulante. Mais je pense que vous feriez mieux de désactiver la zone de liste déroulante lorsque l'utilisateur apporte une modification et de lui demander de sauvegarder ou d'annuler ses modifications.
Vous ne pouvez pas vraiment l'empêcher, mais vous pouvez revenir à l'ancienne valeur si certaines conditions ne sont pas remplies:
private SomeObject = selectedSomeObject=null;
private void cbxTemplates_SelectionChangeCommitted(object sender, EventArgs e)
{
if (!(sender is ComboBox cb)) return;
if (!(cb.SelectedItem is SomeObject tem)) return;
if (MessageBox.Show("You sure?", "??.",
MessageBoxButtons.OKCancel) != DialogResult.OK)
cb.SelectedItem = selectedSomeObject;
else
{
selectedSomeObject = tem;
}
}