MDI親フォームから子フォームの表示について

解決


のり  2004-10-14 00:22:34  No: 116957

VB.NETですが、
MDI親フォームのメニューから、子フォームの表示したいんですが、

Private Sub MenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem1.Click

        Dim ChildForm2 As New Form2

        ChildForm2.MdiParent = Me

        ChildForm2.Show()

End Sub

とすると、表示はされますが、メニューのクリックの度に新規フォームが作成されます。(当然なんですが・・・)
子フォームが表示されているときは、アクティブにする、とゆうような方法はないのでしょうか?

Public ChildForm2 As New Form2

を、モジュールに記述してみましたが、一度表示し閉じてしまうと、メニューをクリックしたときにエラーが発生します。

いろいろ探しては見ましたが分かりません。何か方法はあるのでしょうか?


特攻隊長まるるう  2004-10-14 01:09:37  No: 116958

まだ、MDIフォームでは試してないですが、原理としては
過去ログ検索『別フォーム』で引っ掛かる情報をいくつか
理解できれば実現できるでしょう。まず、

http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200405/04050010.txt

通常、別フォームの場合、子フォームに引数ありの New を
作成し、親フォームの参照を引数として渡してやります。
子フォームは自分が閉じる時に、この参照を使って親フォーム
に自分が閉じる事を知らせることが出来ます。まぁ、今回の
場合、MdiParent に設定してるようですので、それを使えば
いいですね。

実際のサンプルコードに近いのは

http://madia.world.coocan.jp/cgi-bin/VBBBS2/wwwlng.cgi?print+200409/04090099.txt

でしょうか?。別にモジュール起動にする必要はありませんよ。
あくまで親フォームと子フォームのやりとりを、親クラス(Class1)と
子クラス(Form1)のやりとりから盗んでみて下さい。


のり  2004-10-14 09:27:30  No: 116959

やっと出来ました…。

[VB.NET]
'/////////////////////////
Option Explicit On 
'/////////////////////////
'/// Class1.vb
'/////////////////////////
Public Class Class1

    Private Frm2 As Form2

    Friend Sub ShowFrm2(ByRef Frm1 As Form)

        If Me.Frm2 Is Nothing Then
            Me.Frm2 = New Form2(Me)
        End If

        Me.Frm2.MdiParent = Frm1

        Me.Frm2.Show()

        Me.Frm2.BringToFront()

    End Sub

    Friend Sub SetForm2Nothing()

        Me.Frm2 = Nothing

    End SubEnd Class

'/////////////////////////
Option Explicit On 
'/////////////////////////
'/// Form1.vb
'/////////////////////////
Public Class Form1
    Inherits System.Windows.Forms.Form

    ' Windows フォーム デザイナで生成されたコード

    Private mParentClass As New Class1

    Friend Sub New(ByRef ParentClass As Class1)

        Me.New()

        Me.mParentClass = ParentClass

    End Sub

    Private Sub MenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem1.Click

        Me.mParentClass.ShowFrm2(Me)

    End Sub

End Class

'/////////////////////////
Option Explicit On 
'/////////////////////////
'/// Form2.vb
'/////////////////////////
Public Class Form2
    Inherits System.Windows.Forms.Form

    ' Windows フォーム デザイナで生成されたコード

    Private mParentClass As Class1

    Public Sub New(ByRef ParentClass As Class1)

        Me.New()

        Me.mParentClass = ParentClass

    End Sub

    Private Sub Form2_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing

        Me.mParentClass.SetForm2Nothing()

    End Sub

End Class

という感じです。どうでしょう?
親フォームの設定を、引数で渡していなかったので、子フォームとならず、ちょっと苦労しました。
何冊か本も購入しやっていますが、まだまだ勉強不足のようです…。

特攻隊長まるるうさん、ありがとうございました!


のり  2004-10-14 09:30:22  No: 116960

チェックを忘れました。
解決しました。


特攻隊長まるるう  2004-10-14 18:38:20  No: 116961

うむ。面倒くさい事してるねw。ちゃんと理解できて
必要な部分だけ抜き出せればこれだけで済むと思うよ。
[VB.NET]
'/////////////////////////
Option Explicit On 
'/////////////////////////
'/// Form1.vb
'/////////////////////////
Public Class Form1
    Inherits System.Windows.Forms.Form

    [省略] Windows フォーム デザイナで生成されたコード

    Private ChildForm2 As Form2

    Friend Sub SetForm2Nothing()
        Me.ChildForm2 = Nothing
    End Sub

    Private Sub MenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem1.Click
        If Me.ChildForm2 Is Nothing Then
            Me.ChildForm2 = New Form2
            Me.ChildForm2.MdiParent = Me
        End If
        Me.ChildForm2.Show()
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.IsMdiContainer = True
    End Sub
End Class
'/////////////////////////
Option Explicit On 
'/////////////////////////
'/// Form2.vb
'/////////////////////////
Public Class Form2
    Inherits System.Windows.Forms.Form

    [省略] Windows フォーム デザイナで生成されたコード

    Private Sub Form2_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        Call CType(Me.MdiParent, Form1).SetForm2Nothing()
    End Sub

End Class


のり  2004-10-14 20:57:16  No: 116962

はい、確かにそうですね・・・。
もっと楽にとゆうか、スッキリとしたものになるんじゃないかとは、
感覚的に思って、チャレンジはしていたのですが・・・。
いえ、もっと勉強します。
何度もありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加