2008-11-13 10 views
7

Wydaje się to bardzo prostym i bardzo powszechnym problemem. Najprostszy przykład, jaki mogę wymyślić, to:Najlepszy sposób na zawieszanie zdarzeń kontrolnych w Windows Forms?

Formularz ma pięć pól wyboru z zaznaczonym polem wyboru "sprawdź wszystko/zaznacz brak". Gdy użytkownik wybierze zaznaczenie wszystkich pól wyboru, przełączam stany "dzieci" - oczywiście nie chcę wywoływać zdarzeń kontrolnych wszystkich dzieci, dopóki nie skończę ustawiania wszystkich pól wyboru.

Nie można znaleźć zdarzenia sterującego zawieszeniem całego formularza. Jeśli po prostu mi go brakuje, to świetna prosta odpowiedź. Z wyjątkiem prostego rozwiązania, którego mi brakuje, jaki jest najlepszy sposób (najlepsza praktyka? Przyjęte rozwiązanie?) Do zawieszania zdarzeń kontrolnych form?

+0

Czy używasz VB .NET lub C#? –

+0

@Kyralessa: Czy to ma znaczenie? –

+0

Albo/lub. Jest to bardziej ogólne pytanie, a powyższy przykład jest właśnie tym, przykładem. Po prostu wpadłem na scenariusz wiele razy, kiedy chciałbym, aby zdarzenia kontrolne ustały, gdy robię coś i jestem ciekawy co do najlepszej praktyki. –

Odpowiedz

4

Natknąłem tego wcześniej i zazwyczaj postrzegane ludzie to zrobić:

/*SNIP*/ 

private bool isMassUpdate; 

public void Check1_Check(object sender, EventArgs e) 
{ 
    if(!isMassUpdate) 
    { 
     do some stuff 
    } 
} 

/*SNIP*/ 

Można też odłączyć i ponownie podłączyć obsługi zdarzeń, jednak, jak mi powiedziano to może być źródłem wycieków pamięci.

Informacje na temat wycieków pamięci i procedur obsługi zdarzeń: nie są bezpośrednio związane z dołączaniem i odłączaniem, ale widzieliśmy w jednej z naszych aplikacji, że złe odwoływanie się do procedur obsługi zdarzeń powoduje, że drzewa dziedziczenia mogą je powodować.

3

Z twojego innego pytania, będę zgadywać, że używasz VB .NET. Tak więc RemoveHandler jest najlepszym wyborem. Zwykle w VB ludzie konfigurują programy obsługi zdarzeń za pomocą klauzuli Handles. Ale można też zrobić to w ten sposób:

AddHandler chk1.CheckedChanged, AddressOf DoSomething 

gdzie DoSomething może wyglądać następująco:

Private Sub DoSomething(ByVal sender As Object, ByVal e As EventArgs) 
    ' whatever 
End Sub 

AddHandler przewody się zdarzenie, więc będzie to ogień. Aby uzyskać nie do ugaszenia stosować RemoveHandler:

RemoveHandler chk1.CheckedChanged, AddressOf DoSomething 

Przed aktualizacją sprawdzonej własności swojego wyboru dziecka, zadzwoń RemoveHandler na każdego z nich; następnie, gdy skończysz, wywołaj AddHandler, aby przywrócić funkcje obsługi zdarzeń. Jeśli wszystkie pola wyboru używają tego samego modułu obsługi, możesz umieścić je w kolekcji i przechodzić przez kolekcję, aby dodać lub usunąć programy obsługi.

1

Można też rozważyć obsługi 'kliknąć' zdarzeń dla przycisków, zamiast zameldowania zmieniło. To może być bliżej twojej intencji.

+0

Dzięki i prawda ma tutaj sens, ale jest to bardziej ogólne pytanie, a powyższy przykład jest właśnie tym, przykładem. Po prostu wpadłem na scenariusz wiele razy, kiedy chciałbym, aby zdarzenia kontrolne ustały, gdy robię coś i jestem ciekawy co do najlepszej praktyki. –

0

W mojej aplikacji Visual Basic 6.0 miałem do obsługi użytkowników dwukrotne kliknięcie wszystko, więc na wszystkich moich obsługi zdarzeń mam jedną linię, która sprawdza zmienną globalną

Private bSuspendEvents as Boolean 

Private Sub Button1_Click() 

    On Error Goto ErrorHandler 

    If bSuspendEvents then Exit Sub 

    bSuspendEvents = True 

    'Do stuff 

    NormalExit: 
     bSuspendEvents = False 
     Exit Sub 

    ErrorHandler: 
     'Handle Error 
     Resume NormalExit 

End Sub 
4

Co zrobić w takich przypadkach zamiast o wartości boolowskiej, która zawiesza zdarzenia, używam licznika. Gdy liczba jest> 0, a następnie wstrzymaj zdarzenia, gdy liczba = 0, wznów zdarzenia. Pomaga to w rozwiązaniu problemu, jeśli mam wiele rzeczy, które mogą wymagać zawieszenia wydarzeń.

Inną pożyteczną rzeczą jest to, że jeśli potrzebuję zawiesić zdarzenia w bloku, tworzę małą klasę pomocniczą, która jest IDisposable, którą mogę użyć w bloku "using" (w C#), więc nie zapomnę o dekrementacji licznik, gdy jestem poza zasięgiem.

Powiązane problemy