*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*

<C#> Invalidate()メソッドとRefresh()メソッドの相違点を示すサンプル <フォーム描画版>


*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*


「<C#> Paintイベントを扱うプログラミングにおける基本事項」

における一連の説明(知恵ノート)において、ここでは、

「Invalidate()メソッドとRefresh()メソッドの相違点を示すサンプル <フォーム描画版>」

について説明します。






総合の目次


本ページを含めた関連事項の総合目次です。

http://note.chiebukuro.yahoo.co.jp/detail/n388326



関連サンプル


本サンプルと関連性のあるサンプルです。すなわち、前回と次回以降のサンプルです。

関連サンプル 1
「Invalidate()メソッドとRefresh()メソッドの共通点を示すサンプル <フォーム描画版>」
http://note.chiebukuro.yahoo.co.jp/detail/n387757

関連サンプル 2
「Invalidate()メソッドとRefresh()メソッドの相違点を示すサンプル <フォーム描画版>」
http://note.chiebukuro.yahoo.co.jp/detail/n387758


関連サンプル 3
「Paintイベントを扱うプログラミングに関する各種サンプル」
関連サンプル 3 と、それ以降のサンプルもあります。総合目次から参照して下さい。
(Paintイベントを扱うプログラミングの各種サンプルは、総合目次上で複数個あります)




はじめに


<各関連サンプルと共通する総合目的>

Invalidate()メソッドとRefresh()メソッドは、コントロール(フォーム、又は、PictureBox等)のPaintイベントを強制的に発生させて、そのコントロールを再描画します。

しかし、実際は、以下の違いがあります。

Update()メソッドを含めて、Invalidate()メソッドとRefresh()メソッドの違いを以下に説明します。


<Invalidate()メソッド>

コントロール(フォーム、又は、PictureBox等)のPaintイベントを強制的に発生せさる。


<Update()メソッド>

コントロール(フォーム、又は、PictureBox等)を再描画します。


<Refresh()メソッド>

コントロール(フォーム、又は、PictureBox等)のPaintイベントを強制的に発生させて、そのコントロールを再描画します。



すなわち、「 Invalidate()メソッド実行後、Update()メソッド実行 」と言う組み合わせに該当するのが、Refresh()メソッドです。

なお、上記説明文から、Invalidate()メソッドのみを実行する場合、画面更新が行なわれないことになります。

しかし、実際は、Invalidate()メソッドのみの実行でも、画面更新が行なわれます。

正確に言い直せば、基本的に画面更新が行なわれるが、行なわれない場合もあると言うことです。

どう言う場合に行なわれないかと言いますと、Invalidate()メソッドを連続に何度も実行する場合に、画面更新が行なわれません。

その繰り返し中の途中の画像は更新されず、最終画像の画面のみが更新されます。

以上の説明によるInvalidate()メソッドとRefresh()メソッドの共通点のサンプル、及び相違点のサンプルを紹介そます。


<本ページのサンプルの目的>
Invalidate()メソッドとRefresh()メソッドの共通点を示すサンプルです。

どちらのメソッドも、コントロール(フォーム、又は、PictureBox等)のPaintイベントを強制的に発生させて、そのコントロールを再描画します。

その動作を、実際のサンプルプログラムで示します。






関連サンプルと比べた特徴


下記の各種サンプルプログラムは、どれもPaintイベントで扱う図画描画処理に関連するサンプルです。ただし、分離の扱い方が、各サンプルで異なります。詳しくは、下記に説明します。



関連サンプル 1
「Invalidate()メソッドとRefresh()メソッドの共通点を示すサンプル <フォーム描画版>」
Invalidate()メソッドとRefresh()メソッドの共通点を示すサンプルです。どちらのメソッドも、<1> Paintイベントを強制的に発生させます。<2> また、画面を更新させます。どちらのメソッドも、上記<1>、<2>の動作が行なわれることを示すサンプルです。

関連サンプル 2
「Invalidate()メソッドとRefresh()メソッドの相違点を示すサンプル <フォーム描画版>」
Invalidate()メソッドとRefresh()メソッドの相違点を比較するサンプルです。
Refresh()メソッドは、随時画面更新を確実に行ないます。これに対してInvalidate()メソッドは、画面更新を行なわない場合もあります。これらの違いを示すサンプルです。

