2010-03-31 7 views
14

Est-il possible d'annuler l'événement SelectedIndexChange pour une zone de liste sur une application WinForms? Cela semble être une chose si logique d'avoir à négliger quelque chose de facile. Fondamentalement, j'ai ouvert une boîte de message demandant si l'utilisateur veut vraiment passer à un autre élément, car cela va changer l'interface utilisateur et je ne veux pas que leurs changements soient perdus. J'aimerais pouvoir annuler l'événement au cas où l'utilisateur n'aurait pas enregistré ce sur quoi il travaille. Existe-t-il une meilleure façon de le faire?Annulation de l'événement ListBox SelectedIndexChange

+0

Je suis d'accord avec Nawfal pour plus de détails consultez le lien suivant .... http://www.mindstick.com/Articles/176c6d68-ceca-4072-a319-7389f4e5b9dd/?ListBox%20events % 20in% 20C% 20 # .Net –

+0

Copie possible de [Comment empêcher/annuler la modification de valeur d'une liste déroulante dans C#?] (Http://stackoverflow.com/questions/314503/how-to-prevent-cancel-a- comboboxs-value-change-in-c) –

Répondre

16

Vous ne pouvez pas l'annuler.

Ce que j'ai fait il y a quelques jours était d'avoir une variable avec le dernier index sélectionné. Puis, lorsque l'événement se déclenche, vous demandez à l'utilisateur s'il veut enregistrer, ceci est fait dans le gestionnaire d'événement. Si l'utilisateur a sélectionné "Annuler", vous modifiez à nouveau l'identifiant.

Le problème est que cela déclenchera à nouveau l'événement. Donc, ce que j'ai utilisé est un bool juste en disant "Inhiber". Et au sommet de la eventhandler je:

if(Inhibit) 
    return; 

Ensuite, en dessous de ce où vous posez la question que vous faites quelque chose comme ceci:

DialogResult result = MessageBox.Show("yadadadad", yadada cancel etc); 
if(result == DialogResult.Cancel){ 
    Inhibit = true; //Make sure that the event does not fire again 
    list.SelectedIndex = LastSelectedIndex; //your variable 
    Inhibit = false; //Enable the event again 
} 
LastSelectedIndex = list.SelectedIndex; // Save latest index. 
+1

Une légère variation sur ce, j'ai découvert après avoir lu cette réponse - vous pouvez supprimer le gestionnaire d'événements au lieu d'utiliser le drapeau Inhiber: 'list.SelectedIndexChanged - = list_SelectedIndexChanged; list.SelectedIndex = LastSelectedIndex; list.SelectedIndexChanged + = list_SelectedIndexChanged; ' Il pourrait y avoir des raisons pour que ce soit une méthode inférieure, mais a très bien fonctionné pour mes fins. – TwainJ

+0

@J Jones Qu'est-ce qui se passe si vous avez fait deux fois moins? Vous ne savez pas si cela ne déclencherait pas d'exception? –

+0

@OskarKjellin Vous ne le feriez pas deux fois puisque c'est dans la fonction.La fonction ne sera plus jamais appelée jusqu'à ce que vous l'ajoutiez plus tard. – Grungondola

2

Le SelectedIndexChanged ne peut pas être annulé. Donc, vous n'avez qu'une seule vraie option:

private int? currentIndex; 
public void ListBox_SelectedIndexChanged(sender, EventArgs args) { 
    if (currentIndex.HasValue && currentIndex.Value != listBox1.SelectedIndex) { 
     var res = MessageBox.Show("Do you want to cancel edits?", "Cancel Edits", MessageBoxButtons.YesNo); 
     if (res == DialogResult.Yes) { 
      currentIndex = (listBox1.SelectedIndex == -1 ? null : (int?) listBox1.SelectedIndex); 
     } else { 
      listBox1.SelectedIndex = currentIndex.Value; 
     } 
    } 
} 
5

Je viens de rencontrer ce problème. Ce que j'ai fait est quand l'utilisateur apporte des modifications, j'ai mis ListBox.Enabled = false; Cela les empêche de sélectionner un index différent. Une fois qu'ils ont sauvegardé ou rejeté leurs modifications, j'ai défini ListBox.Enabled = true; Probablement pas aussi lisse qu'une invite, mais il fait le travail.

+0

C'est génial. Chaque fois que je commence à avoir à m'inquiéter des variables de membre privé qui gardent la trace de l'index actuel, ou de garder une trace de certains booléens Inhibit, je commence à penser: comment puis-je éviter d'ajouter cette couche supplémentaire de logique? Désactiver le ListBox prend soin de cela. – JustLooking

9

C'est exactement la méthode de @Oskar Kjellin, mais avec une torsion. C'est-à-dire, une variable de moins et avec un événement sélectionné qui a changé d'indice et qui se comporte comme un événement sélectionné. Je me demande souvent pourquoi l'indice sélectionné change d'événement même si je clique exactement sur le même élément sélectionné. Ici non. Oui c'est une déviation, alors soyez doublement sûr si vous voulez que ce soit là.

int _selIndex = -1; 
    private void listBox1_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     if (listBox1.SelectedIndex == _selIndex) 
      return; 

     if (MessageBox.Show("") == DialogResult.Cancel) 
     { 
      listBox1.SelectedIndex = _selIndex; 
      return; 
     } 

     _selIndex = listBox1.SelectedIndex; 
     // and the remaining part of the code, what needs to happen when selected index changed happens 
    } 
0

Plus élégant, utilisez la propriété Tag:

 if ((int)comboBox.Tag == comboBox.SelectedIndex) 
     { 
      // Do Nothing 
     } 
     else 
     { 
      if (MessageBox.Show("") == DialogResult.Cancel) 
      { 
       comboBox.SelectedIndex = (int)comboBox.Tag; 
      } 
      else 
      { 
       // Reset the Tag 
       comboBox.Tag = comboBox.SelectedIndex; 

       // Do what you have to 
      } 
     } 
0

Ceci est ma façon d'annuler SelectionChange pour ComboBox. Je pense que cela pourrait également correspondre à ListBox.

private bool comboBox_CancelSelection = false; 
private int comboBox_LastSelectedIndex = -1; 

private void comboBox_SelectedIndexChanged(object sender, EventArgs e) { 
    if (comboBox_CancelSelection) { 
     comboBox_CancelSelection = false; 
     return ; 
    } 

    // Handle Event 

    if (!comoBox_CancelSelection) { 
     comboBox_LastSelectedIndex = comboBox.SelectedIndex; 
    } else { 
     comboBox.SelectedIndex = comboBox_LastSelectedIndex; 
    } 
}