投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/3/10 14:00:00
Form1 と Form2 の前後関係を切り替えられるようにしたいのであれば、
Owner を指定してはいけません。Owner は Nothing のままにしておいてください。

Owner プロパティ(あるいは Show メソッドの引数)にセットしたウィンドウは、
モードレス ダイアログの親ウィンドウとして管理され、前後関係(ZOrder)が固定される仕様です。

そして、Owner ウィンドウが閉じられたり非表示になったりすれば、
子フォームも一緒に閉じられたり非表示になります。


ということで、Owner を通じてデータのやり取りを行うことは避けてください。
そもそも他フォームのコントロールを直接操作するのは、本来は望ましくありません。


> DirectCast(Me.Owner, Form1).txt_pic.Text = txt_ans.Text

たとえば上記の場合、右辺は「自フォームの txt_ans」への操作なので問題無いのですが、
左辺は「他フォームの txt_pic」を操作していることになるため、避けるべきです。

互いのフォームを操作しあうような実装は「密結合」となり、
画面仕様の変更に弱くなります。


慣れないうちは手間に感じるかもしれませんが、疎結合を原則とし、
「フォームのコントロールを読み書きできるのは、そのフォーム自身のみ」
の方針で設計した方が、画面仕様の変更などに追従しやすくなります。

つまりコントロールそのものを操作させるのではなく、
コントロールの値を読み書きするためのメンバー(プロパティ・メソッド・イベント等)を
作成し、それを通じて読み書きする設計にするのが望ましいということです。


Form2 の txt_ans.Text を読み書きするコードは Form2 に置き、
Form1 の txt_pic.Text を読み書きするコードは Form1 に置くようにします。

たとえばこんな感じ。これなら、Owner に頼る必要もなくなります。

Public Class Form1
    'Form2 のイベントを捕らえる 
    Private WithEvents childForm As Form2 = Nothing

    'Button1 を押すと、Form2 を表示する 
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If childForm Is Nothing Then
            childForm = New Form2()
        End If
        'childForm.Show(Me) 'これだと親子関係になってしまう 
        childForm.Show()    'これならどちらのフォームも手前にできる 
    End Sub

    'Form2 から変更通知が飛んで来たら、自フォームの txt_pic に反映させる 
    Private Sub childForm_AnswerChanged(sender As Object, e As Form2.AnswerChangedEventArgs) Handles childForm.AnswerChanged
        txt_pic.Text = e.Answer
    End Sub

    Private Sub childForm_FormClosed(sender As Object, e As FormClosedEventArgs) Handles childForm.FormClosed
        childForm = Nothing
    End Sub
End Class



Public Class Form2
    '変更通知用の「イベント」を自作しておく 
    Public Event AnswerChanged As EventHandler(Of AnswerChangedEventArgs)

    'EventArgs クラスを継承して、受け渡したい情報を「プロパティ」として盛り込む 
    Public Class AnswerChangedEventArgs
        Inherits EventArgs
        Public ReadOnly Property Answer As String
        Public Sub New(answer As String)
            Me.Answer = answer
        End Sub
    End Class

    ' txt_ans が書き換わったらすぐに、変更を通知したい場合 
    
    Private Sub txt_ans_TextChanged(sender As Object, e As EventArgs) Handles txt_ans.TextChanged
        ' 自フォームの txt_ans の内容を持ったイベント引数を用意する 
        Dim arg As New AnswerChangedEventArgs(txt_ans.Text)
        ' その情報を引数に渡して、自作の変更通知イベントを発生させる 
        RaiseEvent AnswerChanged(Me, arg)
    End Sub

    'Button1 が押された時に、変更を通知したい場合 
    
    'Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
    '    RaiseEvent AnswerChanged(Me, New AnswerChangedEventArgs(txt_ans.Text)) 
    'End Sub 
End Class