2010-05-14 24 views
6

Tôi gặp sự cố với các hình thức dưới dạng C# .NET. Hãy nói rằng tôi có hình thức chính # 0 (xem hình dưới đây). Biểu mẫu này đại diện cho biểu mẫu đăng ký chính, nơi người dùng có thể thực hiện các hoạt động khác nhau. Tuy nhiên, theo thời gian, có một nhu cầu để mở thêm hình thức phi phương thức để thực hiện bổ sung chức năng ứng dụng chính hỗ trợ nhiệm vụ. Giả sử đây là biểu mẫu # 1 trong hình ảnh. Trên biểu mẫu # 1 này có thể mở thêm vài biểu mẫu bổ sung trên đầu trang (dạng # 2 trong hình), và cuối cùng, có một hộp thoại tiến trình hiển thị tiến trình và trạng thái hoạt động lâu dài, có thể mất từ ​​vài phút đến vài giờ. Vấn đề là hình thức chính # 0 không đáp ứng cho đến khi bạn đóng tất cả các hình thức phương thức (# 2 trong hình ảnh). Tôi cần rằng mẫu chính # 0 sẽ hoạt động trong tình huống này. Tuy nhiên, nếu bạn mở một biểu mẫu không có dạng thức ở dạng # 2, bạn có thể hoạt động với cả hai dạng phương thứC# 2 và biểu mẫu không được tạo mới. Tôi cần hành vi tương tự giữa biểu mẫu chính # 0 và mẫu # 1 với tất cả các biểu mẫu con của nó. Có thể không? Hay tôi đang làm gì sai? Có thể có một số loại workaround, tôi thực sự không muốn thay đổi tất cả các cuộc gọi đến ShowDialog Hiện ...Lập trình WinForms - Vấn đề về hình thức và không phải phương thức

Image http://img225.imageshack.us/img225/1075/modalnonmodalproblem.png

+2

Bạn có yêu cầu tạo biểu mẫu chỉ là phương thức cho một trong các biểu mẫu khác của bạn không? – SLaks

+0

Tôi muốn rằng biểu mẫu chính # 0 sẽ vẫn đáp ứng khi có biểu mẫu không phải là phương thức số 1 với một số biểu mẫu con bổ sung (# 2). – Povilas

Trả lời

12

Biểu mẫu phương thức thực hiện chính xác "phương thức" nghĩa là gì, chúng vô hiệu hóa tất cả các cửa sổ khác trong ứng dụng. Điều đó khá quan trọng, chương trình của bạn đang ở trong tình trạng hơi nguy hiểm. Bạn đã có một đoạn mã đang đợi hộp thoại đóng lại. Những điều thực sự tồi tệ có thể xảy ra nếu những cửa sổ khác không bị vô hiệu hóa. Giống như người dùng có thể bắt đầu lại hộp thoại phương thức, bây giờ mã của bạn được lồng hai lần. Hoặc cô ấy có thể đóng cửa sổ chủ sở hữu của hộp thoại, bây giờ nó đột nhiên biến mất.

Đây là những loại vấn đề chính xác mà bạn gặp phải nếu bạn gọi Application.DoEvents() bên trong một vòng lặp. Đó là một cách để có được một hình thức để hành xử phương thức mà không cần vô hiệu hóa các cửa sổ khác. Ví dụ:

Form2 mDialog; 

    private void button1_Click(object sender, EventArgs e) { 
     mDialog = new Form2(); 
     mDialog.FormClosed += (o, ea) => mDialog = null; 
     mDialog.Show(this); 
     while (mDialog != null) Application.DoEvents(); 
    } 

Đây là nguy hiểm.

Tốt nhất là sử dụng các dạng phương thức theo cách thức chúng được thiết kế để tránh rắc rối. Nếu bạn không muốn một hình thức phương thức thì đơn giản là không làm cho nó phương thức, sử dụng phương thức Show(). Theo dõi sự kiện FormClosing của nó để biết rằng nó sắp đóng cửa:

private void button1_Click(object sender, EventArgs e) { 
     var frm = new Form2(); 
     frm.FormClosing += new FormClosingEventHandler(frm_FormClosing); 
     frm.Show(); 
    } 

    void frm_FormClosing(object sender, FormClosingEventArgs e) { 
     var frm = sender as Form2; 
     // Do something with <frm> 
     //... 
    } 
+0

Cảm ơn câu trả lời của bạn, tôi nghĩ rằng tôi có thể sử dụng một thread GUI riêng biệt, vì form chính # 0 và form # 1 về cơ bản sống cuộc sống của chính họ và không tương tác với nhau. Biểu mẫu số 1 có thể là một ứng dụng riêng biệt. Tôi không thể thay đổi ShowDialog() thành Show() vì tôi cần các biểu mẫu phương thức nhưng chỉ ở dạng ngữ cảnh # 1. Người dùng không thể tiếp tục làm việc với biểu mẫu # 1 (chỉ với biểu mẫu # 1) cho đến khi hình thức phương thức được mở từ biểu mẫu # 1 không bị đóng. – Povilas

