こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

Form間のデータ渡しについて

申し訳ありません。VB.NET初心者です。
Form1から、ボタンAをクリックするとForm2がオープンします。
Form1から、ボタンBをクリックするとForm3がオープンします。

Form1では、Form2またはForm3で設定した値をそれぞれ演算に使おうとしています。

MicrosoftのHPからパクってForm1 - Form2間のデータの引渡しを行うことはできたの
ですが、新規でForm3を作成して、Form1 - Form3間のデータの引渡しを行おうとする
とForm3の立ち上がり時に

"NullReferenceException はハンドルされませんでした"となり、
困ってしまいました。

使われている方から見ると簡単かもしれず
申し訳ありませんが、どなたか教えていただけないでしょうか。

==================== Form1.vb =======================
Form1には、Label1、Label2、Button1、Button2があります。

Public Class Form1
Inherits System.Windows.Forms.Form

Private m_form2 As Form2
Private m_form3 As Form3

Public Property LabelText() As String
Get
Return Label1.Text
End Get
Set(ByVal Value As String)
Label1.Text = Value
End Set
End Property

Public Property LabelText2() As String
Get
Return Label2.Text
End Get
Set(ByVal Value As String)
Label2.Text = Value
End Set
End Property

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles ScaleYokusou.Click
m_form2 = New Form2(Me)
m_form2.ShowDialog()
m_form2.Dispose()
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles ScaleHikito.Click
m_form3 = New Form3()
m_form3.ShowDialog()
m_form3.Dispose()
End Sub

End Class


==================== Form2.vb =======================
Form2には、TextBox1、Button1があります。

Public Class Form2
Inherits System.Windows.Forms.Form

Private m_form1 As Form1

Private Sub TextBox1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Handles TextBox1.TextChanged
If m_form1 Is Nothing = False Then
m_form1.LabelText = Me.TextBox1.Text
End If
End Sub

Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load
If m_form1 Is Nothing = False Then
Me.TextBox1.Text = m_form1.LabelText
End If
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles Button1.Click
Me.Close()
End Sub
End Class


==================== Form3.vb =======================
Form3には、TextBox1、Button1があります。

Public Class Form3
Inherits System.Windows.Forms.Form

Private m_form1 As Form1

Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles TextBox1.TextChanged
If m_form1 Is Nothing = False Then
m_form1.LabelText2 = Me.TextBox1.Text
End If
End Sub

Private Sub Form3_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load
Me.TextBox1.Text = m_form1.LabelText2
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles Button1.Click
Me.Close()
End Sub

End Class

投稿日時 - 2008-04-09 20:33:05

QNo.3935738

暇なときに回答ください

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(7)

ANo.7

# ANo.2, 4, 6 についてのご回答はご質問者の方やご覧になる方に間違った情報や知識を
# 流布してはならないとのことだけかとは思いますが……。
# 結果として私の拙いアドバイスへの訂正となり申し訳ありません。
# 極力正しいことを伝えようとはしておりますが未熟者故なかなか思うようになりません。

ご質問される方の理解が深まればということで僭越ながら補足を付けさせて頂きます。

ANo.6 から引用
> VB2005の場合でも コードからフォームを起こしてしまうとデザイナーコード(Desiner.vb)は作成されません

これは「マイクロソフトのサイトからダウンロードしたサンプルである VB.NET 2003 コードから
変換されたコードも同様になる」という意味になります。

追加された Form3 の場合には Form3.Designer.vb という別のファイルになっていますが
旧バージョンから変換された Form1 や Form2 にはコードの中にボタンやラベルなどの
配置位置などを記述した部分があるのです。
これは ANo.2 で仰られている『Windows フォーム デザイナで生成されたコード』というものです。

> 『Windowsフォームの追加』や『新しい項目の追加』などで追加したフォームの場合は dexiner.vbの先頭に
> Partial Class From2 などと宣言されて このファイルは Form2 クラスの1部ですと宣言されます

# Form2 となっておりますが、これは追加した Form3 のことを意味されておられるかと思われます。

この Partial やバージョンの相異点については以下のサイトをご覧になるとイメージがつかめるかと思われます。

