2010-03-31 9 views
14

Kann das SelectedIndexChange-Ereignis für eine Listbox in einer Winforms-Anwendung abgebrochen werden? Das scheint so logisch zu sein, dass ich ein leichtes Feature übersehen muss. Im Grunde habe ich ein Meldungsfeld geöffnet, in dem ich gefragt werde, ob der Benutzer wirklich zu einem anderen Element wechseln möchte, da dies die Benutzeroberfläche ändern wird und ich möchte nicht, dass ihre Änderungen verloren gehen. Ich möchte die Veranstaltung abbrechen können, wenn der Benutzer nicht gespeichert hat, woran er gerade arbeitet. Gibt es einen besseren Weg, dies zu tun?ListBox löschen SelectedIndexChange-Ereignis

+0

ich mit Nawfal um weitere Informationen zu vereinbaren bin auf den folgenden Link überprüfen .... http://www.mindstick.com/Articles/176c6d68-ceca-4072-a319-7389f4e5b9dd/?ListBox%20events % 20in% 20C% 20 # .Net –

+0

Mögliches Duplikat von [So verhindern/löschen Sie die Wertänderung einer Combobox in C#?] (Http://stackoverflow.com/questions/314503/how-to-prevent-cancel-a- comboboxs-value-change-in-c) –

Antwort

16

Sie können den Vorgang nicht abbrechen.

Was ich vor ein paar Tagen getan habe, war eine Variable mit dem letzten ausgewählten Index zu haben. Wenn das Ereignis ausgelöst wird, fragen Sie den Benutzer, ob er speichern möchte, dies geschieht im Eventhandler. Wenn der Benutzer "Abbrechen" ausgewählt hat, ändern Sie die ID erneut.

Das Problem ist, dass dadurch das Ereignis erneut ausgelöst wird. Also was ich benutzt habe, ist ein Bool, der nur "Inhibit" sagt. Und an der Spitze des Eventhandler ich habe:

if(Inhibit) 
    return; 

Dann unterhalb dieses, wo Sie die Frage stellen Sie etwas tun, wie folgt aus:

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

Eine geringfügige Abweichung davon, entdeckte ich nach dem Lesen dieser Antwort - Sie können den Event-Handler anstelle der Verwendung der Inhibit Flag entfernen: 'list.SelectedIndexChanged - = list_SelectedIndexChanged; list.SelectedIndex = LastSelectedIndex; list.SelectedIndexChanged + = list_SelectedIndexChanged; ' Es könnte einige Gründe geben, dass dies eine minderwertige Methode ist, aber für meine Zwecke sehr gut funktioniert. – TwainJ

+0

@J Jones Was passiert, wenn Sie zweimal minus gemacht haben? Nicht sicher, ob das keine Ausnahme auslösen würde? –

+0

@OskarKjellin Sie würden es nicht zweimal tun, da dies in der Funktion ist.Die Funktion wird nie wieder aufgerufen, bis Sie sie später hinzufügen. – Grungondola

2

Die SelectedIndexChanged kann nicht storniert werden. Sie haben also nur eine echte 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

Ich lief gerade in genau dieses Problem. Was ich getan habe, wenn der Benutzer Änderungen vornimmt, setze ich ListBox.Enabled = false; Dies verbietet ihnen, einen anderen Index auszuwählen. Sobald sie ihre Änderungen entweder gespeichert oder verwerfen, setze ich ListBox.Enabled = true; Wahrscheinlich nicht so glatt wie eine Aufforderung, aber es macht den Job erledigt.

+0

Das ist großartig. Jedes Mal, wenn ich anfange, mich um private Member-Variablen zu kümmern, die den aktuellen Index verfolgen oder einen booleschen Inhibit-Eintrag verfolgen, denke ich: Wie vermeide ich es, diese zusätzliche Logikschicht hinzuzufügen? Das Deaktivieren der ListBox erledigt dies. – JustLooking

9

Dies ist genau @Oskar Kjellins Methode, aber mit einer Wendung. Das heißt, eine Variable weniger und mit einem ausgewählten Index wurde ein Ereignis geändert, das sich tatsächlich wie ein ausgewähltes Ereignis mit geändertem Index verhält. Ich wundere mich oft, warum ein ausgewählter Index geändert wird, wenn das Ereignis ausgelöst wird, selbst wenn ich auf den exakt gleichen ausgewählten Gegenstand klicke. Hier ist es nicht. Ja, es ist eine Abweichung, also sei dir sicher, ob du das hier haben willst.

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

Mehr elegant, verwenden Sie die Eigenschaft 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

Das ist meine Art und Weise für Selection ComboBox abzubrechen. Ich denke, es könnte auch zu ListBox passen.

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; 
    } 
}