2010-06-21 28 views
10

Trong ứng dụng C# của tôi, tôi có một hộp thoại tùy chọn có thể được mở từ một lệnh menu.Làm cách nào để tạo một mẫu đơn lẻ (không phải ứng dụng)?

Tôi muốn đảm bảo rằng hộp thoại tùy chọn chỉ có một cá thể (người dùng không thể mở nhiều cửa sổ tùy chọn tại một thời điểm nhất định) mà không làm cho nó phương thức.

Ngoài ra nếu người dùng đã mở cửa sổ này và nhấp vào mục menu để mở lại, ứng dụng chỉ làm cho biểu mẫu đã hiển thị trở thành cửa sổ trên cùng.

Có ai có thể chỉ cho tôi chỉ đường về cách hoàn thành các tác vụ này không?

Cảm ơn bạn rất nhiều.

Trả lời

6

Bạn sẽ cần mẫu này là tài sản

Form1 myForm = null; 
private void Form1_FormClosed(object sender, FormClosedEventArgs e) 
{ 
    myForm = null; 
} 

private void ShowForm() 
{ 
    if (myForm != null) 
    { 
     myForm.BringToFront(); 
    } 
    else 
    { 
     myForm = new Form1; 
     myForm.Show(); 
    } 
} 
+0

Chỉ cần khai báo myForm là tĩnh để có thể truy cập bằng mẫu tùy chọn FormClosed của tôi (để làm cho myForm = null một lần nữa). – RHaguiuda

17

Vâng, cách đơn giản nhất là có một trường tĩnh lưu trữ một tham chiếu đến một cá thể hoặc null và sau đó là một phương thức để lấy nó hoặc tạo một phương thức mới.

Lưu ý rằng điều này không phải là giống như làm cho nó trở thành một singleton - bởi vì tôi giả sử nếu biểu mẫu được đóng, bạn muốn tạo một phiên bản mới vào lần sau. (Cách khác - giấu nó và tái sử dụng nó - được thể hiện trong câu trả lời STO của.) Bạn có thể muốn một cái gì đó như thế này:

public class OptionsDialog : Form 
{ 
    private static OptionsDialog openForm = null; 

    // No need for locking - you'll be doing all this on the UI thread... 
    public static OptionsDialog GetInstance() 
    { 
     if (openForm == null) 
     { 
      openForm = new OptionsDialog(); 
      openForm.FormClosed += delegate { openForm = null; }; 
     } 
     return openForm; 
    } 
} 

Bạn có thể muốn thực hiện phương pháp này thực hiện "mang nó đến phía trước" bước cũng , tất nhiên.

+0

Xin chào @Jon, bạn có thể cung cấp một ví dụ không? – RHaguiuda

+0

@RHaguiuda: Bạn muốn gì ngoài mã tôi đã cung cấp? –

+1

Hmm, tôi có thể thấy yêu cầu đó đến từ đâu, đó không phải là bài đăng trông như ban đầu. Súng nhanh nhất trong thủ thuật phương Tây? –

2

bạn có thể sử dụng mã như thế này:

private MyDialogForm _FormInstance; 

public void ShowOptions() 
{ 
    if (_FormInstance == null) 
    { 
     _FormInstance = new MyDialogForm(); 
     _FormInstance.FormClosing += (s,e) => 
     { 
      e.Cancel = true; 
      _FormInstance.Hide(); 
     } 
     } 
    _FormInstance.Show(); 
} 
0

tôi giả sử bạn có ít nhất hai hình thức. Một hình thức, gọi nó là frmMain, cho phép bạn mở frmOptions. Trong frmMain, thêm một biến kiểu frmOptions như thế này:

public partial class frmMain : Form 
{ 
    private frmOptions optionsInstance = null; 
    ... 

trong thói quen mở ra hộp thoại Options, thêm này:

if (optionsInstance == null || !optionsInstance.Visible) 
{ 
    optionsInstance = new frmOptions(); 
    optionsInstance.Show(); 
} 

Khi frmOptions đóng lại, optionsInstance sẽ không được null, vì vậy đó là tại sao bạn kiểm tra xem nó có hiển thị trước khi instantiating một cá thể frmOptions hay không.

Nếu cách này không hiệu quả với bạn, bạn có thể thử một mutex, nhưng đó có thể là quá mức cần thiết.

10

Bạn cần phải ngăn chặn biểu mẫu đóng. Nếu không, mẫu đơn sẽ được xử lý và trở nên không sử dụng được. Bạn có thể làm điều này bằng cách thực hiện các sự kiện FormClosing:

protected override void OnFormClosing(FormClosingEventArgs e) { 
     if (e.CloseReason == CloseReason.UserClosing) { 
      this.Hide(); 
      e.Cancel = true; 
     } 
    } 

Để làm cho nó một singleton, chỉ cần theo dõi thời gian tuổi thọ của mẫu tại lớp mẫu chính của bạn:

frmOptions options; 

    private void btnShowOptions_Click(object sender, EventArgs e) { 
     if (options == null) { 
      options = new frmOptions(); 
      // To make absolutely sure: 
      options.FormClosed += (o, ea) => options = null; 
     } 
     else { 
      options.WindowState = FormWindowState.Normal; 
     } 
     options.Show(); 
    } 
+0

cảm ơn cho câu trả lời này, bạn có thể giải thích '(o, ea) =>' Tôi biết rằng bạn thiết lập các hình thức trở lại null nhưng tôi không hiểu cú pháp này – meda

+2

Nó là một biểu thức lambda. Tôi thường viết (người gửi, e) => nhưng những tên đó đã được sử dụng. –

+0

Cảm ơn bạn đã làm rõ – meda

0

Dựa trên Jon Skeet's answer, Tôi đang sử dụng mã sau đây để hiển thị biểu mẫu dưới dạng hộp thoại phương thức.

 if (this.aboutForm == null) 
     { 
      this.aboutForm = new AboutForm(); 
      this.aboutForm.FormClosed += (sender2, e2) => { this.aboutForm = null; }; 
      this.aboutForm.ShowDialog(this); 
     } 
     else 
     { 
      this.aboutForm.Focus(); 
     } 

Tôi phải làm điều này vì tôi có mục trình đơn để hiển thị biểu mẫu Giới thiệu trong menu của biểu mẫu chính và trong menu ngữ cảnh của biểu tượng thông báo.Nếu tôi mở biểu mẫu Giới thiệu bằng cách sử dụng menu của biểu mẫu chính, tôi vẫn có thể mở một phiên bản khác bằng cách sử dụng mục menu ngữ cảnh của biểu tượng thông báo.

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