tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル複数のフォーム
記事No12148
投稿日: 2024/08/22(Thu) 16:27
投稿者たけし
お世話になります。vb.net 2010使用しています。

フォーム1とフォーム2を表示していまして、
フォーム2よりモジュールをコールして
モジュール内で、フォーム2のテキストへデータを貼り付けしたいのですができない状況です。
(フォーム1へは貼り付けできる)

現状はフォーム1をロードする時にフォーム2を起動しています。
dim frm2 As New Form2()
frm2.Show()

対応方法など教えてください。

[ツリー表示へ]
タイトルRe: 複数のフォーム
記事No12149
投稿日: 2024/08/23(Fri) 01:15
投稿者魔界の仮面弁士
> 現状はフォーム1をロードする時にフォーム2を起動しています。
> dim frm2 As New Form2()
> frm2.Show()

「New」は、新しくオブジェクトを作成するためのものです。
そして上記の場合、その生成されたインスタンスは、変数 frm2 によって保持されています。


たとえば、
 Dim a As Form2
 Dim b As Form2
 a = New Form2()
 b = New Form2()
 a.Show()
 b.Show()
のようにすると、「New」によって生成された 2 つの Form2 が同時に表示されることになります。

Form2 のタイトルを変更しようとした場合、どちらの Form2 インスタンスを操作したいのかを
指示しなければなりません。今回の場合、それらは変数 a, b に保持されていますので、
 a.Text = "画面1"
 b.Text = "画面2"
のようにして指定できます。


つまりモジュールから操作するときも、「フォームのインスタンス変数」を渡して操作させれば良いということです。

フォーム変数は、As Form や As Form2 といった型の引数や変数を通じて Module に渡しておきましょう。

Module Module1
 Public Sub Test(f As Form2)
  f.TextBox1.Text = Now.ToString("HH:mm:ss")
  f.BackColor = Color.Yellow
 End Sub
End Module

Class Form1
 Private Sub Button1_Click(sender As Object, e AS EventArgs) Handles Button1.Click
  Dim o As New Form2()
  Test(o)
  o.Show()
 End Sub
End Class

Class Form2
 Private Sub Button1_Click(sender As Object, e AS EventArgs) Handles Button1.Click
  Test(Me)
 End Sub
End Class


あるいは、My.Forms による「暗黙のフォームオブジェクト」を使う受け渡し方法もあります。
インスタンスを同時に複数 New する必要が無いのであれば、Module レベルの変数や Shared メンバーに
そのインスタンスを渡しておくといった手法もあります。下記も参照してみてください。
https://dobon.net/vb/dotnet/form/accessanotherformdata.html



> モジュール内で、フォーム2のテキストへデータを貼り付けしたいのですができない状況です。
> (フォーム1へは貼り付けできる)

VB の場合、TextBox 等の Modifiers プロパティの既定値が Friend になっているので、
同一プロジェクト内であれば、フォーム変数のフィールド変数を通じて
 a.TextBox1.Text = "新しい文字列1"
 b.TextBox1.Text = "新しい文字列1"
というように、フォーム上のコントロールを直接読み書きできます。
先述の通り、対象のフォームインスタンス(上記の a, b)を明示する必要はありますけれどね。

ちなみに C# の場合は、Modifiers プロパティの既定値が private なので、上記のように
自フォーム以外から直接操作するようなことはできません。
(Modifiers を書き換えれば、VB と同じように操作できますが)


とはいえそもそも自フォーム以外から上記のようにコントロールを直接読み書きするのは
あまり良いコードとは言えません。「Form 上のコントロール」を操作して良いのは、本来は
そのフォーム自身だけです。(オブジェクト指向における「カプセル化」の概念)

たとえば Form2 上に「自身の TextBox へ文字列をセットするためのメソッドあるいはプロパティ」を
 Public Sub Example(newText As String)
  Me.TextBox1.Text = newText
 End Sub
などと用意しておき、外部からはそれを呼び出すようにしてみます。
 ' a.TextBox1.Text = "xyz"
 a.Example( "xyz" )


このようにしておくと、今後、Form2 側で画面仕様の変更が生じた場合も、
 Public Sub Example(newText As String)
  If Me.RadioButton1.Chekced Then
   Me.TextBox1.Text = newText
  Else
   Me.Label1.Text = newText
  End If
 End Sub
などのように処理をまとめられます。こうしておくと、呼び出し側のコードは修正する必要が無く、
 a.Example( "xyz" )
のままで良いことになりますので、仕様変更に強いコードになります。

[ツリー表示へ]
タイトルRe^2: 複数のフォーム
記事No12150
投稿日: 2024/08/23(Fri) 13:05
投稿者たけし
返答ありがとうございます。

スタートアップフォームに

フォーム1を設定しています。
フォーム1をロードするときに
以下の2つ実行しています。(1つ追加です)

dim frm2 As New Form2()
frm2.Show()

dim frm3 As New Form3()
frm2.Show()

Form2をロードするときに
モジュール内で Form2.TextBox1.Text = "テスト" していますが
書き込めないです。
(Form3でも同じようなことをやります)

以下をやってみましたが
書き込みできない状況でした。
Module Module1
 Public Sub Test(f As Form2)

[ツリー表示へ]
タイトルRe^3: 複数のフォーム
記事No12151
投稿日: 2024/08/23(Fri) 15:08
投稿者shu
> Form2.TextBox1.Text = "テスト" 
frm2.TextBox1.Text = "テスト" 

でどうでしょう?

[ツリー表示へ]
タイトルRe^3: 複数のフォーム
記事No12152
投稿日: 2024/08/28(Wed) 15:39
投稿者とくま
フォームの表示の仕方に2種類用意されているんですが、それらを混ぜて使っているのが原因です。

>モジュール内で Form2.TextBox1.Text = "テスト" していますが
クラス名と同じ"Form2"を使うと、VBが裏で別のインスタンスを作成します。
モジュール内で Form2.Show() を実行すれば、裏に隠れていた書込みできている
2枚目の Form2 が表示されます。
https://shinichiaoyagi.blogspot.com/2005/06/re-vb2005.html

>以下をやってみましたが
>書き込みできない状況でした。
>Module Module1
> Public Sub Test(f As Form2)
New もテキストの設定も全て魔界の仮面弁士さんの書いた通りのコードにすれば
表示されているフォームに書込みできます。

"Form2"という暗黙のインスタンスを使うか、
dim frm2 As New Form2()という明示的なインスタンスを使うか、
どちらかに統一してください。
ちなみに暗黙のインスタンスは、2回目以降も共通のものが呼び出されるので、
一度入力した値が残り続けます。
https://dxo.co.jp/blog/archives/8566

[ツリー表示へ]
タイトルRe
記事No12153
投稿日: 2024/09/10(Tue) 21:39
投稿者たけし
お世話になります。

>frm2.TextBox1.Text = "テスト" 
の方法で解決しました。


ありがとうございました。

[ツリー表示へ]