関連サンプル 3
「Paintイベントを扱うプログラミングに関する各種サンプル」
上記までのサンプルは、Paintイベント使用の図画描画関連の基礎について解説しました。すなわち、基本中の基本のサンプルを紹介しただけです。次のステップとして、少しだけですが、なるべく応用的なサンプルを紹介して行きます。




サンプルコード


ここで取り上げるサンプルは、なるべく複雑にならない範囲で、Paintイベントによる図画描画を確かめられるものとします。






本サンプルの仕様概要


<全般の仕様>サンプルプログラムを起動した時の初期画面では、線が表示されています。そして、「線移動」ボタンをクリックすると、線が少し移動した位置に描画されます。「線移動」ボタンを何度も繰り返しクリックするたびに、線は移動して行きます。す。「リセット」ボタンをクリックすると、線は元の位置に戻ります。


<Invalidate()メソッドとRefresh()メソッドを比較するための仕様>2個の子フォームを用意します。その2個の子フォームは、Form2クラスとForm3クラスとします。Form2には、Refresh()メソッドによる描画結果を表示します。これに対してForm3には、Invalidate()メソッドによる描画結果を表示します。これらの2者の描画内容を見て比較します。


フォームデザイン等の前準備


コードを記述する前に、フォームのデザイン作成などの、以下の前準備を行なって下さい。


<プロジェクトの作成>
本サンプルの確認用に、新規にプロジェクトを作成して下さい。
プロジェクトの種類は、「Windowsフォームアプリケーション」です。

<子フォームの追加>子ウィンドウとなるフォームを、下記操作で追加してください。[プロジェクト] - [Windows フォームの追加]で、「新しい項目の追加」画面を表示します。その「新しい項目の追加」画面で、ファイル名を入力してから[追加]ボタンを押します(取り決めたいファイル名が特に無ければ、デフォルトのファイル名で構いません)。そうすると、新しいフォーム(Form2)のデザイン画面等が追加されます。また、同様の操作で、もう一つ子フォーム(Form3)を追加して下さい。。

<Form1 におけるフォームのデザイン>デザイン画面で、ボタン(button)を2個貼り付けて下さい。

 デザイン画面1.jpg



<Form1 におけるイベントプロシージャの作成>デザイン画面のフォーム(ボタン等のコントロールが貼り付いていない無地の部分)をダブルクリックすることにより、Form1_Load() メソッドを作って下さい。次に、デザイン画面で先ほど貼り付けたボタン1(button1)をダブルクリックして、button1_Click() メソッドを作って下さい。同様に、ボタン2(button2)をダブルクリックして、button2_Click() メソッドを作って下さい。

<Form2 におけるフォームのデザイン>Form2 においては、コントロールは何も貼り付けません。(すなわち、Form2 のデザイン画面での操作は、特にありません)。
 デザイン画面2.jpg

<Form2 におけるイベントプロシージャの作成>デザイン画面のフォーム(ボタン等のコントロールが貼り付いていない無地の部分)をダブルクリックすることにより、Form2_Load() メソッドを作って下さい。次に、デザイン画面のフォームが選択された状態で、「プロパティ」画面の「イベント」ボタン(雷マークのボタン)をクリックして下さい。その「プロパティ」画面で、Paint と言う項目をダブルクリックして下さい。そうすると、Form2_Paint()メソッドが作成されます。

<Form3 におけるフォームのデザイン>Form3 においては、コントロールは何も貼り付けません。(すなわち、Form3 のデザイン画面での操作は、特にありません)
 デザイン画面3.jpg

<Form3 におけるイベントプロシージャの作成>デザイン画面のフォーム(ボタン等のコントロールが貼り付いていない無地の部分)をダブルクリックすることにより、Form3_Load() メソッドを作って下さい。次に、デザイン画面のフォームが選択された状態で、「プロパティ」画面の「イベント」ボタン(雷マークのボタン)をクリックして下さい。その「プロパティ」画面で、Paint と言う項目をダブルクリックして下さい。そうすると、Form3_Paint()メソッドが作成されます。





ソースコード




<Form1のソースコード>

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;

