2013-03-21 13 views
14

Mam mały formularz z niektórymi polami wyboru, a dla każdego z pól wyboru dla zdarzenia CheckChanged znajduje się program obsługi wiadomości. Ponieważ niektóre pola wyboru zależą od innych, jeśli zmieni się stan jednego z pól wyboru, zmienia on zaznaczony stan dowolnych zależnych pól wyboru. Odkryłem, że powoduje to podniesienie zdarzeń w innych polach wyboru, ale moim problemem jest to, że każde zdarzenie ma jedno wywołanie funkcji, które powinno być wywołane tylko wtedy, gdy zdarzenie pochodzi od użytkownika, który faktycznie kliknął to pole wyboru. Chciałbym wiedzieć, jak powiedzieć (prawdopodobnie od nadawcy lub od EventArgs), czy zdarzenie CheckChanged zostało spowodowane kliknięciem myszy, czy nie.Jak stwierdzić, czy zdarzenie pochodzi z danych wprowadzonych przez użytkownika w języku C#?

Cliffs:

  • Wiele pól wyboru otrzymujących CheckChanged zdarzenie
  • należy ustalić, czy zdarzenie zostało podniesione przez kliknięcie myszą lub nie
+0

Co gdy używają klawiszy Tab i przestrzeni do poruszania się i wyboru? Postaram się rozwiązać twoją logikę, zanim zdecyduję się na przełamanie metod wprowadzania danych. –

+5

Prawdopodobnie odłączę obsługę zdarzeń dla zmiany, a następnie ponownie je połączę. – spender

+0

Czy możesz nam powiedzieć, dlaczego chciałbyś wiedzieć, czy to była mysz, której użyli? To może nam pomóc. Niemal we wszystkich przypadkach mogę pomyśleć, że nie ma to znaczenia ... – Penfold

Odpowiedz

5

Można używać flag do wskazania, czy nie ignorować zdarzenia. Prawdopodobnie jest to łatwiejsze niż anulowanie subskrypcji z programów obsługi zdarzeń. Nie jest bardzo wyrafinowany, ale powinien wykonać swoją pracę.

ułożyła szybki przykład:

bool ignoreEvents = false; 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void checkBox1_CheckedChanged(object sender, EventArgs e) 
     { 
      ignoreEvents = true; 
      checkBox2.Checked = checkBox1.Checked ; 
      checkBox3.Checked = checkBox1.Checked; 
      ignoreEvents = false; 
     } 

     private void checkBox2_CheckedChanged(object sender, EventArgs e) 
     { 
      if (ignoreEvents) return; 
      MessageBox.Show("Changed in 2"); 
     } 

     private void checkBox3_CheckedChanged(object sender, EventArgs e) 
     { 
      if (ignoreEvents) return; 
      MessageBox.Show("Changed in 3"); 
     } 
+0

Zrobiłem lewę i było to całkiem proste do zrealizowania, dzięki! EDYTOWANIE: Jestem nieco rozczarowany, że nie było odpowiedzi, która mogłaby podrażnić informacje z argumentów do obsługi zdarzeń – riqitang

0

Dla większej stabilności kodu można również użyć TriggerLock klasy zamiast flagi ignoreEvents.

private void checkBox1_CheckedChanged(object sender, EventArgs e) 
    { 
     using (new TriggerLock()) 
     { 
      checkBox2.Checked = checkBox1.Checked; 
      checkBox3.Checked = checkBox1.Checked; 
     } 
    } 

    private void checkBox2_CheckedChanged(object sender, EventArgs e) 
    { 
     if (TriggerLock.IsOpened) 
     { 
      MessageBox.Show("Changed in 2"); 
     } 
    } 

    private void checkBox3_CheckedChanged(object sender, EventArgs e) 
    { 
     if (TriggerLock.IsOpened) 
     { 
      MessageBox.Show("Changed in 3"); 
     } 
    } 

Klasa TriggerLock, to działa jak semafor:

public class TriggerLock 
    : IDisposable 
{ 
    private static int _nUsing = 0; 
    private bool _bDisposed; 

    public TriggerLock() 
    { 
     _bDisposed = false; 
     Interlocked.Increment(ref _nUsing); 
    } 
    ~TriggerLock() 
    { 
     Dispose(false); 
    } 

    public static bool IsOpened 
    { 
     get { return _nUsing == 0; } 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
    } 
    private void Dispose(bool bDisposing) 
    { 
     if (bDisposing && !_bDisposed) 
     { 
      Interlocked.Decrement(ref _nUsing); 
      _bDisposed = true; 
     } 
    } 
} 
+0

interesujących, ale w jaki sposób twoja klasa rozróżnia zdarzenia wywołane przez bezpośrednie interakcje użytkownika (np. Użytkownik klikający pole wyboru) i zdarzeń wywoływanych przez logikę efektów ubocznych (np. użytkownik klika pole wyboru, co powoduje, że inne pola wyboru zmieniają stan)? – riqitang

+0

Ta klasa nie powoduje niejawnego rozróżnienia między interakcjami użytkowników a efektami ubocznymi. Jest to tylko ulepszona (wyjątkowa) wersja pomysłu Alexa. – Georg

+0

Myślę, że statyczna zmienna '_NUsing' jest naprawdę złym pomysłem. Co się stanie, jeśli ta klasa zostanie użyta w dwóch niepowiązanych częściach tego samego projektu? To spowodowałoby koniec zamieszania. Byłoby lepiej użyć pola instancji i sprawić, by użytkownik zachowywał i obiekt tej klasy w polu. – Lii