none
メッセージを最前面にかつ元のフォームの動作を停止しないで表示する方法について RRS feed

  • 質問

  • いつもお世話になっております。
    初歩的なことかと思いますがメッセージボックスの表示について教えて頂きたいと思います。

    プログラムは、フォーム上に時計が表示されており1秒毎にカウントしています。
    「時間を設定するボックス」、「表示する文字のボックス」等が対でそれぞれ10個あります。

    時間を表示するボックスにセットした時間になったら、「表示する文字ボックス」に入力し
    た文字のメッセージをウィンドウの最前面にメッセージボックスで表示し、操作者が「OK」
    ボタンをクリックするとそのメッセージボックスを閉じるようにしたいと考えています。

    (例1)MessageBox.Show(Message_textBox1.Text, "Alarm Clock");
    のようにすれば、メッセージを表示することはできますが、他のアプリケーションを利用して
    いる場合にはそのウィンドウの下に隠れて表示される場合がありNGです。

    (例2)MessageBox.Show(alarm_Message_textBox1.Text, "O's Alarm Clock", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
    のようにすれば、最前面に表示されますが元のフォームの時計が止まったままになりこれもNGです。

    「表示する文字ボックス」は、10個ありますのでそれぞれ「時間を設定するボックス」に指
    定した時間の到来により判断して該当の文字を表示するようにする予定です。

    ここでは、例として、1つのメッセージ(Message_textBox1.Text)の内容を表示して「OK」
    ボタンで閉じる方法についてお教え頂きたくよろしくお願いいたします。

            private void timer1_Tick(object sender, EventArgs e)
            {
                //label1は常に時間を更新する
                label1.Text = DateTime.Now.ToString("yyyy年 MM月 dd日 (ddd)  HH時   mm分   ss秒");      //ToString("yyyy年MM月dd日 HH時mm分 ss秒fffms")

                if ((DateTime.Now >= a1date) && (Setting1 == true) && (Play == 0))
                {
                    setLabel1.Text = "経過";
                    player.Play();
                    Play = 1;
                    alarm1Enabled = false;
                    alarmcheckBox1.Checked = alarm1Enabled;

                    MessageBox.Show(Message_textBox1.Text, "Alarm Clock");
                    MessageBox.Show(Message_textBox1.Text, "Alarm Clock", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                }
            }

    2011年6月26日 12:13

回答

  • MessageBoxを表示した段階でコードの実行がそこで止まってしまいますから、label1.Textの時間が更新されなくなってしまいます。
    現状のコードですとユーザーが確認のためにOKボタンを押すだけのようですから、MessageBoxを止め、代わりにFormをTopMost=trueの状態で表示してメッセージを知らせてはいかがでしょうか? ただし、このフォームが開かれているかどうかという状態を何らかの方法で管理しなければ、何度も開いてしまうことになりますので注意して下さい。

    さて、刻々と変わる時刻の表示は、根本的には別スレッドで行うのが良いと思います。

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答としてマーク 山本春海 2011年7月4日 8:17
    2011年6月26日 13:05
    モデレータ
  • 以下の方法で表示できるようになりました。
    メッセージの表示ひとつにしても、奥が深いです。
    いろいろチャレンジして覚えていくのが必要ですね。

    //Form1.cs
    Form2 f = new Form2();
    f.Owner = this;
    f.TopMost = true;
    f.Text = "Alarm Clock";
    f.GetOtherFormTextBox();
    f.Show();


    //Form2.cs
    public partial class Form2 : Form
    {
            public Form2()
            {
                InitializeComponent();
            }
            public void GetOtherFormTextBox()
            {
                label1.Text = ((Form1)this.Owner).Message_textBox1.Text;
            }

            private void CloseButton_Click(object sender, EventArgs e)
            {
                this.Close();
            }

    }

    • 回答としてマーク 山本春海 2011年7月4日 8:17
    2011年6月26日 15:27

すべての返信

  • MessageBoxを表示した段階でコードの実行がそこで止まってしまいますから、label1.Textの時間が更新されなくなってしまいます。
    現状のコードですとユーザーが確認のためにOKボタンを押すだけのようですから、MessageBoxを止め、代わりにFormをTopMost=trueの状態で表示してメッセージを知らせてはいかがでしょうか? ただし、このフォームが開かれているかどうかという状態を何らかの方法で管理しなければ、何度も開いてしまうことになりますので注意して下さい。

    さて、刻々と変わる時刻の表示は、根本的には別スレッドで行うのが良いと思います。

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答としてマーク 山本春海 2011年7月4日 8:17
    2011年6月26日 13:05
    モデレータ
  • お返事ありがとうございます。

    先のコードのif文の
    MessageBox.Show(・・・
    に代えて以下のフォーム表示に関するコードを記述してみました。

    Form2 f = new Form2();
    f.Owner = this;
    f.TopMost = true;
    f.Show();

    しかし、何の表示も無いボックスは表示されますが、元のフォームからの
    メッセージ(Message_textBox1.Text)の内容の表示方法、データの
    引継ぎ方法が分かりません。
    Form2は、メニューの「プロジェクト」「コンポーネントの追加」「windowsフォーム」から追加し、
    コントロールのlabelを(Name)label1で設定しています。

    Form1のデータをForm2へ引き継いで、メッセージボックスのように表示させる方法についてお教えください。

    時刻表示の別スレッド化?については、「別スレッド」をキーにして調べてみます。
    また別途よろしくお願いします。

    2011年6月26日 13:52
  • 以下の方法で表示できるようになりました。
    メッセージの表示ひとつにしても、奥が深いです。
    いろいろチャレンジして覚えていくのが必要ですね。

    //Form1.cs
    Form2 f = new Form2();
    f.Owner = this;
    f.TopMost = true;
    f.Text = "Alarm Clock";
    f.GetOtherFormTextBox();
    f.Show();


    //Form2.cs
    public partial class Form2 : Form
    {
            public Form2()
            {
                InitializeComponent();
            }
            public void GetOtherFormTextBox()
            {
                label1.Text = ((Form1)this.Owner).Message_textBox1.Text;
            }

            private void CloseButton_Click(object sender, EventArgs e)
            {
                this.Close();
            }

    }

    • 回答としてマーク 山本春海 2011年7月4日 8:17
    2011年6月26日 15:27