2009-07-20 33 views
40

Tại sao hộp tin nhắn C# /. NET không phải là phương thức?C#/.NET messagebox không phải là phương thức

Vô tình, nếu hộp thư đi phía sau giao diện người dùng chính của chúng tôi, giao diện người dùng chính không phản hồi, cho đến khi chúng tôi nhấp OK (trên hộp thư của chúng tôi).

Có cách giải quyết nào khác ngoài việc tạo hộp thông báo tùy chỉnh không?

+2

Bạn đang tạo hộp thư trên một chuỗi riêng biệt? – LBushkin

+0

Cả hai đều nằm trong chuỗi riêng biệt. Nó có ảnh hưởng không? – Mahesh

+1

Tôi cũng đã thấy điều này xảy ra. Nó thường là trong một số trường hợp mà không ai có thể nhân đôi. Bạn có thể sao chép nó theo yêu cầu không? –

Trả lời

54

Bạn cần phải gán thuộc tính chủ sở hữu MessageBox để cửa sổ giao diện người dùng chính (xem xét hàm tạo thứ 3).

+5

(Thông thường, điều này chỉ có nghĩa là chuyển trong 'this' làm tham số đầu tiên khi gọi' MessageBox.Show (...) 'từ biểu mẫu của bạn.) –

6

Cửa sổ bật lên được định nghĩa kỹ thuật là hộp bật lên làm gián đoạn luồng ứng dụng bình thường ... không nhất thiết phải nằm trên đầu tất cả các cửa sổ khác để hành vi bạn mô tả là chính xác cho một cửa sổ bật lên phương thức.

Modal Window

Dưới đây là một dự án trên CodeProject mà cố gắng để bắt chước các "luôn luôn trên đầu" chức năng cho một cửa sổ phong cách MessageBox Modal:

CodeProject: TopMost MessageBox

+5

Vấn đề của anh ta không phải là hộp thoại được bao phủ bởi một ứng dụng khác. Nó đang bị ứng dụng gọi điện che phủ. Điều này dẫn đến một ứng dụng không thể được sử dụng, bởi vì hộp thoại không thể đóng được. Không thể đóng hộp thoại vì không thể truy cập được. –

+0

Điểm tốt ... Tôi đã đi với cách tiếp cận này bởi vì nó sẽ giúp cả hai tình huống, nhưng nếu anh ta không quan tâm đến các ứng dụng khác sau đó thiết lập chủ sở hữu là con đường để đi. –

5

Bạn có thể sử dụng tham số chủ sở hữu để chỉ định một đối tượng cụ thể, thực hiện IWin32Window interface, để đặt hộp tin nhắn ở phía trước.

Hộp thông báo là hộp thoại phương thức, có nghĩa là không có đầu vào (bàn phím hoặc nhấp chuột) có thể xảy ra ngoại trừ đối tượng trên biểu mẫu 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.

MessageBox.Show Method

10

Đây là một đơn giản C# mới ứng dụng Windows Forms:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      string message = "You did not enter a server name. Cancel this operation?"; 
      string caption = "No Server Name Specified"; 
      MessageBoxButtons buttons = MessageBoxButtons.YesNo; 
      DialogResult result; 

      // Displays the MessageBox. 
      result = MessageBox.Show(this, message, caption, buttons); 
      if (result == DialogResult.Yes) 
      { 
       // Closes the parent form. 
       this.Close(); 
      } 
     } 
    } 
} 

Như Dusty states in his answer, một hộp thông báo là một hộp thoại modal. Chỉ định thuộc tính 'chủ sở hữu'. Trong ví dụ này, chủ sở hữu được biểu thị bằng từ khóa 'this'.

+0

+1 cho tiếng hét. :) – Dusty

+0

Cũng giống như một lời nhắc nhở, khi đi qua chủ đề đừng quên kiểm tra 'this' cho' InvokeRequired'. Tuy nhiên, bạn nhận được +1 của tôi cho bản demo. – Joel

+1

@ Jelel, tôi cho rằng thực hành không tốt để gọi 'Invoke()' trực tiếp bên trong trình xử lý sự kiện winforms. Winforms và Designer cùng đảm bảo rằng các sự kiện sẽ được kích hoạt trên luồng GUI đúng vì các điều khiển thành viên đều được khởi tạo trên cùng một luồng với 'this'. Tôi thậm chí còn cho rằng, vì việc nhấp vào một 'Nút' yêu cầu chủ sở hữu của nó 'Biểu mẫu' để có tiêu điểm, việc chỉ định' chủ sở hữu' thành 'MessageBox.Show()' là không cần thiết trong ví dụ này. Nó sẽ là cần thiết, nói, trong một xử lý 'Timer.Tick'. Cả hai 'Invoke()' và 'owner' đều được yêu cầu khi' MessageBox.Show() 'được gọi từ một luồng khác. – binki

-2
public static System.Windows.Forms.DialogResult WW_MessageBox(string Message, string Caption, 
     System.Windows.Forms.MessageBoxButtons buttons, System.Windows.Forms.MessageBoxIcon icon, 
     System.Windows.Forms.MessageBoxDefaultButton defaultButton) 
    { 
     System.Windows.Forms.MessageBox.Show(Message, Caption, buttons, icon, defaultButton, 
      (System.Windows.Forms.MessageBoxOptions)8192 /*MB_TASKMODAL*/); 

    } 
