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を参照していないので何の問題もありません。
まとめ
循環参照を避けて、別プロジェクトのフォームを開けるようになりました。
ですが、これ使わなくちゃいけなくなった場合、可能であれば設計を見直した方が良いと思います。
コメントを残す