※ 「5-3.分割クラス」という項目で下の方にあります。

VB いろいろなクラス・構造体 - Module, Enum, Structure, Partial
http://homepage1.nifty.com/rucio/main/dotnet/shokyu/standard50.htm

投稿日時 - 2008-04-11 22:28:57

ANo.6

> くどくどと書いてしまいましたが、要するに Form3 にもこういう処理を追加する必要があるのです。
> ただしこれは Visual Basic .NET 2003 までの話です。
> Visual Basic 2005 は Form ごとの Sub New の定義はなく、敢えてそうしたいのであれば

VB2005の場合でも コードからフォームを起こしてしまうとデザイナーコード(Desiner.vb)は作成されません

『Windowsフォームの追加』や『新しい項目の追加』などで追加したフォームの場合は dexiner.vbの先頭に
Partial Class From2
などと宣言されて このファイルは Form2 クラスの1部ですと宣言されます

投稿日時 - 2008-04-11 16:27:23

ANo.5

> Form3のSub Mainですか。。。。ほんとによくわかってなくて恐縮
> なのですが

失礼いたしました、Sub New が正しく Sub Main は誤りでした。
基礎的なことは説明しないのですが、私が間違えたお詫びとして説明します。

ANo.4 の方が仰られている通りなので、蛇足にしかなりませんが。

VB 2005 の場合は、私の記述したようなコードでも動作しますが、以前のバージョンは
VB.NET 2003 などは明確に渡す必要がありました。

わかり易く「値」と言いますが、オブジェクトを識別するための値です。

>【Form2.vb】
> Private m_form1 As Form1
ここが識別する値を格納するのための変数を用意している部分、これは Form2 の中であれば
どこからでも値を得ることが可能な Private 変数として宣言されています。

> Public Sub New(ByVal fr As Form1)
ここで fr という変数に Form1 の識別する値が受け取られる。
Form1 から呼ぶ時に「m_form2 = New Form2(Me)」としていたのはそのためです。

> MyBase.New()
> m_form1 = fr
ここで fr から m_form1 に値が渡される。
何故かというと fr は Sub New の中でのみ生存できる変数であるため先ほど述べた m_form1 という変数に
値を渡しているのです。

> InitializeComponent()
> End Sub
ここで Sub New は終わるので fr という変数は消滅します。

くどくどと書いてしまいましたが、要するに Form3 にもこういう処理を追加する必要があるのです。

ただしこれは Visual Basic .NET 2003 までの話です。

Visual Basic 2005 は Form ごとの Sub New の定義はなく、敢えてそうしたいのであれば
Form3 のフォームのコードの「全般」の箇所の
Public Class Form3
のすぐ下の行で
Public Sub New
と書いてエンターだけ押せば次のような Sub New のスケルトンが自動で作られますので

 Public Sub New()

  ' この呼び出しは、Windows フォーム デザイナで必要です。
  InitializeComponent()

  ' InitializeComponent() 呼び出しの後で初期化を追加します。

 End Sub

これを修正すれば良いです。

と、説明下手の私が説明するよりも他の方のお書きになられた次のサイトをご覧になるほうが
早いかも知れません。

※ VB.NET 2003 と VB 2005 の違いについてですが……
  検索で最初に出たものです、検索すれば他にもあると思います。

VB.NET
http://www.geocities.jp/hatanero/vbnet.html

投稿日時 - 2008-04-10 23:36:21

ANo.4

>【Form2.vb】
> Private m_form1 As Form1
> Public Sub New(ByVal fr As Form1)
> MyBase.New()
> m_form1 = fr
> InitializeComponent()
> End Sub
の役割ですが Form2のインスタンス(実体)を作る際に 引数としてForm1型オブジェクトが必要ということです
この引数により 自分自身のメンバー変数 m_form1を初期化し
他のメソッド内で Form1のプロパティなどを使うのに使用します

投稿日時 - 2008-04-10 17:19:08

ANo.3

ANo.1 で答えた者です。

ANo.1 の方法は VB 2005 であれば動く方法ですので Inherits System.Windows.Forms.Form が
ついてるということは VB.NET 2003 かそれより前でバージョンでしょうか?