// Invalidate()メソッドとRefresh()メソッドの相違点を示すサンプル <フォーム描画版>namespace CompareDifferenceInInvalidateAndRefreshF{    public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();        }

        // 子フォーム        public Form2 f2;        public Form3 f3;


        // ==============        // フォーム起動時に実行されるイベントプロシージャ        private void Form1_Load(object sender, EventArgs e)        {
            // コントロールの初期化            button1.Text = "線移動";            button2.Text = "リセット";

            // 子フォームの生成と表示            f2 = new Form2();   // 生成            f2.Show();  // 表示            f3 = new Form3();   // 生成            f3.Show();  // 表示
        }


        // ==============        // 「線描画」ボタンのクリック時に実行されるイベントプロシージャ        private void button1_Click(object sender, EventArgs e)        {
            // 線の終端位置を移動させるためのループ            for (int i = 0; i < 70; i++)            {
                // 線の終端y座標値を増加                f2.EndPointY = f2.EndPointY + 5;                f3.EndPointY = f3.EndPointY + 5;


                // 上記で指定した画像をフォームに描画                //  --- Paintイベントを強制発生させる。                f2.Refresh();                f3.Invalidate();

                // わずかな時間だけ、間を空ける。                System.Threading.Thread.Sleep(100);
            }
        }


        // ==============        // 「リセット」ボタンのクリック時に実行されるイベントプロシージャ        private void button2_Click(object sender, EventArgs e)        {
            // 線の終端y座標値を0で初期化            f2.EndPointY = 0;            f3.EndPointY = 0;

            // 上記で指定した画像をフォームに描画            //  --- Paintイベントを強制発生させる。            f2.Refresh();            f3.Invalidate();
        }

    }}




<Form2のソースコード>

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;

// Invalidate()メソッドとRefresh()メソッドの相違点を示すサンプル <フォーム描画版>namespace CompareDifferenceInInvalidateAndRefreshF{    public partial class Form2 : Form    {        public Form2()        {            InitializeComponent();        }


        // 線の終端におけるy座標値        public int EndPointY = 0;


        // ==============        // フォーム起動時に実行されるイベントプロシージャ        private void Form2_Load(object sender, EventArgs e)        {
            // 線の終端y座標値を0で初期化            EndPointY = 0;

            // 上記で指定した画像をフォームに描画            //  --- Paintイベントを強制発生させる。            this.Refresh();            //this.Invalidate();
        }


        // ==============        // Paintイベント発生時に実行されるイベントプロシージャ        private void Form2_Paint(object sender, PaintEventArgs e)        {
            // 描画を行うグラフィックスクラスを作成            Graphics gr = e.Graphics;

            // 画像領域に線を描画            System.Drawing.Pen PenObj = new System.Drawing.Pen(System.Drawing.Color.DarkGreen, 5.0f);            gr.DrawLine(PenObj, 0, 0, this.ClientSize.Width, EndPointY);
        }    }}



<Form3のソースコード>

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;

// Invalidate()メソッドとRefresh()メソッドの相違点を示すサンプル <フォーム描画版>namespace CompareDifferenceInInvalidateAndRefreshF{    public partial class Form3 : Form    {        public Form3()        {            InitializeComponent();        }


        // 線の終端におけるy座標値        public int EndPointY = 0;


        // ==============        // フォーム起動時に実行されるイベントプロシージャ        private void Form3_Load(object sender, EventArgs e)        {
            // 線の終端y座標値を0で初期化            EndPointY = 0;

            // 上記で指定した画像をフォームに描画            //  --- Paintイベントを強制発生させる。            //this.Refresh();            this.Invalidate();
        }


        // ==============        // Paintイベント発生時に実行されるイベントプロシージャ        private void Form3_Paint(object sender, PaintEventArgs e)        {
            // 描画を行うグラフィックスクラスを作成            Graphics gr = e.Graphics;

            // 画像領域に線を描画            System.Drawing.Pen PenObj = new System.Drawing.Pen(System.Drawing.Color.DarkGreen, 5.0f);            gr.DrawLine(PenObj, 0, 0, this.ClientSize.Width, EndPointY);
        }    }}



コードの解説


サンプルコードの中に書かれていますコメントを読んで下さい。すなわち、コードの解説は、基本的にサンプルコードの中に書かれているコメントとします。



実行結果


「線移動」ボタンをクリックすると、線の描画位置が移動します。



 実行画面1_1.jpg

Form1




 実行画面1_2.jpgForm2



 実行画面1_3.jpg Form3



途中では、フォーム2(Form2)が画面更新されていません。すなわち、Invalidate()メソッドの場合、途中では画面更新が行なわれないことがわかりました。これに対してRefresh()メソッド(フォーム1)の場合では、途中を含めて随時画面更新が行なわれています。



さいごに


本サンプルは、図画描画における基礎的な範囲です。よって、総合目次から、引き続き各種サンプルを参照して下さい。