4

モーダルダイアログが開いているときにアプリケーションのフォームをプログラムで最小化すると、そのモーダルダイアログは閉じられます。

ただし、MessageBoxが開いているときにアプリケーションのフォームをプログラムで最小化すると、MessageBoxは閉じられません(つまり、アプリケーションを通常のウィンドウ状態に復元しても、メッセージボックスは表示されたままになります)。

違いを示すサンプルコードは次のとおりです。

    public partial class Form1 : Form
    {
        // ... 

        private void showMessageBoxBtn_Click(object sender, EventArgs e)
        {
            timer1.Start();

            // This MessageBox does *not* get closed when the WindowState of Form1 is set to minimized in timer1_Tick
            MessageBox.Show(this, "MessageBox");
        }

        private void formShowDialogBtn_Click(object sender, EventArgs e)
        {
            timer1.Start();

            // This form gets closed when the WindowState of Form1 is set to minimized in timer1_Tick
            Form2 form2 = new Form2();
            form2.ShowDialog(); 
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            WindowState = FormWindowState.Minimized;
            timer1.Stop();
        }
    }

質問:

フォームをメッセージボックスのように動作させる方法はありますか?

4

5 に答える 5

8

あなたが見ているのは、ダイアログの使いやすさの問題に対処するためにWinformsに組み込まれている対抗策の副作用であり、MessageBox()関数にはない対抗策です。それらはおそらく、元々Winformsの重要なターゲットオペレーティングシステムであったWindows 98との関連性が高かったのですが、私が正確に覚えるにはあまりにも昔のことです。

重要なユーザビリティの問題は、ダイアログを表示して最小化したときに何が起こるかです。ダイアログがアプリ内の他のすべてのウィンドウを無効にするため、それらをアクティブにすることはできなくなります。ダイアログのShowInTaskbarプロパティをfalseに設定する必要があります。ユーザーに問題が発生しました。ダイアログに戻る簡単な方法はありません。クリックするものはありません。

Winformsは、ダイアログを自動的に閉じることにより、このトラップを回避します。お分かりのように、MessageBoxはこれを行いません。これも合理的に行うことはできません。「ダイアログがキャンセルされました」というステータスコードを返す良い方法がありません。

注目すべきは、このトラップがまだ部分的に存在していることです。Win8マシンでは、無効にしたフォームのタスクバーボタンをクリックして、フォアグラウンドに戻すことができます。ただし、メッセージボックスではなく、無効になっているフォームがアクティブになります。そこにある主要なUING集であり、メッセージボックスがそのフォームの背後にある場合は厄介です。

だからあなたの質問に答えるために:いいえ。機能であり、バグではありません。

于 2013-01-25T00:11:59.443 に答える
1

まず、メソッドのスコープ外でフォーム変数を宣言してForm2、メソッドから到達できるようにしtimer1_tickます。次に、Timerチェックマークが付いたら、メインフォームを最小化しますが、モーダルダイアログを表示してから最小化します。

これを試して:

Form2 form2;

private void timer1_Tick(object sender, EventArgs e)
{
    WindowState = FormWindowState.Minimized;
    form2.Show();
    form2.WindowState = FormWindowState.Minimized;
    timer1.Stop();
}
于 2013-01-25T07:50:39.853 に答える
0

マット、

変更してみてください:

form2.ShowDialog();

form2.Show(this);

これはあなたが探している行動ですか?

于 2013-01-23T02:58:42.770 に答える
0

あなたはこのようなことを試すことができます:

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;
using System.Runtime.InteropServices;

namespace WindowsFormsApplication37
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
        public static extern IntPtr GetParent(IntPtr hWnd);

        Form2 form2 = null;
        IntPtr parent = IntPtr.Zero;

        public Form1()
        {
            InitializeComponent();
        }

        private void formShowDialogBtn_Click(object sender, EventArgs e)
        {
            timer1.Start();

            // This form gets closed when the WindowState of Form1 is set to minimized in timer1_Tick
            form2 = new Form2();
            form2.ShowDialog();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            WindowState = FormWindowState.Minimized;
            timer1.Stop();
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.parent = GetParent(form2.Handle);
                SetParent(form2.Handle, IntPtr.Zero);
                form2.Hide();
            }
            else
            {
                SetParent(form2.Handle, this.parent);
                form2.ShowDialog();
            }
        }
    }
}

これはややハックであることに注意してください。結果については完全にはわかりません。批判は受け入れられます:)

于 2013-01-25T14:08:22.827 に答える
0

設定した場合

Visible = true;

プログラムで所有者を最小化した直後のモーダルフォームでは、モーダルフォームはOSによって強制終了されません。

それで

ownerForm.WindowState = FormWindowState.Minimized;

モーダルフォームを殺します。だが

ownerForm.WindowState = FormWindowState.Minimized;
modalForm.Visible = true;

それを殺すことはありません。

于 2014-04-07T02:16:43.823 に答える