none
Form1.Invalidate()を実行させたい。 RRS feed

  • 質問

  • Form2内のコードから、Form1のInvalidateを直接呼び出したいと思っているのですが、

    できません。

    どうすればできますか?よろしくお願いいたします(_ _)

    Code Snippet

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

    namespace testFm1InvalidateAppli
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
            public int counter = 0;
            Form2 form2;
            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                System.Reflection.Assembly myAssembly = System.Reflection.Assembly.GetExecutingAssembly();
                Image theImage = new Bitmap(myAssembly.GetManifestResourceStream("testFm1InvalidateAppli.image1.png"));
                e.Graphics.DrawImage(theImage, counter, counter);
                counter++;
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                form2= new Form2();
                form2.Show();
               
            }
        }
    }

     

     

    Code Snippet

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

    namespace testFm1InvalidateAppli
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }

            private void Form2_Load(object sender, EventArgs e)
            {

            }

            private void button1_Click(object sender, EventArgs e)
            {
               //ここにForm1.Invalidate()を記述したいのですが・・・
            }
        }
    }

     

     

    2009年1月22日 11:40

回答

  • おはようございます!(^^)!ふ~です。

     

    Code Snippet

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

    namespace testFm1InvalidateAppli
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                Paint+=new PaintEventHandler(Form1_Paint);
            }

            public int counter = 0;
           
            Form2 form2;

            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                System.Reflection.Assembly myAssembly = System.Reflection.Assembly.GetExecutingAssembly();

     

                //このアセンブリの全てのリソース名を取得する
                //string[] resources = myAssembly.GetManifestResourceNames();

                //リソース名を一つずつ表示する
                //foreach (string resource in resources)
                //        Debug.WriteLine(resource);

     

                Image theImage = new Bitmap(myAssembly.GetManifestResourceStream

                                                                                        ("testFm1InvalidateAppli.Resources.image1.PNG"));
                e.Graphics.DrawImage(theImage, counter, counter);
                counter++;
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                form2 = new Form2();
                form2.Show();
            }
        }
    }

     

     

     

    Code Snippet

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

    namespace testFm1InvalidateAppli
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }

            private void Form2_Load(object sender, EventArgs e)
            {

            }

            private void button1_Click(object sender, EventArgs e)
            {
                // Form1を取得する。
                Form1 frm = (Form1)Application.OpenForms[0];

                // Form1の描画領域を無効にする
                frm.Invalidate();
            }
        }
    }

     

     

    2009年1月22日 23:51

