2011-02-08 29 views
8

Tôi đã tìm kiếm một tấn, nhưng tôi không thể tìm thấy bất cứ điều gì liên quan đến vấn đề cụ thể của tôi.Ứng dụng biểu mẫu Windows C# - Cập nhật GUI từ một chuỗi và lớp khác?

Tôi muốn có thể cập nhật biểu mẫu MainUI của tôi từ một lớp khác (SocketListener) và trong đó tôi có một luồng xử lý mạng (clientThread). Ngay bây giờ tôi có thể chạy các kết quả đầu ra đơn giản từ chuỗi mạng chẳng hạn như ghi vào đầu ra trình gỡ rối và tạo một MessageBox.

Nhưng những gì tôi thực sự muốn làm là có thể gọi mã từ clientThread sẽ làm việc trên trường hợp MainUI của tôi. Tôi có thể làm cái này như thế nào?

Ngoài ra, nếu có ai muốn các phần cụ thể của mã thì tôi có thể đăng nó để giúp bạn hiểu rõ hơn về những gì tôi đang yêu cầu.

Trân trọng!

Trả lời

17

Kiểm tra InvokeRequired của lớp Control và nếu đúng, hãy gọi số Invoke và chuyển vào đại biểu (thường là một phương thức ẩn danh) thực hiện những gì bạn muốn thực hiện trên chuỗi của khách hàng.

Ví dụ:

public void DoWork(Form form) 
{ 
    if (form.InvokeRequired) 
    { 
     // We're on a thread other than the GUI thread 
     form.Invoke(new MethodInvoker(() => DoWork(form))); 
     return; 
    } 

    // Do what you need to do to the form here 
    form.Text = "Foo"; 
} 
+0

Vì tôi đang ở trong một lớp khác với UI, làm cách nào để lấy biến "form" trỏ tới biểu mẫu đang chạy để chuyển nó tới DoWork? –

+0

Chẳng phải một số đường cú pháp giống như AutoProperty có tốt cho loại bản mẫu này không? – MusiGenesis

+1

@firstEncounter: bạn có thể thêm một hàm tạo vào lớp của bạn để lấy một 'Biểu mẫu' làm tham số, sau đó lưu trữ tham chiếu trong một biến cấp lớp. – MusiGenesis

4

Vâng, bạn có thể thêm một constructor cho lớp của bạn mà có dạng MainUI như một tham số. Đó là cách nhanh chóng để làm điều đó, nhưng nó giới thiệu một sự phụ thuộc "lạc hậu" từ lớp của bạn đến MainUI, trong lý thuyết, không có sự phụ thuộc là bắt buộc.

Thay vào đó, tôi khuyên bạn nên thêm sự kiện công khai vào lớp học của bạn để biểu mẫu MainUI có thể đăng ký. Khi lớp của bạn cần cập nhật MainUI (hoặc điều khiển trong MainUI), lớp sẽ chỉ đơn giản là "nâng cao" sự kiện. Điều này sẽ gọi phương thức MainUI mà nó đã đăng ký tại thời điểm đăng ký. Vì nó là một phương thức của biểu mẫu MainUI, tất cả những gì bạn phải làm là cập nhật các điều khiển thích hợp trên biểu mẫu, đảm bảo lấy thuộc tính InvokeRequired của mỗi điều khiển trong tài khoản.

Và khi làm điều đó, đây là cấu trúc tôi đã sử dụng trong tất cả mã của mình.

class NetworkEventArgs : EventArgs { /* defined class here */ } 
private void NetworkEventHandler(object sender, NetworkEventArgs e) 
{ 
    Invoke((MethodInvoker) delegate { 
     myTextBox.Text = e.Message; 
    } 
} 

Tôi đã dựa trên mục nhập blog here. Tôi đã không có cách tiếp cận này thất bại cho tôi, vì vậy tôi thấy không có lý do để làm phức tạp mã của tôi với một kiểm tra đệ quy của tài sản InvokeRequired.

+0

Cách cấu trúc mã của tôi thực sự hiệu quả với tôi. Tôi chỉ muốn thêm tôi đã gặp rắc rối với Invoke/MethodInvoker, GUI của tôi sẽ treo. Tôi đã thay đổi nó thành BeginInvoke (MyDelegate mới (MyDelegateMethod), myParam); Hoạt động tốt ngay bây giờ. –

0

bạn có thể xác định một sự kiện lớp clientThread bạn

và xử lý nó trong mainform khi clientThread cần mainform biết để làm một cái gì đó (như cập nhật một số tình trạng kiểm soát) bạn nên Cháy sự kiện

nên mainform được paramter from event và gọi hàm update

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