参照していない別プロジェクトのフォームを表示する




1年以上前に更新された記事です。
情報が古い可能性がありますので、注意してください。

はじめに

別プロジェクトのフォームを表示したいけれど、その表示したいフォームが呼び出し元のリソースを使用している場合、循環参照になるため設定できません。

この場合、リフレクションを使えば別プロジェクトのexeをdllみたいに読み込んで呼び出せるようになる。

コード

呼び出す側(親)のプロジェクト:PJ01

Public Class frmPJ_01
    Private asm As System.Reflection.Assembly
    Private typ As Type

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Try
            ' PJ02のアセンブリを読み込む
            If IsNothing(Me.asm) Then
                Me.asm = System.Reflection.Assembly.LoadFrom("PJ02.exe")
                ' typeを取得する
                Me.typ = Me.asm.GetType("PJ02.frmPJ_02")
            End If


            ' インスタンス作成
            Dim frm As Object = typ.InvokeMember(
                Nothing,
                System.Reflection.BindingFlags.CreateInstance,
                Nothing,
                Nothing,
                Nothing
            )

            'フォーム表示
            Dim res As Object = typ.InvokeMember(
                "Show",
                System.Reflection.BindingFlags.InvokeMethod,
                Nothing,
                frm,
                Nothing
            )
        Catch fnfe As IO.FileNotFoundException
            MsgBox("ファイルが見つかりませんでした。", MsgBoxStyle.Critical, "エラー")
        Catch ex As Exception
            MsgBox("その他の例外が発生しました。", MsgBoxStyle.Critical, "エラー")
        End Try
    End Sub

    Private Sub frmPJ_01_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' 自プロジェクトのモジュール内の変数なので、当たり前にアクセスできる
        TextBox1.Text = foo
        TextBox2.Text = bar
        TextBox3.Text = hoge
        TextBox4.Text = foobar
    End Sub
End Class

リフレクションを使えば参照せずに、PJ02のフォームを表示できます。

今回使用してないけど、InvokeMember の一番最後の引数は、呼び出すメソッドの引数。
配列で渡してあげれば、引数付きコンストラクタ等も呼び出せる。

呼び出される側(子)のプロジェクト:PJ02

Imports PJ01

Public Class frmPJ_02
    Private Sub frmPJ_02_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' PJ01のモジュール内の変数だけど、インポートしてるので参照できる
        TextBox1.Text = foo
        TextBox2.Text = bar
        TextBox3.Text = hoge
        TextBox4.Text = foobar
    End Sub
End Class

ここでは、PJ01の変数にアクセスしたいので参照しています。
でも、PJ01はPJ02を参照していないので何の問題もありません。

まとめ

循環参照を避けて、別プロジェクトのフォームを開けるようになりました。
ですが、これ使わなくちゃいけなくなった場合、可能であれば設計を見直した方が良いと思います。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です