Refresh、Update、Invalidateメソッドの違いControlクラスのRefresh、Update、Invalidateメソッドは主にコントロールの再描画を促すために使用されますが、これらの違いはヘルプを読んだだけでは非常に分かりにくいです。 ヘルプによると、これらのメソッドは次のように説明されています。
これらのメソッドが実際に何をしているのか調べるには、「Reflector for .NET」などの逆アセンブラを使ってDecompileすればよいでしょう。その結果、次のようなことが分かります。 まず、Refreshメソッドは、Invalidateメソッド(パラメータはTrue)を呼び出した後、さらにUpdateメソッドを呼び出しているだけです。 また、Invalidateメソッドは、Win32 APIのRedrawWindow(子コントロールを再描画する時)または、InvalidateRect関数を呼び出しており、Updateメソッドは、Win32 APIのUpdateWindow関数を呼び出しているらしいということが分かります。 つまり、Invalidateメソッドはアプリケーションキューが空になった時にコントロールを再描画し、Updateメソッドはアプリケーションキューが空でなくても再描画すべき領域があるならばすぐに再描画し、Refreshはアプリケーションキューが空でなくてもコントロールとその子コントロールをすぐに再描画するということになります。 言葉だけでは分かりにくいので、実際のコードでその動作を確認してみましょう。次のサンプルは、Windowsフォーム(Form1)にボタンを4つ配置し、これらをクリックすると、フォームに0から10までの数字が1秒おきにカウントアップして表示されるようにしたものです。4つのボタンはそれぞれカウンターをインクリメントした後にRefresh、Update、Invalidateメソッドを呼び出す(あるいは呼び出さない)という違いがあります。 [VB.NET] 'カウンターの値 Private counter As Integer = 0 'Button1のクリックイベントハンドラ Private Sub Button1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Button1.Click Dim i As Integer For i = 0 To 9 'カウンターを増やす counter += 1 'フォームを再描画しない '1秒間停止する System.Threading.Thread.Sleep(1000) Next i End Sub 'Button2のクリックイベントハンドラ Private Sub Button2_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Button2.Click Dim i As Integer For i = 0 To 9 'カウンターを増やす counter += 1 'Invalidateを呼び出す Me.Invalidate() '1秒間停止する System.Threading.Thread.Sleep(1000) Next i End Sub 'Button3のクリックイベントハンドラ Private Sub Button3_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Button3.Click Dim i As Integer For i = 0 To 9 'カウンターを増やす counter += 1 'Updateを呼び出す Me.Update() '1秒間停止する System.Threading.Thread.Sleep(1000) Next i End Sub 'Button4のクリックイベントハンドラ Private Sub Button4_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Button4.Click Dim i As Integer For i = 0 To 9 'カウンターを増やす counter += 1 'Refreshを呼び出す Me.Refresh() '1秒間停止する System.Threading.Thread.Sleep(1000) Next i End Sub 'PictureBox1のPaintイベントハンドラ Private Sub PictureBox1_Paint(ByVal sender As Object, _ ByVal e As System.Windows.Forms.PaintEventArgs) _ Handles MyBase.Paint 'カウンターを描画する e.Graphics.DrawString(counter.ToString(), Me.Font, _ Brushes.Black, 0, 0) End Sub [C#] //カウンターの値 private int counter = 0; //Button1のクリックイベントハンドラ private void Button1_Click(object sender, System.EventArgs e) { for (int i = 0; i < 10; i++) { //カウンターを増やす counter++; //フォームを再描画しない //1秒間停止する System.Threading.Thread.Sleep(1000); } } //Button2のクリックイベントハンドラ private void Button2_Click(object sender, System.EventArgs e) { for (int i = 0; i < 10; i++) { //カウンターを増やす counter++; //Invalidateを呼び出す this.Invalidate(); //1秒間停止する System.Threading.Thread.Sleep(1000); } } //Button3のクリックイベントハンドラ private void Button3_Click(object sender, System.EventArgs e) { for (int i = 0; i < 10; i++) { //カウンターを増やす counter++; //Updateを呼び出す this.Update(); //1秒間停止する System.Threading.Thread.Sleep(1000); } } //Button4のクリックイベントハンドラ private void Button4_Click(object sender, System.EventArgs e) { for (int i = 0; i < 10; i++) { //カウンターを増やす counter++; //Refreshを呼び出す this.Refresh(); //1秒間停止する System.Threading.Thread.Sleep(1000); } } //PictureBox1のPaintイベントハンドラ private void PictureBox1_Paint( object sender, System.Windows.Forms.PaintEventArgs e) { //カウンターを描画する e.Graphics.DrawString( counter.ToString(), this.Font, Brushes.Black, 0, 0); } まず、カウンターをインクリメントした後に何もしない時(Button1をクリックした時)は、フォームに表示された数字は全く変化しません。ただし、10秒後フォームを一回隠してもう一度表示するなどすれば、カウンターの値が表示されます。しかもこの10秒間は、フォーム全体はフリーズしたようになり、フォームの上に別のウィンドウを重ねても、フォームは一切再描画されません。 Invalidateメソッドを呼び出した時(Button2をクリックした時)も同様に10秒間変化しませんが、10秒後ようやくカウンターが更新されて表示されます。しかし、10秒間フォーム全体はフリーズしたようになります。 Updateメソッドを呼び出した時(Button3をクリックした時)も同じく何も変化しないように見えますが、フォームの上に別のウィンドウを重ね、またどけるというようなことを行うと、フォームは1秒おきに再描画されます。カウンターが表示される部分を別のウィンドウで隠せば、カウンターも更新されて表示されます。 Refreshメソッドを呼び出した時(Button4をクリックした時)は、何もしなくても1秒おきにフォーム全体が再描画され、カウンターも更新されて表示されます。 実際のこれらのメソッドの使い分けとしては、コントロールを再描画したいがすぐである必要がないときはInvalidateメソッドを使い、今すぐ再描画する必要があるときはRefreshメソッドを使うということになるでしょう。 注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。
|
|
Copyright 2002-2008 DOBON!. All rights reserved.
|