すべての返信

  • 考えられるパターンは以下です。

     

    1.Form2へForm1のインスタンスを渡してしまう。幸い実行したいのがInvalidateメソッドなので、Form2でそのインスタンスをForm型へキャストしてしまえば良い。従って、Form2はForm1へ依存しない疎結合が保たれる。

     

    2.Form2へForm1のインスタンスを渡す場合、インターフェース経由にして疎結合を保つ。

     

    3.Form1でInvalidateを呼び出すメソッドを定義する。Form2ではイベントを定義し、先に定義したメソッドをイベントハンドラとする。ただ、形的にはこれで動作するが、Form2のイベントとして意味づけができるかどうかという問題もある。つまり、Form2で何かが起こった時に発動するのがイベントであるが、何かが起こった時ではなく、いろいろなケースの場合に発動しなければならない場合、簡単に言えばそのイベントにどういう名前を付けたらよいのかわからなくなることもあるんじゃないかと思います。

     

    簡単にやるなら1ですが、実際には2か3を選択することになるんじゃないかと思います。

     

    #はしょって書いてしまいましたが、わかりにくいところがあれば言ってください。

    2009年1月22日 12:00
    モデレータ
  • おはようございます!(^^)!ふ~です。

     

    Code Snippet

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

    namespace testFm1InvalidateAppli
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                Paint+=new PaintEventHandler(Form1_Paint);
            }

            public int counter = 0;
           
            Form2 form2;

            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                System.Reflection.Assembly myAssembly = System.Reflection.Assembly.GetExecutingAssembly();

     

                //このアセンブリの全てのリソース名を取得する
                //string[] resources = myAssembly.GetManifestResourceNames();

                //リソース名を一つずつ表示する
                //foreach (string resource in resources)
                //        Debug.WriteLine(resource);

     

                Image theImage = new Bitmap(myAssembly.GetManifestResourceStream

                                                                                        ("testFm1InvalidateAppli.Resources.image1.PNG"));
                e.Graphics.DrawImage(theImage, counter, counter);
                counter++;
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                form2 = new Form2();
                form2.Show();
            }
        }
    }

     

     

     

    Code Snippet

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

    namespace testFm1InvalidateAppli
    {
        public partial class Form2 : Form
        {
            public Form2()
            {
                InitializeComponent();
            }

            private void Form2_Load(object sender, EventArgs e)
            {

            }

            private void button1_Click(object sender, EventArgs e)
            {
                // Form1を取得する。
                Form1 frm = (Form1)Application.OpenForms[0];

                // Form1の描画領域を無効にする
                frm.Invalidate();
            }
        }
    }

     

     

    2009年1月22日 23:51
  • !(^^)!ふ~さん

    trapemiyaさん

    ご協力ありがとうございます。

     

     「Paint+=new PaintEventHandler(Form1_Paint);

    にはどういう意味があるのでしょうか?

    上記なしで

    「 Form1 frm = (Form1)Application.OpenForms[0];

                // Form1の描画領域を無効にする
                frm.Invalidate();
    を加えただけで、一応目的のものができたのですが、

    注意点などあれば教えてください。

    2009年1月23日 14:43
  •  acslearner さんからの引用

     「Paint+=new PaintEventHandler(Form1_Paint);

    にはどういう意味があるのでしょうか?

    Form1のPaintイベントにForm1_Paintを割り当てる。

    デザイナのプロパティウィンドウでPaintイベントをダブルクリックしたときとほぼ同じです。

     

     acslearner さんからの引用

    上記なしで

    「 Form1 frm = (Form1)Application.OpenForms[0];

                // Form1の描画領域を無効にする
                frm.Invalidate();
    を加えただけで、一応目的のものができたのですが、

    注意点などあれば教えてください。

    OpenForms[0]がお望みのものであるかは、アプリケーションの構成次第です。

    例えば、類似の事例で、2番目のFormに対してInvalidateしたくなった時はどうするかとか考えないといけませんね。

     

    また、Form2をForm1やForm3から利用し、呼び出し元のForm(Form1かForm3)にInvalidateを実行したいときは、このような順番決め打ちや呼び出し元限定のコードは使いにくくなります。

     

    そのため、Form2側では親のフォームが何かを意識しないようにするコーディングが望ましいのかもしれません。

    例えば、Form2側でイベントを呼び出すような実装にしておき、呼び出し側のFormからはそのイベントに登録しておくとか。

    2009年1月24日 4:25
    モデレータ
  • こんにちは!(^^)!ふ~です。

     

    > 「Paint+=new PaintEventHandler(Form1_Paint);」はどういう意味があるのか?

     

    ソースを貼り付けて動作し易いように、プロパティで設定した内容を明らかにする為、コードで表現しております。

    VS2005, VS2008では、Form1のプロパティのイベントの表示のPaintで、イベントハンドラがご存じのように簡単

    に作成できます。この作成されたソースコードは、Form1.Designer.csの『Windows フォーム デザイナで生成されたコード』

    となります。

    ここを展開(+をクリック)すると、 this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);

    のソースコードが有る筈です。

     

    この自動生成作業を手動で、Paint+=new PaintEventHandler(Form1_Paint);と作成しただけです。手作業ですので

    省略できる部分は省略しておりますが、全く同じものです。

    2009年1月24日 5:26
  • 皆様、ご協力ありがとうございます。

    力不足で理解しきれていない部分もあるかもしれませんが、

    疑問がほぼ氷解しました。

    本当に有難うございました。

    2009年1月24日 12:51