tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルMDI子フォームのSHOW
記事No1719
投稿日: 2005/05/24(Tue) 14:05
投稿者こう
[OSのVer]:Windows2000    [VBのVer]:VB.NET  

以前、MDIフォームについて質問をさせていただいたのですが、
その続きになります。

MDIの子フォームから、同じMDI内の別の子フォーム
をSHOWする方法を教えてもらえないでしょうか?

よろしくお願いします。

[ツリー表示へ]
タイトルRe: MDI子フォームのSHOW
記事No1720
投稿日: 2005/05/24(Tue) 15:14
投稿者るしぇ
> 以前、MDIフォームについて質問をさせていただいたのですが、
> その続きになります。
本当に話題が続いてるならリンク貼って下さい。

> MDIの子フォームから、同じMDI内の別の子フォーム
> をSHOWする方法を教えてもらえないでしょうか?
親に連絡して表示してもらって下さい。

[ツリー表示へ]
タイトルRe^2: MDI子フォームのSHOW
記事No1721
投稿日: 2005/05/24(Tue) 15:38
投稿者こう
[OSのVer]:Windows    [VBのVer]:VB.NET  

ご回答ありがとうございます。

> > 以前、MDIフォームについて質問をさせていただいたのですが、
> > その続きになります。
> 本当に話題が続いてるならリンク貼って下さい。

リンクの貼り方がわかりませんでした。
一応今回の質問は今回分だけで完結しています。
曖昧なことを言ってすみませんでした。

>
> > MDIの子フォームから、同じMDI内の別の子フォーム
> > をSHOWする方法を教えてもらえないでしょうか?
> 親に連絡して表示してもらって下さい。

具体的にどの様にすればよいでしょうか?

親フォームの中でPublic関数を作成し、
それを子フォームから呼ぼうとしたのですが、これでは
もう1つの子フォームが表示されませんでした。

以下に作成したモジュールの一部を記述します。
よろしくお願いします。

<親フォーム側の関数>
    Public Sub ShowChild()
        Dim frmValue As New FrmChild2
        frmValue.MdiParent = Me
        frmValue.Show()
    End Sub
<子フォーム1のイベント>
    Private Sub BtnShowChild2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles BtnShowChild2.Click
        Dim objMainForm As New FrmMain
        Call objMainForm.ShowChild()
    End Sub

[ツリー表示へ]
タイトルRe^3: MDI子フォームのSHOW
記事No1731
投稿日: 2005/05/24(Tue) 19:03
投稿者じゃんぬねっと
参照先http://jeanne.wankuma.com/
こんにちは、じゃんぬ です。

> リンクの貼り方がわかりませんでした。

これのことでしょうか?
hhttp://www.bcap.co.jp/hanafusa/bbs/wforum.cgi?mode=allread&no=1673&page=0

アドレスを貼るだけです。

> 親フォームの中でPublic関数を作成し、
> それを子フォームから呼ぼうとしたのですが、これでは
> もう1つの子フォームが表示されませんでした。

インスタンスが同一でないからですね。
以前にも同じコトを、こうさんに話した記憶があります。

[ツリー表示へ]
タイトルじゃんぬさんのレスに追加
記事No1735
投稿日: 2005/05/25(Wed) 09:04
投稿者るしぇ
じゃんぬさんのレスで十分に理解できる説明ですが、
>アドレスを貼るだけです。
掲示板の標準機能で
>以降が色変えで表示されます。
http://以降がリンクとして表示されます。
個々のスレッドのアドレスをテキストで打てばリンクを
貼る事になります。スレッドのアドレスは、一覧画面で
リンク先を右クリック『新しいウィンドウで開く』を
使えば簡単に分かります。…ま、掲示板の基本知識ですね。

>インスタンスが同一でないからですね。
同じ参照変数でも New すれば新しいインスタンスが
生成され、その参照が格納されます。それまで参照して
いたオブジェクトへの参照は、その変数からは開放
されてしまいます。…言ってる事が分からない場合は、
ヘルプで『変数の宣言』に関して勉強してきて下さい。
『New』や『変数の値型と参照型』について説明
できなければ、回答を続けても理解できないと
思います。

で、具体的には、操作したいフォームの全ての参照を
親が覚えておく必要があります。

[ツリー表示へ]
タイトルRe: じゃんぬさんのレスに追加
記事No1736
投稿日: 2005/05/25(Wed) 10:10
投稿者こう
[OSのVer]:Windows    [VBのVer]:VB.NET  
> じゃんぬさんのレスで十分に理解できる説明ですが、
> >アドレスを貼るだけです。
> 掲示板の標準機能で
> >以降が色変えで表示されます。
> http://以降がリンクとして表示されます。
> 個々のスレッドのアドレスをテキストで打てばリンクを
> 貼る事になります。スレッドのアドレスは、一覧画面で
> リンク先を右クリック『新しいウィンドウで開く』を
> 使えば簡単に分かります。…ま、掲示板の基本知識ですね。