+0

Điều này không làm gì khác hơn bình thường. – Andy

0

Tận dụng hộp thông báo xuất hiện trong các chủ đề chính, nếu hình thức của bạn đã được tạo ra từ nó:

private bool ShowMessageBoxYesNo() 
{ 
    if (this.InvokeRequired) 
     return (bool)this.Invoke(new ShowMessageBoxYesNoDelegate(ShowMessageBoxYesNo)); 
    else 
    { 
     DialogResult res = MessageBox.Show("What ?", "Title", MessageBoxButtons.YesNo, MessageBoxIcon.Question); 
     if (res == DialogResult.Yes) 
      return true; 
     else 
      return false; 
    } 
} 
+0

Cách mà 'MessageBox.Show()' đặt chủ sở hữu của nó (khi sử dụng quá tải mà chủ sở hữu không được chỉ định bởi người gọi) là tìm bất kỳ cửa sổ nào trong chuỗi hiện tại được tập trung. Nếu 'Biểu mẫu' của bạn không được tập trung (ví dụ: thu nhỏ) khi bạn gọi' MessageBox.Show() ', 'Hộp thư' của bạn sẽ không tự động được nâng lên khi người dùng cố gắng tăng' Biểu mẫu' của bạn. Gọi 'Invoke()' * only * đảm bảo rằng người dùng không thể tập trung 'Form' của bạn. – binki

7

Để có được hệ thống phương thức MessageBox thiết MessageBoxOptions.DefaultDesktopOnly.

+3

Thông số này dẫn đến hiển thị hộp thông báo ở trên cùng của tất cả các cửa sổ trên màn hình hoạt động. Trong khi đó nó không có chủ sở hữu. Xem chi tiết trong MSDN - http://msdn.microsoft.com/en-us/library/system.windows.forms.messageboxoptions.aspx –

+0

Để làm rõ, tùy chọn này làm cho cửa sổ ở trên đầu của tất cả các cửa sổ chỉ khi chủ sở hữu là vô giá trị. Nếu chủ sở hữu không phải là số không, nó chỉ ở trên đầu chủ sở hữu của nó. –

-2

Hộp thư là một điều khiển cục bộ cục bộ cho máy chủ. Và nó không đáp ứng cho đến khi nhấp vào OK trên hộp thông báo được hiển thị trong máy chủ.

+2

Cụ thể hơn. Những gì chúng ta đang nói đến là các hộp thông báo * phương thức. –

+1

Tôi nghĩ rằng câu hỏi là về winforms, không phải dạng ASP.Net. – binki

0

này đang làm việc cho tôi:

MessageBox.Show(Form.ActiveForm,"Finished processing", "Process finished", , MessageBoxButtons.OK, MessageBoxIcon.Information); 

Form.ActiveForm sẽ cung cấp cho bạn những hình thức đang hoạt động, ngay cả khi bạn đang nâng MessageBox của bạn từ bất kỳ lớp khác.

+1

Tính năng này có hoạt động khi không có biểu mẫu nào đang hoạt động (ví dụ: thu nhỏ) không? Không. Mã này giống hệt với việc gọi 'MessageBox.Show()' mà không chỉ định bất kỳ chủ sở hữu nào, trong bộ kiểm thử nhỏ của tôi. – binki

+0

Tìm kiếm tốt đẹp @binki. Vì vậy, nó hoạt động trong cả hai trường hợp, tức là với Active Form và không có bất kỳ hình thức hoạt động nào ... :) –

+0

Xin lỗi, những gì tôi đang cố gắng nói là chỉ định 'Form.ActiveForm' là vô nghĩa.Giả sử cửa sổ ứng dụng của bạn không được tập trung (ví dụ: thu nhỏ) và sau đó mã của bạn gọi 'MessageBox.Show()' không có chủ sở hữu (giống như gọi 'MessageBox.Show (Form.ActiveForm)'). Sau đó, khi người dùng cố gắng nâng cao cửa sổ chính của ứng dụng, người dùng có thể sẽ tăng cửa sổ ứng dụng của bạn lên trên cùng của hộp thông báo xuất hiện. Sau đó, bạn nhận được tình huống được mô tả trong câu hỏi của OP nơi người dùng cố gắng tương tác với cửa sổ chính của bạn nhưng chỉ nhận được âm "Ding" từ Windows ;-). – binki

0

Những gì tôi thường làm gì nếu tôi có để kích hoạt một MessageBox từ một chủ đề (không phải từ các chủ đề chính) là thế này:

  1. tôi có thể tạo một biến tĩnh với các trường hợp có dạng:

    tin tĩnh Form1 myform;

  2. Từ sợi, tôi gọi các hoạt động để hiển thị MessageBox từ các chủ đề chính:

    myform.BeginInvoke ((MethodInvoker) đại biểu() {MessageBox.Show ("! Process xong", "Process Chủ đề Thông tin ", MessageBoxButtons.OK, MessageBoxIcon.Information);});

Đây chỉ là "công cụ cắt cookie" mà tôi luôn sử dụng và hoạt động hoàn hảo cho tôi.

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