none
FormからFormへの参照の渡し方がわからない。 RRS feed

  • 質問

  • こんにちは、初心者です。回答よろしくお願いします。

    私は今Visual Basic 2008 Express Edition を使い、グラフィックスで六角形を描画し、Form1のPictureBoxからForm2のPictureBoxへ複写しようとしています。そして以前ここで質問したときは、Cloneを作成し、それを渡せば良いということを学んだのですが、渡し方が本を読んでもわかりません。本の通りにコードを書いたら、メソッドの部分に「宣言されていません」という警告が出たので、メソッドを定義したのですが、これが正しいのかもよくわかりません。あと渡しを参照渡しにしてpointの配列の座標を変えるようなことが出来るのでしょうか。質問がまとまっていないかもしれませんが、ご回答していただけると幸いです。以下に今まで書いたコードを示します。

    Public Class Form1
        Public ReturnDialog As Boolean
        Public Sub SomeMethod(ByVal M2)

      End Sub

    ・六角形をイメージに描画、Cloneの作成

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim M As Image = New Bitmap(624, 578)
            Dim g As Graphics = Graphics.FromImage(M)
            Dim points(5) As Point

            points(0) = New Point(140, 100)
            points(1) = New Point(180, 130)
            points(2) = New Point(180, 180)
            points(3) = New Point(140, 210)
            points(4) = New Point(100, 180)
            points(5) = New Point(100, 130)

            g.DrawPolygon(Pens.Black, points)
            PictureBox1.Image = M
            Dim M2 As Image = New Bitmap(141, 161)
            M2 = M.Clone
            SomeMethod(M2)
        End Sub

    ・Form2の表示

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
            Form2.Show()
            ReturnDialog = True
        End Sub

    ・Form2へ値渡し

    Public Sub SomeMethod(ByVal M3 As Image)
            PictureBox2.Image = M3
        End Sub

     

    2010年7月22日 14:44

回答

  • Form2上のPictureBoxに表示するイメージを指定渡すためのプロパティを、Form2に定義してはどうでしょうか。そして、Cloneで複製した画像は、そのプロパティにセットすればいいと思います。

     

    あと、Point配列もプロパティやメソッドで同様に渡せます。ただ、渡したあとに配列の中身を操作しても、すでに描画されたイメージの内容を変更することはできないと思います。中の値を変更したPoint配列を使って、DrawPolygonで再描画する必要があるかと。

     


    なかむら(http://d.hatena.ne.jp/griefworker)
    • 回答としてマーク 山本春海 2010年8月2日 4:51
    2010年7月22日 20:51
  • 示されたコードで正しく動いているのでしょうか?
    Form1もForm2もクラスです。クラスが連携して仕事をするのがオブジェクト指向です。フォームにこだわらず、一般的にクラス間でどう連携を取るかに着目して調べられると良いと思います。初心者ということですのでわからないところがわからないようなご質問の内容になっていると思いますので、六角形にこだわらず、そういったオブジェクト指向の基本的な部分に注目されると良いと思います。ちなみに、なかむらさんも書かれていますが、クラス間で値を受け渡しする一般的な方法はプロパティを使うことです。

    また、「参照渡し」はよく誤解されていますので、以下を確認されると良いでしょう。

    第 7 回 「参照渡し」という用語の誤解
    http://msdn.microsoft.com/ja-jp/ff394162.aspx


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク 山本春海 2010年8月2日 4:51
    2010年7月23日 0:45
    モデレータ
  • 外池と申します。

    ざっと拝見したところ、とりあえず、Bitmapのオブジェクトを作っていますよね。これが、オブジェクトとしては判りやすいと思います。

    1) これを参照する変数としてMが宣言されていますが、Form1のButton1_Clickの中でしか有効になっていません。これを、Form1全体で有効になるように、宣言する場所を移してはいかがでしょう?

    2) この参照を、Form2のPictureBoxのImageプロパティーにセットしてやれば、コピーが出来たように見えるはずです。Form2のPictureBoxですから・・・、Button4_Clickで、Form2.Showした直後にセットできるチャンスがあります。Form2.PictureBox.Image = Mというような感じで。(Clone作る必要あるんだろうか・・・)

    ただ、すいません、Form1やForm2の扱い方も十分に注意してください。これ、個人的にはVisual Basicの非常に悪い点だと思うのですが、クラス名と参照する変数名がゴッチャにするのは良くないです。

    Public Class Form1
      Private _Image As Bitmap
    
      Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
        MyBase.OnLoad(e)
    
        _Image = Image.FromFile("../test.jpg")
        PictureBox1.Image = _Image
      End Sub
    
      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim dlg As New Form2
        dlg.PictureBox1.Image = _Image
        dlg.ShowDialog()
        dlg.Dispose()
      End Sub
    End Class
    

    とりあえず、こんな感じで、画像のコピーはできます。

    Form1には、PictureBox1と、Button1が載っているものとします。コードは上記のとおり。

    Form2にもPictureBox1とButton1が載っていますが、Form2のAcceptButtonプロパティーはこのButton1にセットして、Button1のDialogResultプロパティーはOKにセットするものとします。これだけで、Form2のコードは特に書く必要はありません。

    Form1でButton1をクリックすれば、Form2が出ます。Form2のButton1をクリックすれば、Form2は消えてForm1に戻ります。


    (ホームページを再開しました)
    • 回答としてマーク 山本春海 2010年8月2日 4:51
    2010年7月23日 2:06