ありがとうございます、わかりました。
掲示板初心者ですみません。
次回からリンクを貼るようにします。

>
> >インスタンスが同一でないからですね。
> 同じ参照変数でも New すれば新しいインスタンスが
> 生成され、その参照が格納されます。それまで参照して
> いたオブジェクトへの参照は、その変数からは開放
> されてしまいます。…言ってる事が分からない場合は、
> ヘルプで『変数の宣言』に関して勉強してきて下さい。
> 『New』や『変数の値型と参照型』について説明
> できなければ、回答を続けても理解できないと
> 思います。
>
> で、具体的には、操作したいフォームの全ての参照を
> 親が覚えておく必要があります。

じゃんぬねっとさん、るしぇさん、ありがとうございます。
できました。
MDI子フォーム1から子フォーム2をSHOWできました。

やり方は、以下のとおりです。
まず、各子フォームの変数をグローバルで保持しておき、
次に親フォームロード時にそれぞれの子フォームのMdiParentを自分にします。
最後に子フォーム1で子フォーム2用の変数をSHOWすれば
子フォーム2が表示されました。

ただ、このやり方だと一度子フォーム1から子フォーム2をSHOWしてしまえば
次に子フォーム1から子フォーム2はSHOWできないんです。。
(この変数は既に表示されたフォームに対して生成されたものなので。)
恐らくまだ根本的(基本的?)なところが理解できていないんだと
思います。
もう少し調べていきます。

[ツリー表示へ]
タイトルRe^2: じゃんぬさんのレスに追加
記事No1739
投稿日: 2005/05/25(Wed) 13:40
投稿者じゃんぬねっと
参照先http://jeanne.wankuma.com/
こんにちは、じゃんぬ です。

> やり方は、以下のとおりです。
> まず、各子フォームの変数をグローバルで保持しておき、
> 次に親フォームロード時にそれぞれの子フォームのMdiParentを自分にします。

グローバルは宜しくないですね。
親 MDI フォームのメンバであるべきですよね?

> 恐らくまだ根本的(基本的?)なところが理解できていないんだと思います。
> もう少し調べていきます。

まず、オブジェクト指向とかクラスとかそういったところから勉強してください。
それだけで、こうさんは飛躍的に伸びると感じます。

前発言の説明が不足で申し訳ありませんでした。
フォローありがとうございます > るしぇ さん

[ツリー表示へ]
タイトルRe^3: じゃんぬさんのレスに追加
記事No1740
投稿日: 2005/05/25(Wed) 14:18
投稿者こう
[OSのVer]:Windows    [VBのVer]:VB.NET  
> まず、オブジェクト指向とかクラスとかそういったところから勉強してください。
> それだけで、こうさんは飛躍的に伸びると感じます。
>
> 全開の説明が不足で申し訳ありませんでした。
> フォローありがとうございます > るしぇ さん

イメージではなんとなくはわかっているつもりなのですが、
具体的なところになるとまだまだ理解できていないようです。
根本的にVB.NETに必要となる知識⇒オブジェクト指向・クラスの概念
について勉強していきます。

丁寧な対応どうもありがとうございました。

[ツリー表示へ]
タイトルRe^4: じゃんぬさんの要求も満たしてると…
記事No1742
投稿日: 2005/05/25(Wed) 14:46
投稿者るしぇ
勉強していただく事を前提で、普通に勉強していたら見落としがちなテクニックを1つ。

親フォームで参照変数に子フォームの参照を入れた後、子フォームを閉じると、
親フォームで参照変数に既に閉じられた(破棄された)子フォームの参照が残り、
開放されません。子フォームが閉じた事を検知して参照変数に Nothing を設定し、
開放する必要があります。

あとは下記サンプルで勉強してみて下さい。じゃんぬさんの要求も満たしてると
思います。子フォームの参照変数はメンバとして公開してませんが。

※プロジェクトに Form1 Form2 Form3 を追加。Form2 に Botton1 を貼り付けて下さい。
[VB.NET]
'/////////////////////////
Option Explicit On
'/////////////////////////
'/// Form1.vb
'/////////////////////////
Public Class Form1
    Inherits System.Windows.Forms.Form

