トップ回答者
プログレスバー用のフォームが操作不能になる

質問
-
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();
}
}
}----------------------------------------------------------------------------
回答
-
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秒毎に処理をするという意味でしょうから、タイマーの使用を検討してください。
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年2月21日 0:26
- 回答としてマーク chamobns 2017年2月21日 4:20
すべての返信
-
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秒毎に処理をするという意味でしょうから、タイマーの使用を検討してください。
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年2月21日 0:26
- 回答としてマーク chamobns 2017年2月21日 4:20
-
佐祐理 様
ご返信ありがとうございます。
イベント処理中に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++;
}
}
}
}----------------------------------------------------------------------------