先ほどは Form1 についてうっかり見落としてましたが……
ANo.2 で回答されている方が仰るように m_form3 = New Form3() に引数が指定されていないようです。

例にされたのはここでしょうか?

ユーザー インターフェース
http://msdn.microsoft.com/library/ja/jpdnvs05/htm/2005/migrate/Form.asp
上記 URL からの引用
>【Form2.vb】
> Private m_form1 As Form1
> Public Sub New(ByVal fr As Form1)
> MyBase.New()
> m_form1 = fr
> InitializeComponent()
> End Sub

だとすれば Form3 の Sub Main に処理するコードを付け忘れている可能性が高いと思われます。

投稿日時 - 2008-04-10 05:12:24

お礼

そうです。そのマイクロソフトのコードをほとんど引用しているだ
けです。ちなみにVB2005のExpress Editionです。

Form3のSub Mainですか。。。。ほんとによくわかってなくて恐縮
なのですが

>【Form2.vb】
> Private m_form1 As Form1
> Public Sub New(ByVal fr As Form1)
> MyBase.New()
> m_form1 = fr
> InitializeComponent()
> End Sub

上記のコードはどういう意味になるんでしょうか・・

投稿日時 - 2008-04-10 10:51:14

ANo.2

# 開発環境のバージョン情報も記載しましょう
Form2の作成には Form1のインスタンスをあらわす Meを渡していますが
Form3の作成時には渡していませんね

Form3を作成した手順が Foerm2を作成した手順と異なっていませんか

Private Sub Button2_Click(引数省略) Handles ScaleHikito.Click
  ' ここの Form3に引数 Meを追加する
  m_form3 = New Form3(Me)
  m_form3.ShowDialog()
  m_form3.Dispose()
End Sub

VB2005の場合 VB.NETのメニューで
プロジェクト > すべてのファイルを表示
にしておいて Form3.Desiner.vbと Form2.Desiner.vb を比較してみましょう

VB2002/2003の場合は Form2.vb、Form3.vbのなかの
『Windows フォーム デザイナで生成されたコード』
を展開した部分に相違が無いか調べましょう

投稿日時 - 2008-04-10 02:13:31

お礼

コメントありがとうございました。
Form2は最初にあったコードを編集しただけで、同じようにするということでForm3の部分をコピー貼り付けしました。

私も同じようにm_form3 = New Form3(Me)
と書くと"Public Sub New()"に対する引数が多すぎます。
とメッセージが出ましたので
m_form3 = New Form3()
としていました。

投稿日時 - 2008-04-10 10:45:07

ANo.1

Form1 の Label1 や Label2 に Form2 や Form3 の TextBox で変更した値を入れたいだけなのでしょうか?

一部は余計なお世話なのですが、コードを書きます。

※ 動作確認はしてません。

Form1 は良いとして Form2 と Form3 を

> ==================== Form2.vb =======================
> Private m_form1 As Form1

Private m_form1 As Form1 や Private Sub TextBox1_TextChanged は不要なのではないでしょうか?

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
 Form1.LabelText = Me.TextBox1.Text
 Me.Close()
End Sub

Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 Me.TextBox1.Text = Form1.LabelText
End Sub

とする。

> ==================== Form3.vb =======================
> Private m_form1 As Form1

Private m_form1 As Form1 や Private Sub TextBox1_TextChanged は不要なのではないでしょうか?

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
 Form1.LabelText2 = Me.TextBox1.Text
 Me.Close()
End Sub

Private Sub Form3_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 Me.TextBox1.Text = Form1.LabelText2
End Sub

とすれば、なさりたいことは実現可能かと思われますが?

投稿日時 - 2008-04-10 01:31:22

お礼

> Form1 の Label1 や Label2 に Form2 や Form3 の TextBox で変更>した値を入れたいだけなのでしょうか?
> 一部は余計なお世話なのですが、コードを書きます。

いえいえ、ありがとうございました。
上記のコードで確認できました。

投稿日時 - 2008-04-10 10:39:05

あなたにオススメの質問