3

Việc đầu tiên mà nói đến cái tâm sẽ là một cái gì đó như thế này. Bạn có thể vô hiệu hóa biểu mẫu 1 khi bạn khởi chạy biểu mẫu 2 và sau đó có biểu mẫu 1 xử lý sự kiện đã đóng của biểu mẫu thứ hai để kích hoạt lại chính nó. Bạn sẽ không mở phương thức 2 bằng cách sử dụng hộp thoại hiển thị.

Bây giờ hãy nhớ, từ góc độ người dùng, điều này sẽ khá cồng kềnh, bạn có thể xem xét thực hiện một ứng dụng MDI để có được tất cả các cửa sổ bên trong một vùng chứa duy nhất.

0

Biểu mẫu chính của bạn sẽ không phản hồi cho đến khi mọi hộp thoại phương thức trong cùng một không gian quy trình được đóng lại. Không có công việc xung quanh cho điều đó.

0

Có vẻ với tôi như bạn có thể sử dụng một ứng dụng MDI thiết Form # 0 IsMdiContainer tài sản để thành sự thật.

Sau đó, bạn có thể làm một cái gì đó giống nhau:

public partial class Form0 { 
    public Form0 { 
     InitializeComponent(); 
     this.IsMdiContainer = true; // This will allow the Form #0 to be responsive while other forms are opened. 
    } 

    private void button1_Click(object sender, EventArgs e) { 
     Form1 newForm1 = new Form1(); 
     newForm1.Parent = this; 
     newForm1.Show(); 
    } 
} 

Sử dụng ShowDialog() như bạn đã nêu trong câu hỏi của bạn sẽ làm cho tất cả các hình thức Modal = true.

Theo định nghĩa, một dạng phương thức là:

Khi một hình thức được hiển thị modally, không có đầu vào (bàn phím hoặc click chuột) có thể xảy ra, ngoại trừ các đối tượng về hình thức phương thức. Chương trình phải ẩn hoặc đóng một biểu mẫu phương thức (thường là để phản hồi lại một số hành động của người dùng) trước khi nhập vào biểu mẫu khác có thể xảy ra. Các biểu mẫu được hiển thị theo phương thức thường được sử dụng làm hộp thoại trong một ứng dụng.

Bạn có thể sử dụng thuộc tính này [(Modal)] để xác định xem biểu mẫu mà bạn đã thu được từ phương thức hoặc thuộc tính đã được hiển thị một cách bình thường hay chưa.

Vì vậy, một hình thức phương thức sẽ chỉ được sử dụng khi bạn cần sự hỗ trợ/tương tác ngay lập tức từ người dùng. Sử dụng các hình thức phương thức khác nếu không tin rằng bạn có thể đang chạy sai hướng.

Nếu bạn không muốn biểu mẫu chính của bạn trở thành vùng chứa MDI, thì có thể sử dụng đa luồng là một giải pháp thông qua lớp đơn giản BackgroundWorker là chìa khóa cho những gì bạn muốn đạt được. Như vậy, có vẻ với tôi như một mùi thiết kế ...

  • nó là gì bạn muốn làm, ngoài việc làm hình thức chính của bạn đáp ứng vv
  • gì là nó, bạn phải làm ?

Giải thích bạn phải làm gì, chúng tôi có thể hướng dẫn bạn hoàn toàn về bên phải hoặc ít nhất có thể là hướng tốt hơn.

+0

Cảm ơn câu trả lời của bạn, tôi sẽ cố gắng giải thích tốt hơn. MDI hoặc thay đổi ShowDialog() thành Show() sẽ không giải quyết vấn đề này vì tôi cần các biểu mẫu (trình chỉnh sửa dữ liệu tùy chỉnh) và người dùng không thể tiếp tục cho đến khi chưa hoàn thành. ở dạng ngữ cảnh # 1. Trên form # 1 người dùng đang làm việc với một số dữ liệu mà sau này là cần thiết trên biểu mẫu chính # 0. Về cơ bản, hình thức chính # 0 và hình thứC# 1 sống cuộc sống của chính họ, và hình thứC# 1 có thể là ứng dụng riêng biệt. Từ # 0 đang lấy dữ liệu từ vài đối tượng singleton, trong đó biểu mẫu # 1 đang cập nhật dữ liệu. – Povilas

+0

Đối với một nửa của năm tất cả mọi thứ đã được tốt, nhưng vì yêu cầu mới đổ xô trong tôi có tình huống mà làm việc với một trình soạn thảo dữ liệu tùy chỉnh có thể mất đến vài giờ. Vì vậy, tôi nghĩ rằng tôi có thể sử dụng những gì Hans Passant đang đề xuất - một thread GUI riêng biệt. Và đồng bộ hóa dữ liệu qua vài đối tượng đơn lẻ. – Povilas

-1

Thực ra câu trả lời rất đơn giản. Hãy thử

newForm.showDialog(); 

Điều này sẽ mở một biểu mẫu mới, trong khi biểu mẫu gốc không thể truy cập được.

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