画面の再描画するメソッドとしてUpdate() Refresh() Invalidate()メソッドがあります。それぞれの違いを見てみます。
メソッド | 動作 |
---|---|
Update | 無効領域(画面更新が必要な領域)を再描画します |
Invalidate | 無効領域を(画面更新が必要な領域)を設定します |
Refresh | クライアント領域全体を無効領域に設定し、再描画します。 |
Invalidateで設定した無効領域(画面更新が必要な領域)を再描画します。
無効領域を(画面更新が必要な領域)を設定します。invalidateを引数なしで呼び出した場合は、子コントロールを含まないクライアント領域を無効領域に設定します。再描画のメッセージを送信するため、Updateメソッドを呼び出さなくてもApplication.DoEvents呼び出し時やアイドル時に画面更新がされます。
子コントロールを含むクライアント領域全体を無効領域に設定し、すぐに再描画します。
以下は等価のコードです
Invalidate(true);
Update();
と
Refresh();
は等しいです。int型のカウンタをPaintBoxに描画するコードがあります。
private int counter = 0;
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawString(counter.ToString(), this.Font, Brushes.Black, 0, 0);
}
Button1に以下のコードを実装し、実行し、ボタンを押した場合画面の更新はされません。(ウィンドウが再描画されない前提)
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++) {
counter++;
System.Threading.Thread.Sleep(1000);
}
}
Button1に以下のコードを実装し、実行しボタンを押した場合画面の更新はされません。Windows7以降ではフォームに覆い隠された場合でも再描画しません。フォームがリサイズされ文字を描画する部分がウィンドウの外側になってしまい、その後再びフォームの内部になった場合には再描画されます。Invalidate()でフォーム全体が無効領域になっているためフォームの再描画が必要な状況になった場合には再描画されます。
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++) {
counter++;
this.Invalidate();
System.Threading.Thread.Sleep(1000);
}
}
下記のコードの場合はループ実行中には画面の更新はされません。ループを抜けた後pictureBox1のPaintイベントが発生しpictureBox1が更新されます。
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++) {
counter++;
pictureBox1.Invalidate();
System.Threading.Thread.Sleep(1000);
}
}
この場合はループ実行中には画面の更新はされません。ループを抜けた後でも、Windows7以降ではフォームに覆い隠された場合でも再描画しません。フォームがリサイズされ文字を描画する部分がウィンドウの外側になってしまい、その後再びフォームの内部になった場合や、ウィンドウを移動させ画面外にはみ出させ、再び画面内に移動させた場合には再描画されます。
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++) {
counter++;
this.Update();
System.Threading.Thread.Sleep(1000);
}
}
この場合はループ実行中には画面の更新はされません。ループを抜けた後でも、Windows7以降ではフォームに覆い隠された場合でも再描画しません。フォームがリサイズされ文字を描画する部分がウィンドウの外側になってしまい、その後再びフォームの内部になった場合や、ウィンドウを移動させ画面外にはみ出させ、再び画面内に移動させた場合には再描画されます。
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++) {
counter++;
pictureBox1.Update();
System.Threading.Thread.Sleep(1000);
}
}
この場合はループ実行中に画面の更新がされます。
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++) {
counter++;
this.Refresh();
System.Threading.Thread.Sleep(1000);
}
}
この場合はループ実行中に画面の更新がされます。
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++) {
counter++;
pictureBox1.Refresh();
System.Threading.Thread.Sleep(1000);
}
}
この場合はループ実行中には画面の更新はされません。ループを抜けた後でも、Windows7ではフォームに覆い隠された場合でも再描画しません。フォームがリサイズされ文字を描画する部分がウィンドウの外側になってしまい、その後再びフォームの内部になった場合や、ウィンドウを移動させ画面外にはみ出させ、再び画面内に移動させた場合には再描画されます。
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++) {
counter++;
this.Invalidate();
this.Update();
System.Threading.Thread.Sleep(1000);
}
}
この場合はループ実行中には画面の更新がされます。Invalidateの引数で子コントロールも無効に設定したためです。
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++) {
counter++;
this.Invalidate(true);
this.Update();
System.Threading.Thread.Sleep(1000);
}
}
この場合はループ実行中には画面の更新がされません。Invalidateの引数で子コントロールも無効に設定したのみで、画面の更新を要求するUpdate()メソッドを呼び出さないためです。
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++) {
counter++;
this.Invalidate(true);
System.Threading.Thread.Sleep(1000);
}
}
この場合はループ実行中には画面の更新はされます。Invalidateの引数で子コントロールも無効に設定したのみで、画面の更新を要求するUpdate()メソッドを呼び出さないですが、Application.DoEvents()でキューにたまっている描画要求が処理されるため、ループを実行中にフォームの再描画がされます。
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++) {
counter++;
this.Invalidate(true);
System.Threading.Thread.Sleep(1000);
Application.DoEvents();
}
}
この場合はループ実行中に画面の更新がされます。
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++) {
counter++;
pictureBox1.Invalidate();
pictureBox1.Update();
System.Threading.Thread.Sleep(1000);
}
}