none
プログレスバー用のフォームが操作不能になる RRS feed

  • 質問

  • VisualStudio2015(.NETFramework4.6)でWindowsフォームアプリを作成しています。

    Form1には実行ボタン(btnExec)を1つだけ配置

    Form2にはプログレスバーとキャンセルボタン(btnCancel)を1つ配置

    Form1の実行ボタンを押すとForm2が開いてプログレスバーを1から10(100%)までカウントアップし、

    10になったらForm2を閉じるというコードを書きました。

    カウントアップの途中でForm2を閉じたくなった時用にキャンセルボタンを配置したのですが、

    Form2自体が操作不能でキャンセルボタンも×ボタンも押せません。(Form2の移動も出来ません)

    この現象は何が原因で解決方法はどうしたら良いのか、ご存知の方がいましたら教えていただけると幸いです。

    Form1.cs

    ----------------------------------------------------------------------------

    using System;
    using System.Windows.Forms;
    using System.Threading;

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

            private void btnExec_Click(object sender, EventArgs e)
            {
                var f = new Form2();
                f.Show();
                f.UpdateControl(); // Form2表示時に正常に表示されない事象の対策
                for (int i = 1; i < 11; i++)
                {
                    Thread.Sleep(1000);
                    f.CountUp(i);
                }
                f.Close();
            }
        }
    }

    ----------------------------------------------------------------------------

    Form2.cs

    ----------------------------------------------------------------------------

    using System;
    using System.Windows.Forms;

    namespace WindowsFormsApplication1
    {
        public partial class Form2 : Form
        {
            internal Form2()
            {
                InitializeComponent();
                progressBar1.Minimum = 0;
                progressBar1.Maximum = 10;
            }

            internal void UpdateControl()
            {
                btnCancel.Update();
                progressBar1.Update();
            }

            internal void CountUp(int pval)
            {
                progressBar1.Value = pval;
            }

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

    ----------------------------------------------------------------------------

    2017年2月20日 5:25

回答

  • private void btnExec_Click(object sender, EventArgs e)
    {
      var f = new Form2();
      f.Show();
      f.UpdateControl(); // Form2表示時に正常に表示されない事象の対策
      for (int i = 1; i < 11; i++)
      {
        Thread.Sleep(1000);
        f.CountUp(i);
      }
      f.Close();
    }

    この部分ですが、イベント処理中にSleepしてはいけません。Sleep中にGUI操作ができなくなります。「Form2表示時に正常に表示されない事象」もこれが原因です。

    1秒毎に処理をするという意味でしょうから、タイマーの使用を検討してください。

    2017年2月20日 5:37

すべての返信

  • private void btnExec_Click(object sender, EventArgs e)
    {
      var f = new Form2();
      f.Show();
      f.UpdateControl(); // Form2表示時に正常に表示されない事象の対策
      for (int i = 1; i < 11; i++)
      {
        Thread.Sleep(1000);
        f.CountUp(i);
      }
      f.Close();
    }

    この部分ですが、イベント処理中にSleepしてはいけません。Sleep中にGUI操作ができなくなります。「Form2表示時に正常に表示されない事象」もこれが原因です。

    1秒毎に処理をするという意味でしょうから、タイマーの使用を検討してください。

    2017年2月20日 5:37
  • 佐祐理 様

    ご返信ありがとうございます。

    イベント処理中にSleepしてはいけなかったのですね!

    知識不足で恥ずかしいばかりです。

    タイマーを使用した所、プログレスバーは正常に動き、

    Form2表示が正常に表示されないという点も解決されました!

    Form1.cs

    ----------------------------------------------------------------------------

    using System;
    using System.Windows.Forms;
    using System.Threading;

    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            private int counter;
            private Form2 f = new Form2();

            public Form1()
            {
                InitializeComponent();
                timer1.Interval = 1000;
                counter = 0;
            }

            private void btnExec_Click(object sender, EventArgs e)
            {
                f.Show();
                timer1.Enabled = true;
                timer1.Tick += new EventHandler(this.CountUp);
            }

            private void CountUp(object sender, EventArgs e)
            {
                if (counter >= 10)
                {
                    timer1.Enabled = false;
                    counter = 0;
                    f.Close();
                }
                else
                {
                    f.CountUp();
                    counter++;
                }
            }
        }
    }

    ----------------------------------------------------------------------------

    2017年2月21日 4:29