2010-03-31 14 views
14

Czy można anulować zdarzenie SelectedIndexChange dla pola listy w aplikacji WinForm? Wydaje się to być logiczną rzeczą, że muszę przejść przez jakąś łatwą funkcję. Zasadniczo pojawiałem się w oknie z pytaniem, czy użytkownik naprawdę chce przejść do innego elementu, ponieważ zmieni to interfejs użytkownika i nie chcę, aby ich zmiany zostały utracone. Chciałbym móc anulować wydarzenie na wypadek, gdyby użytkownik nie zapisał tego, nad czym pracuje. Czy jest lepszy sposób na zrobienie tego?Anulowanie wybranego elementu ListViewIndexChange Event

+0

jestem zgodzić się z Nawfal więcej szczegółów sprawdź poniższy link .... http://www.mindstick.com/Articles/176c6d68-ceca-4072-a319-7389f4e5b9dd/?ListBox%20events % 20in% 20C% 20 # .Net –

+0

Możliwy duplikat [Jak zapobiec/anulować zmianę wartości combobox w C#?] (Http://stackoverflow.com/questions/314503/how-to-prevent-cancela-a- comboboxs-value-change-in-c) –

Odpowiedz

16

Nie można anulować.

To, co zrobiłem kilka dni temu, to mieć zmienną z najnowszym wybranym indeksem. Następnie, gdy zdarzenie zostanie wywołane, pytasz użytkownika, czy chce go zapisać, odbywa się to w module obsługi zdarzenia. Jeśli użytkownik wybrał opcję "Anuluj", zmienia się ponownie identyfikator.

Problem polega na tym, że wydarzenie zostanie ponownie uruchomione. Więc użyłem słowa bool, które mówi "Inhibit". A na górze eventhandler mam:

if(Inhibit) 
    return; 

Następnie poniżej tego gdzie zadać pytanie można zrobić coś takiego:

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

Drobna zmiana w tym, odkryłem po przeczytaniu tej odpowiedzi - można usunąć obsługę zdarzeń zamiast używać flagi Inhibit: 'list.SelectedIndexChanged - = list_SelectedIndexChanged; list.SelectedIndex = LastSelectedIndex; list.SelectedIndexChanged + = list_SelectedIndexChanged; ' Może być kilka powodów, dla których jest to gorsza metoda, ale działa bardzo dobrze dla moich celów. – TwainJ

+0

@J Jones Co się stanie, jeśli zrobiłeś minus dwa razy? Nie jestem pewien, czy to nie wyrzuciłoby wyjątku? –

+0

@OskarKjellin Nie robiłbyś tego dwa razy, ponieważ jest to wewnątrz funkcji.Funkcja nigdy nie zostanie wywołana, dopóki nie dodasz jej później. – Grungondola

2

SelectedIndexChanged nie mogą być anulowane. Więc masz tylko jedną prawdziwą opcję:

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

Właśnie wpadłem na ten dokładny problem. To, co zrobiłem, to gdy użytkownik wprowadza zmiany, ustawiam ListBox.Enabled = false; To uniemożliwia im wybór innego indeksu. Po zapisaniu lub odrzuceniu zmian ustawię ListBox.Enabled = true; Prawdopodobnie nie jest tak gładki jak podpowiedź, ale wykonuje swoją robotę.

+0

To jest niesamowite. Za każdym razem, gdy zaczynam się martwić o prywatne zmienne składowe, które śledzą bieżący Indeks, lub śledzę niektóre wartości Boolean Inhibit, zaczynam myśleć: jak mogę uniknąć dodawania tej dodatkowej warstwy logiki? Wyłączenie ListBox dba o to. – JustLooking

9

To jest dokładnie metoda @Oskar Kjellin, ale z niespodzianką. Oznacza to, że jedna zmienna mniej iz wybranym indeksem zmieniło zdarzenie, które naprawdę zachowuje się jak wybrane zmienione zdarzenie indeksu. Często zastanawiam się, dlaczego wybrany wskaźnik zmieniło wydarzenie, nawet jeśli kliknę dokładnie ten sam wybrany element. Tutaj tak nie jest. Tak, to odchylenie, więc bądźcie podwójnie pewni, jeśli chcecie, aby to tam było.

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

bardziej elegancki, należy użyć właściwości 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

To jest mój sposób, aby anulować SelectionChange dla ComboBox. Myślę, że może również pasować do 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; 
    } 
} 
Powiązane problemy