2006年05月12日

他のフォームのコントロールを参照するには

VB6の時は簡単だった。(フォーム名).(コントロール名).(プロパティ)で参照できた。たとえばForm1.Text1.Textのような感じで。
VB.NETで別のフォームからForm1.TextBox1.Textを参照しようとしてもそのままではTextBox1が見えない。
ガリバー著「VisualBasic.NET基礎300の技」のTips261「他のフォームのコントロールを参照する」をみると、コントロールをSharedキーワードと共に宣言すると出ている。ところがこの通りやってみると、参照は確かにするのだが、フォームデザイン画面からコントロールが消えてしまう。Sharedを外すと復活する。これではたとえ参照できても画面の編集ができないから使いようがない。この本はVB.NET2002を元に書かれたものだからVB.NET2003の仕様が変わったためなのかもしれない。

仕方が無いので自分で調べることにした。そして試行錯誤の上、以下のような方法で実現することができた。

1.クラスモジュールにForm1をPublic Shared で定義
2.上記クラスモジュールのMainプロシージャからForm1を起動。
3.Form2に上記クラスモジュールをimportsで参照
4.Form1から開いたForm2でForm1のコントロールを参照。

サンプルソース(SharedForm.lzh)を用意したので詳しくはそちらを見てもらうとして、サンプルでは、Form1のTextBox1の内容をForm2から参照し、さらにForm2のTextBox1の値をForm1のTextBox2へ直接代入するようになっている。なおスタートアップをMainプロシージャでなくForm1にした場合では参照することはできなかった。


'=== プロジェクト名:SharedForm ===
'--- Class1.vb ---
Public Class Class1
Public Shared f1 As New Form1
Shared Sub Main()
Application.Run(f1)
End Sub
End Class
 
'--- Form1.vb ---
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
Dim f2 As New Form2
If f2.ShowDialog(Me) = DialogResult.OK Then
'f2側から変更しているので不要
'TextBox1.Text = f2.TextBox2.Text
'TextBox1.BackColor = System.Drawing.Color.Red
End If
f2.Dispose()
End Sub
 
'--- Form2.vb ---
Imports SharedForm.Class1
Public Class Form2
(中略)
Private Sub Form2_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles MyBase.Load
Me.Left = f1.Left + f1.Width
Me.Top = f1.Top
TextBox1.Text = f1.TextBox2.Text
End Sub
 
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
f1.TextBox1.Text = TextBox2.Text
f1.TextBox1.BackColor = System.Drawing.Color.Red
Me.Close()
End Sub
End Class

20060512.gif サンプル画面

Visual Basic.NET基礎300の技Visual Basic.NET基礎300の技
ガリバー

Visual Basic .NET逆引き大全 500の極意―WindowsXP/2000/NT対応 Visual Basic .NET ネットワーク+データベース300の技 ひと目でわかるMicrosoft Visual Basic .NET データベース開発入門 Visual Basic.NETプログラミングマニュアル ステップバイステップで学ぶMicrosoft Visual Basic .NET実践講座〈Vol.1〉基礎編

by G-Tools

posted by なっちゃん at 17:26| 静岡 ☔| Comment(5) | TrackBack(0) | VB.NET Tips | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
大変役立ちました。
この問題を解こうと何時間費やしたか
分かりません。

本当にどうもありがとうございました。
Posted by arturo_tak at 2007年03月03日 15:03
 もやもやしていたのが、上記記事のおかげで理解できました。ありがとうございました。
 オブジェクトにしてクラスに取り込まないと、連携がとれないということですね。このクラスをスタートアップにすることで、このクラスがオブジェクトになるから、クラスメンバがSharedでない場合、結局は、オブジェクトにしてオブジェクト間しか連携をとるしかない。クラス自体はSharedにできないが、他のクラスのメンバにすればその際にSharedにでき、その単一オブジェクトらしきものをいろんなオブジェクトからアクセスできる。
 上記記事で、Form1をスタートアップにすると、それは1つのオブジェクトになり、Shared宣言したオブジェクトとは異なる。「らしきもの」とは、Shared宣言したオブジェクト以外にもオブジェクトを生成できるという意味です。
 奥が深いですね。
Posted by 松本眞吉 at 2008年01月02日 00:59
コードインテリセンスで、

 form のクラス名.コントロール名

という記述ができてしまうのが、おかしいですよね。
まるで、form がはじめから shared 宣言されてるように見えます。
Posted by 地獄の素顔 at 2013年05月02日 02:50
訂正

>まるで、form がはじめから shared 宣言されてるように見えます。

     ↓ 訂正

まるで、コントロールがはじめから shared 宣言されてるように見えます。

コントロール類は、Friend WithEvent 宣言されていて、Shared などはついていないのに。
なぜ、クラス名.コントロール名というコードが文法エラーにならず、コードインテリセンスで書けてしまうのでしょうね。
Posted by 地獄のうんぬん at 2013年05月02日 02:55
VB6からVB.NETへの仕様変更の時にVB6までとは全然異なる仕様が沢山ありましたが、ユーザーが使い続けられるようにVB6の仕様を引継いだものがあって、それが仕様の統一感をそぐ結果になっているんだと思います。VB2005でそれが更に進み、VB6風の作り方が復活したのでも分かります。ただ私にすれば統一感より作りやすさの方が気に入っています。
Posted by なっちゃん at 2013年05月02日 11:18
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。