すべての返信

  • Form2上のPictureBoxに表示するイメージを指定渡すためのプロパティを、Form2に定義してはどうでしょうか。そして、Cloneで複製した画像は、そのプロパティにセットすればいいと思います。

     

    あと、Point配列もプロパティやメソッドで同様に渡せます。ただ、渡したあとに配列の中身を操作しても、すでに描画されたイメージの内容を変更することはできないと思います。中の値を変更したPoint配列を使って、DrawPolygonで再描画する必要があるかと。

     


    なかむら(http://d.hatena.ne.jp/griefworker)
    • 回答としてマーク 山本春海 2010年8月2日 4:51
    2010年7月22日 20:51
  • 示されたコードで正しく動いているのでしょうか?
    Form1もForm2もクラスです。クラスが連携して仕事をするのがオブジェクト指向です。フォームにこだわらず、一般的にクラス間でどう連携を取るかに着目して調べられると良いと思います。初心者ということですのでわからないところがわからないようなご質問の内容になっていると思いますので、六角形にこだわらず、そういったオブジェクト指向の基本的な部分に注目されると良いと思います。ちなみに、なかむらさんも書かれていますが、クラス間で値を受け渡しする一般的な方法はプロパティを使うことです。

    また、「参照渡し」はよく誤解されていますので、以下を確認されると良いでしょう。

    第 7 回 「参照渡し」という用語の誤解
    http://msdn.microsoft.com/ja-jp/ff394162.aspx


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://blogs.wankuma.com/trapemiya/
    • 回答としてマーク 山本春海 2010年8月2日 4:51
    2010年7月23日 0:45
    モデレータ
  • 外池と申します。

    ざっと拝見したところ、とりあえず、Bitmapのオブジェクトを作っていますよね。これが、オブジェクトとしては判りやすいと思います。

    1) これを参照する変数としてMが宣言されていますが、Form1のButton1_Clickの中でしか有効になっていません。これを、Form1全体で有効になるように、宣言する場所を移してはいかがでしょう?

    2) この参照を、Form2のPictureBoxのImageプロパティーにセットしてやれば、コピーが出来たように見えるはずです。Form2のPictureBoxですから・・・、Button4_Clickで、Form2.Showした直後にセットできるチャンスがあります。Form2.PictureBox.Image = Mというような感じで。(Clone作る必要あるんだろうか・・・)

    ただ、すいません、Form1やForm2の扱い方も十分に注意してください。これ、個人的にはVisual Basicの非常に悪い点だと思うのですが、クラス名と参照する変数名がゴッチャにするのは良くないです。

    Public Class Form1
      Private _Image As Bitmap
    
      Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
        MyBase.OnLoad(e)
    
        _Image = Image.FromFile("../test.jpg")
        PictureBox1.Image = _Image
      End Sub
    
      Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim dlg As New Form2
        dlg.PictureBox1.Image = _Image
        dlg.ShowDialog()
        dlg.Dispose()
      End Sub
    End Class
    

    とりあえず、こんな感じで、画像のコピーはできます。

    Form1には、PictureBox1と、Button1が載っているものとします。コードは上記のとおり。

    Form2にもPictureBox1とButton1が載っていますが、Form2のAcceptButtonプロパティーはこのButton1にセットして、Button1のDialogResultプロパティーはOKにセットするものとします。これだけで、Form2のコードは特に書く必要はありません。

    Form1でButton1をクリックすれば、Form2が出ます。Form2のButton1をクリックすれば、Form2は消えてForm1に戻ります。


    (ホームページを再開しました)
    • 回答としてマーク 山本春海 2010年8月2日 4:51
    2010年7月23日 2:06
  • 外池さん、trapemiyaさん、なかむらさん、ご意見ありがとうございました。この意見について深く検討しようと思います。ありがとうございます。
    2010年7月23日 12:19
  • こんにちは、mokeke さん。

    MSDN フォーラムをご利用いただき、ありがとうございます。フォーラム オペレーターの 山本です。

    みなさんからのアドバイスは、有効な情報であると思われるため、勝手ながら私のほうで一旦回答としてマークさせていただきました。
    回答いただいたみなさん、アドバイスありがとうございます。

    その後いかがでしょうか。
    ご不明点などがあるかもしれませんが、解決されていないようでしたら、不明点など詳細をお知らせいただいて、ご質問を続けてくださいね。
    (内容によっては新たにスレッドを立てたほうがいい場合もありますが)

    お時間のある時にでも、現在の状況をお知らせくださいね。お待ちしています。それでは。
                                                         

    マイクロソフト株式会社 フォーラム オペレーター 山本 春海
    2010年8月2日 4:51