DOBON.NET DOBON.NETプログラミング掲示板過去ログ

親フォームと子フォームの操作方法について

環境/言語:[Windows XP/VB.NET]
分類:[.NET]

初めまして。
参考書片手にやっておりましたが、行き詰ったので質問させてください。

親フォーム(Form1)の中に子フォーム(Form2)を表示させています。
Form1プロパティ ⇒ IsMdiContainer ⇒ True

Form1(親)にメインメニューを作り、そこから新しい子フォーム(Form3)を開く方法は分かるんですが↓
  Dim frmC As Form
  frmC = New Form3()
  '▼子フォームを最大化
  frmC.WindowState = FormWindowState.Maximized
  frmC.MdiParent = Me
  frmC.Show()

Form2からForm3を開く方法が分かりません。
(Form2はボタンを使用してForm3を開こうとしてます)

重ねて質問なんですが、Form1の子ウィンドウに何も表示されていないとき、メインメニューにあるメニューの表示(Enabled)を消したい(False)にしたいんですが、子ウィンドウの情報の取り方ってありますか?

別サイトになりますが、親・子フォームの表示は↓こちらを参考にしました。
ttp://anetm.com/dev/tools/vbdotnet/112297.htm

宜しくお願いします。
■No7602に返信(くーさんさんの記事)
> Form2からForm3を開く方法が分かりません。
> (Form2はボタンを使用してForm3を開こうとしてます)

試してないけど。。。
Form2から次のようにしたら開くことは開くんじゃないかな。

  Dim frmC As Form
  frmC = New Form3()
  frmC.WindowState = FormWindowState.Maximized
  frmC.MdiParent = Me.MdiParent
  frmC.Show()

ただ、これだと後の使い勝手がわるいよーな。

Form1の中にForm3を開くためのPublicなメソッドを用意して、
Form2でボタンが押されたときに、そのメソッドを呼び出す、
という方法でいけるんじゃないかと思います。
2004/11/24(Wed) 12:52:55 編集(投稿者)

【1番目の】:
Form1で、ボタンのイベント処理に直接Form2やForm3の呼出しを記述せず、
別にpublicなメソッドとして作成してイベント処理では単にそれ(createForm2等)を
呼ぶようにして、
Form2では
directcast(Form2.MDIparent,Form1Class).createForm2()
とかすればできるかと。
MDIparentからアクセスするのは嫌だというのであれば、Form2にForm1への参照を保持する
フィールド(例えばpublic ManagerForm As Form1)を持たせて、
Form1側でnewした後にセットしておけばいい。
そうすれば、
me.ManagerForm.createForm2()
とかしてアクセスできる。


【2番目の】:

'Formは管理のためMDIの子を配列で保持するので、それを利用すればいいだけです。
'例えばプロパティを作るなら、以下のようなかたちでしょうか。
'(まぁ、わざわざプロパティにするまでもないのですが。)
Private ReadOnly Property hasMdiChildren() As Boolean
  Get
    If Me.MdiChildren.Length() <= 0 Then
      Return False
    Else
      '@単純に配列に何か入っていたらtrueを返す。
      Return True
      'Aもしくは・・・
      '配列が遅延で反応するんだという前提で処理する疑心暗鬼な人は、
      '破棄されていないフォームが配列に残っているか確認・・・。
      Dim exstC As Boolean = False
      For Each f As Form In Me.MdiChildren
        If f.IsDisposed <> True Then
          exstC = True
          Exit For
        End If
      Next
      Return exstC
    End If
  End Get
End Property

こんなとこでしょうか。
小野@どっとねっとふぁん さん
こど。 さん
回答ありがとうございます

1番目の方法は、小野@どっとねっとふぁんさんの方法で上手くいきました。
メニューの『ウィンドウ』の開いてる子ウィンドウを全て表示させたかったもので。

2番目の回答で
> Private ReadOnly Property hasMdiChildren() As Boolean
> Get
> If Me.MdiChildren.Length() <= 0 Then
> Return False
> Else
> '@単純に配列に何か入っていたらtrueを返す。
> Return True
> 'Aもしくは・・・
> '配列が遅延で反応するんだという前提で処理する疑心暗鬼な人は、
> '破棄されていないフォームが配列に残っているか確認・・・。
> Dim exstC As Boolean = False
------> For Each f As Form In Me.MdiChildren
> If f.IsDisposed <> True Then
> exstC = True
> Exit For
> End If
> Next
> Return exstC
> End If
> End Get
> End Property

------>の所が構文エラーになってしまい、『名前'f'は宣言させていません。』と出てしまいます。

結果として何がしたいかと言うと…、

ファイル│ウィンドウ
閉じる │***

で、子ウィンドウに何も表示してない時、ファイルの『閉じる』のEnabledをFalseにしたいのです。
良く分かってない者で申し訳ないです。
宜しくお願いします。
> ------>の所が構文エラーになってしまい、『名前'f'は宣言させていません。』と出てしまいます。

 VB.NET 2002 ( 或いは VS.NET 2002 ) で開発されているのですね。
 その構文は .NET Framework 1.1 以上でなければ使用できません。以下の 2 行に置き換えてみてください。

Dim f As Form
For Each f In Me.MdiChildren


#でも↓じゃ駄目だったのかなぁと素朴な疑問。疑心暗鬼なのかしら?
> ' 1. 単純に配列に何か入っていたらtrueを返す。
※丸数字は書き換えてます。

DOBON.NET | プログラミング道 | プログラミング掲示板