2011-11-14 29 views
7

chạy Khi bạn có một nút, và làm điều gì đó như:Force vẽ lại chẳng bao lâu hoạt động

Private Function Button_OnClick 

    Button.Enabled = False 

    [LONG OPERATION] 

End Function 

Sau đó, nút sẽ không được chuyển sang màu xám, vì hoạt động lâu ngăn thread UI từ sơn lại sự kiểm soát. Tôi biết thiết kế phù hợp là để bắt đầu một chủ đề nền/dispatcher, nhưng đôi khi đó là quá nhiều rắc rối cho một hoạt động đơn giản.

Vậy làm cách nào để buộc nút vẽ lại ở trạng thái đã tắt? Tôi đã thử .UpdateLayout() trên Button, nhưng nó không có bất kỳ hiệu ứng nào. Tôi cũng đã thử System.Windows.Forms.DoEvents() mà thường hoạt động khi sử dụng WinForms, nhưng nó cũng không có hiệu lực.

Trả lời

8

Mã sau sẽ làm những gì bạn đang tìm kiếm. Tuy nhiên tôi sẽ không sử dụng nó. Sử dụng lớp BackgroundWorker cho các hoạt động thời gian dài. Nó rất dễ sử dụng và rất ổn định.
Đây mã:

public static void ProcessUITasks() {    
     DispatcherFrame frame = new DispatcherFrame(); 
     Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate(object parameter) { 
      frame.Continue = false; 
      return null; 
     }), null); 
     Dispatcher.PushFrame(frame); 
    } 

Here bạn sẽ tìm thấy một mẫu về cách sử dụng BackgroundWorker.

+0

Anh ấy khá rõ ràng về việc nhận thức nhưng không sử dụng Dispatcher/Backgroundworker :) – edvaldig

+2

@edvaldig: Tôi đã nhấn mạnh không sử dụng nó, tuy nhiên tôi đã cho anh ta mã anh ấy đang tìm kiếm. Tôi không nghĩ rằng điều này đáng giá -1 từ bạn. Nếu mã của tôi không hoạt động, sau đó cho tôi một -1, nhưng không cho một số lời khuyên bổ sung. Tôi không nghĩ điều này là công bằng. – HCL

+1

Bạn nói đúng, tôi đã quá nhanh về nó, bình luận upvote để bù đắp :) – edvaldig

0

InvalidateVisual(); @HCL là đúng ... không làm điều này

Như bạn nói, tốt hơn là nên bắt đầu sử dụng chủ đề nền/điều phối và giữ cho chuỗi giao diện người dùng bị bỏ chặn. Xem xét xem Reactive Extensions library từ Microsoft để lập trình ui mức không đồng bộ cao

+0

Điều này sẽ không hoạt động. Việc vô hiệu hóa chỉ làm mất hiệu lực vùng được sơn lại. Tuy nhiên nó không phải là bức tranh. – HCL

+0

@HCL, Hoạt động tốt cho tôi, xem tài liệu cho hàm: Vô hiệu hóa hiển thị của phần tử và buộc hoàn thành bố cục mới hoàn thành. OnRender được gọi sau khi chu trình bố trí được hoàn tất. – edvaldig

+0

Bạn có chắc chắn rằng giao diện người dùng của mình bị chặn không? Tôi đã thử nghiệm nó lần cuối theo .net3.5SP1. Tại thời điểm này nó đã không hoạt động. Nếu nó hoạt động ngay bây giờ, họ phải thay đổi hành vi với 4.0. Tuy nhiên, đây sẽ là một bất ngờ lớn đối với tôi. – HCL

0

Trong Windows.Forms, bạn có thể Button.Refresh().

Trong Windows.Forms hoặc WPF, bạn có thể mang lại cho máy bơm thông báo để cho phép vẽ lại. Async/Await được thiết kế để cho phép bạn thực hiện điều này mà không cần phải trả lời câu hỏi của HCL.

Private Async Function Button_OnClick 

    Button.Enabled = False 

    Await Task.Yield 

    [LONG OPERATION] 

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