(省略)" Windows フォーム デザイナで生成されたコード "

    Friend WithEvents MainMenu1 As System.Windows.Forms.MainMenu
    Friend WithEvents MenuItem1 As System.Windows.Forms.MenuItem
    Private WithEvents ChildForm2 As Form2
    Private WithEvents ChildForm3 As Form3

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load
        Me.IsMdiContainer = True

        Me.MainMenu1 = New System.Windows.Forms.MainMenu
        Me.MenuItem1 = New System.Windows.Forms.MenuItem
        Me.MainMenu1.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.MenuItem1})
        Me.MenuItem1.Index = 0
        Me.MenuItem1.Text = "Form2.Show"
        Me.Menu = Me.MainMenu1
    End Sub

    Private Sub ChildForm2_Closing(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles ChildForm2.Closing
        Me.ChildForm2 = Nothing
    End Sub

    Private Sub ChildForm3_Closing(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles ChildForm3.Closing
        Me.ChildForm3 = Nothing
    End Sub

    Private Sub MenuItem1_Click(ByVal sender As 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

    Public Sub Form3_Show()
        If Me.ChildForm3 Is Nothing Then
            Me.ChildForm3 = New Form3
            Me.ChildForm3.MdiParent = Me
        End If
        Me.ChildForm3.Show()
        Me.ChildForm3.Activate()
    End Sub
End Class

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

(省略)" Windows フォーム デザイナで生成されたコード "

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles Button1.Click
        Try
            If TypeOf Me.MdiParent Is Form1 Then
                Call DirectCast(Me.MdiParent, Form1).Form3_Show()
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load
        Me.Button1.Text = "Form3.Show"
    End Sub
End Class

[ツリー表示へ]
タイトルRe^5: じゃんぬさんの要求も満たしてると…
記事No1745
投稿日: 2005/05/25(Wed) 16:02
投稿者じゃんぬねっと
参照先http://jeanne.wankuma.com/
> じゃんぬさんの要求も満たしてると思います。

本当は、子フォームから親フォームのインスタンスを取得して開くのではなく、
親に通知して "親から (親クラス内で) 自発的に" 開かせた方が良いと思います。
ただ、自分の親が誰なのか知ってるという時点で、うーん...
かと言って、親から子をずっと監視してる状態にしちゃうのも... うーん...
デリゲート通知... うーん...

難しいとこですね、ガチガチに考えずにある程度妥協した方が良いですね。

# ところで、解放は Nothing ではなく、Dispose() の方が適切じゃないですか?

[ツリー表示へ]
タイトルRe^6: じゃんぬさんの要求も満たしてると…
記事No1748
投稿日: 2005/05/25(Wed) 16:46
投稿者るしぇ
>本当は、子フォームから親フォームのインスタンスを取得して開くのではなく、
>親に通知して "親から (親クラス内で) 自発的に" 開かせた方が良いと思います。
なるほど。
[VB.NET]
'/////////////////////////
'/// Form2.vb
'/////////////////////////
    Public Event Form3_Show()

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles Button1.Click
        RaiseEvent Form3_Show()
    End Sub
で親フォーム側でイベント拾うとかどうですか?

># ところで、解放は Nothing ではなく、Dispose() の方が適切じゃないですか?
参照型の変数を初期化するのは Nothing を設定するので構わないと思ってます。
[Nothing]
hhttp://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vblr7/html/vakeyNothing.asp
処理の意味あいとしては、もしこれが親フォームの Dispose あたりの処理
だった場合は、親から Me.ChildForm2.Dispose を呼びますが、子が閉じる
イベントを親に通知してきた時は、閉じる処理は子に任せて、親は参照を
開放する…といった考えです。
ただ、子フォームのどのイベントを拾うか?というのは検討の余地ありかも?
ご指摘の Dispose あたりを考えるのも良いと思います。今回は閉じる処理を
意識して Closing を使ってあります。子フォームの動作とよく相談の上で
決めた方が良いと思います。

…というような議論ができるようなお勉強ができればいいかと思いますw>こうさん

[ツリー表示へ]
タイトルRe^7: じゃんぬさんの要求も満たしてると…
記事No1749
投稿日: 2005/05/25(Wed) 17:39
投稿者こう
[OSのVer]:Windows    [VBのVer]:VB.NET  

サンプルソースどうもありがとうございます。
親フォームの中で「WithEvents」というものを
発見しました。
この宣言をすれば子フォームのイベントを親フォームで
拾うことができるのですね。
親から呼ぶということがなかなか理解できなかったのですが、
これで少し理解できました。

[ツリー表示へ]
タイトルRe^8: じゃんぬさんの要求も満たしてると…
記事No1751
投稿日: 2005/05/25(Wed) 18:59
投稿者じゃんぬねっと
参照先http://jeanne.wankuma.com/
こんにちは、じゃんぬ です。

> 参照型の変数を初期化するのは Nothing を設定するので構わないと思ってます。

ああ、いけない。バラバラで見てました。(^^;)
批難しているわけではないので、忘れてください。

> 親フォームの中で「WithEvents」というものを発見しました。
> この宣言をすれば子フォームのイベントを親フォームで拾うことができるのですね。

WithEvents 自体は、多分普通に Windows アプリを作ってるなら、
何百も触ってると思いますよ。(見えないところにできますけど)

[ツリー表示へ]