2008-11-13 44 views
7

Điều này có vẻ như là một vấn đề rất đơn giản và rất phổ biến. Ví dụ đơn giản nhất mà tôi có thể nghĩ đến là:Cách tốt nhất để tạm dừng các sự kiện kiểm soát trong Windows Forms?

Biểu mẫu có năm hộp kiểm có hộp kiểm "chọn tất cả/không chọn" ở trên chúng. Khi người dùng chọn kiểm tra tất cả các hộp kiểm, tôi chuyển đổi trạng thái của "trẻ em" - rõ ràng là tôi không muốn kích hoạt các sự kiện kiểm tra của tất cả trẻ em cho đến khi tôi hoàn thành cài đặt tất cả các hộp kiểm.

Tôi không thể tìm thấy sự kiện kiểm soát tạm ngưng trên toàn biểu mẫu. Nếu tôi chỉ đơn giản là thiếu nó thì câu trả lời đơn giản tuyệt vời. Chặn một giải pháp đơn giản mà tôi chỉ thiếu, cách tốt nhất (giải pháp tốt nhất là giải pháp được chấp nhận là gì?) Để đình chỉ các sự kiện kiểm soát biểu mẫu?

+0

Bạn đang sử dụng VB .NET hoặc C#? –

+0

@Kyralessa: Có quan trọng không? –

+0

Hoặc là hoặc. Đây là một câu hỏi chung và ví dụ trên chỉ là một ví dụ. Tôi chỉ chạy vào kịch bản nhiều lần, nơi tôi muốn kiểm soát các sự kiện để ngăn chặn trong khi tôi làm điều gì đó và chỉ tò mò là để thực hành tốt nhất. –

Trả lời

4

tôi đã đi qua này trước và thường thấy mọi người làm điều này:

/*SNIP*/ 

private bool isMassUpdate; 

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

/*SNIP*/ 

Bạn cũng có thể tách rời và lắp lại xử lý sự kiện, tuy nhiên, tôi đang nói điều này có thể là một nguồn rò rỉ bộ nhớ.

Thông tin về rò rỉ bộ nhớ và trình xử lý sự kiện: Chúng không được liên kết trực tiếp với việc gắn và tách, nhưng chúng tôi đã thấy trong một ứng dụng của chúng tôi có tham chiếu xấu về trình xử lý sự kiện xuống cây thừa kế.

3

Từ câu hỏi khác của bạn, tôi sẽ đoán bạn đang sử dụng VB .NET. Vì vậy, RemoveHandler là đặt cược tốt nhất của bạn. Thông thường trong VB người thiết lập xử lý sự kiện bằng cách sử dụng mệnh đề Handles. Nhưng bạn cũng có thể làm theo cách này:

AddHandler chk1.CheckedChanged, AddressOf DoSomething 

nơi DoSomething có thể trông như thế này:

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

dây AddHandler lên sự kiện này, vì vậy nó sẽ bắn. Để không kích hoạt, hãy sử dụng RemoveHandler:

RemoveHandler chk1.CheckedChanged, AddressOf DoSomething 

Trước khi cập nhật thuộc tính Đã kiểm tra của con bạn, hãy gọi RemoveHandler trên mỗi hộp; sau đó khi bạn hoàn tất, hãy gọi AddHandler để đưa trình xử lý sự kiện trở lại. Nếu tất cả các hộp kiểm của bạn sử dụng cùng một trình xử lý, bạn có thể đặt chúng trong một bộ sưu tập và lặp qua bộ sưu tập để thêm hoặc loại bỏ các trình xử lý.

1

Bạn cũng có thể xem xét việc xử lý tiếng 'click' sự kiện cho các nút, chứ không phải là kiểm tra-thay đổi. Điều đó có thể gần hơn với ý định của bạn.

+0

Cảm ơn và thực sự có ý nghĩa ở đây nhưng đây là một câu hỏi chung và ví dụ trên chỉ là một ví dụ. Tôi chỉ chạy vào kịch bản nhiều lần, nơi tôi muốn kiểm soát các sự kiện để ngăn chặn trong khi tôi làm điều gì đó và chỉ tò mò là để thực hành tốt nhất. –

0

Trong ứng dụng Visual Basic 6.0 của tôi, tôi phải xử lý người dùng nhấp đúp vào mọi thứ, vì vậy trên tất cả các xử lý sự kiện của tôi, tôi có một dòng để kiểm tra một biến toàn cầu

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

Những gì tôi làm trong những trường hợp này thay vì có một giá trị boolean đình chỉ các sự kiện, tôi sử dụng một bộ đếm. Khi số đếm là> 0, sau đó đình chỉ các sự kiện, khi đếm = 0, sau đó tiếp tục sự kiện. Điều này giúp giải quyết vấn đề nếu tôi có nhiều thứ có thể yêu cầu tạm ngưng sự kiện.

Điều hữu ích khác là nếu tôi cần tạm dừng sự kiện trong một khối, tôi tạo một lớp trợ giúp nhỏ là IDisposable mà tôi có thể sử dụng trong khối "đang sử dụng" (trong C#) để tôi không quên giảm truy cập một khi tôi ra khỏi phạm vi.

1

Xem Stack Overflow câu hỏi How do I ignore simple events firing when changing control states in C# Windows Forms?

Đối với trường hợp tổng quát hơn, nếu bạn có mối quan hệ phức tạp giữa các điều khiển, bạn có thể kiểm tra mà kiểm soát bắn sự kiện này bằng cách kiểm tra tài sản tập trung riêng của mình ... mỗi đối tượng chỉ phụ thuộc vào chính nó.

Các vấn đề liên quan