39856


**前提**

  1. form1にラベルとボタンを配置
  2. ボタンクリックでform2を表示
  3. form2にはデータを設定したリストボックスを配置済み

**質問**  
form2のリストボックスのある行を選択した時、その行にあるデータをform1のラベルにセットしたい

**コード**

[code]

    sub listbox1_click
      form1.label1.text = listbox1.selectitem
    end sub
    
[/code]

**結果**

> error BC30469: 非共有メンバーを参照するには、オブジェクト参照が必要です。

広域変数を用意した別モジュールを作成して、その中でform2を呼び出してデータを受け渡す方法を考えていますが、form2だけで完結する記述方法はありませんか？


CC BY-SA 3.0
2017-11-25T04:11:23.897
39819
2017-11-26T11:19:16.857
2017-11-25T14:50:38.630
19110
25794
question
vb.net
リストボックスの値を呼び出し元のフォームにあるラベルに表示


まず前提知識としてVB.NETでWindows
Formsアプリケーションを作成した場合、フォームのデフォルトインスタンスと呼ばれるものが生成されます。これにより`Form`に定義されているインスタンスメンバーに`Shared`の文法でアクセスできます。おそらく質問のコードでは

[code]

    Form2.Show()
    
[/code]

のような呼び出しがあると思われますが、これは実質的に

[code]

    My.Forms.Form2.Show()
    
[/code]

という処理です。同様に`Form1`のインスタンスメンバーには`My.Forms.Form1`からアクセスすればよく、`Form1.Label1`のアクセスレベルは既定では`Friend`ですので単純に`Form2`内から

[code]

    My.Forms.Form1.Label.Text = "test"
    
[/code]

のように記述するのがVB.NETのコンテキストでは一番簡潔になります。

* * *

なおVB.NETのアプリケーションフレームワークに依存しないコードの場合は

  * `Form2`に目的の値(コントロール自体ではなく)を公開するプロパティを定義する
  * `Form2`をモードレス(`form.Show()`)で表示する場合、上記プロパティの変更イベントを定義する
  * `Form1`側で`ShowDialog`終了時または上記イベント発生時にプロパティ値を読み出すコードを記述する

のがベストだと思います。この方針であれば`Form1`に関する処理を`Form2`に記述する必要がありませんし、`Form2`のコントロールを`Form1`に対して隠ぺいすることもできます。


CC BY-SA 3.0
2017-11-26T10:27:04.567
39856
2017-11-26T10:35:05.503
2017-11-26T10:35:05.503
5750
5750
39819
answer