C#/。NETメッセージボックスがモーダルではないのはなぜですか?
誤って、メッセージボックスがメインUIの背後にある場合、(メッセージボックスで)[OK]をクリックするまで、メインUIは応答しません。
カスタムメッセージボックスを作成する以外の回避策はありますか?
メインUIウィンドウにMessageBox所有者プロパティを割り当てる必要があります(3番目のコンストラクターを見てください)。
これは、単純なC#の新しいWindowsフォームアプリケーションです。
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();
}
}
}
}
Dustyは答えで述べています のように、メッセージボックスはモーダルダイアログです。 「所有者」プロパティを指定します。この例では、所有者はキーワード「this」で示されています。
システムモーダルメッセージボックスを設定するには、MessageBoxOptions.DefaultDesktopOnlyを設定します。
モーダルポップアップは、技術的にはアプリケーションの通常のフローを中断するポップアップボックスとして定義されます...必ずしも他のすべてのウィンドウの最上部にとどまるものではないため、記述している動作はモーダルポップアップに対して正しいです。
これは、MessageBoxスタイルのモーダルウィンドウの「常に手前にある」機能を模倣しようとするCodeProjectのプロジェクトです。
Ownerパラメーターを使用して、 IWin32Windowインターフェイス を実装する特定のオブジェクトを指定し、メッセージボックスを前に配置できます。
メッセージボックスはモーダルダイアログです。つまり、モーダルフォーム上のオブジェクトを除き、入力(キーボードまたはマウスのクリック)を行うことはできません。プログラムは、別のフォームへの入力が発生する前に、モーダルフォームを非表示または閉じる必要があります(通常は、何らかのユーザーアクションに応答して)。
メインスレッドからではなく、別のスレッドからMessageBoxをトリガーする必要がある場合に通常行うことは次のとおりです。
フォームインスタンスを使用して静的変数を作成します。
プライベート静的Form1 myform;
スレッドから、メインスレッドからMessageBoxを表示する操作を呼び出します。
myform.BeginInvoke((MethodInvoker)delegate(){MessageBox.Show( "Process finished!"、 "Thread Process Information"、MessageBoxButtons.OK、MessageBoxIcon.Information);});
これは私がいつも使用する「クッキーカッター」であり、私にとって完璧に機能します。
フォームが作成されている場合、メッセージボックスをメインスレッドに表示します。
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;
}
}
これは私のために働いています:
MessageBox.Show(Form.ActiveForm,"Finished processing", "Process finished", , MessageBoxButtons.OK, MessageBoxIcon.Information);
Form.ActiveFormは、他のクラスからMessageBoxを上げる場合でも、現在アクティブなフォームを提供します。