C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

MDI子フォームの最大化時のウインドウキャプション /まりもん (25/07/11(Fri) 15:06) #103769
Re[1]: MDI子フォームの最大化時のウインドウキャプション /魔界の仮面弁士 (25/07/11(Fri) 16:52) #103770
  ├ Re[2]: MDI子フォームの最大化時のウインドウキャプション /まりもん (25/07/11(Fri) 17:27) #103772
  │└ Re[3]: MDI子フォームの最大化時のウインドウキャプション /魔界の仮面弁士 (25/07/11(Fri) 19:19) #103773
  └ Re[2]: MDI子フォームの最大化時のウインドウキャプション /魔界の仮面弁士 (25/07/11(Fri) 17:11) #103771


親記事 / ▼[ 103770 ]
■103769 / 親階層)  MDI子フォームの最大化時のウインドウキャプション
□投稿者/ まりもん (5回)-(2025/07/11(Fri) 15:06:13)

分類:[.NET 全般] 

.NET Framework4.8にてWinFormアプリケーションを作成しています。

MDI親フォームにPanelを配置しDock.Leftで左寄せで表示しているのですが
MDI子フォームを表示し、そのフォームを最大化するとウインドウキャプションが親ウインドウの幅全体で表示され左側に配置したパネルがキャプション分下に下がってしまいます。
最大化した子フォームのウインドウキャプションをMdiClientの領域のみに表示することは可能なのでしょうか?
[ □ Tree ] 返信 編集キー/

▲[ 103769 ] / ▼[ 103772 ] ▼[ 103771 ]
■103770 / 1階層)  Re[1]: MDI子フォームの最大化時のウインドウキャプション
□投稿者/ 魔界の仮面弁士 (3861回)-(2025/07/11(Fri) 16:52:55)
No103769 (まりもん さん) に返信
> MDI親フォームにPanelを配置しDock.Leftで左寄せで表示しているのですが
> MDI子フォームを表示し、そのフォームを最大化するとウインドウキャプションが親ウインドウの幅全体で表示され左側に配置したパネルがキャプション分下に下がってしまいます。
そういうものですね。

仮に 子フォームが FormBorderStyle.None であったとしても、
子フォームが最大化されれば同様の動作になります。


> 最大化した子フォームのウインドウキャプションをMdiClientの領域のみに表示することは可能なのでしょうか?
MDI であることに拘りが無いのなら、Left パネルの隣に
 Dock = Fill
 BackColor = AppWorkspace
 BorderStyle = Fixed3D
なパネルを置いて、それを元の MdiClient 代わりにするのはどうでしょうか。


C# か VB か分からなかったので、とりあえず VB で書いてみました。


'Form1: MDI親フォーム
Public Class Form1

  Private WithEvents mdiClient As MdiClient
  Protected Overrides Sub OnLoad(e As EventArgs)
    mdiClient = Controls.OfType(Of MdiClient).FirstOrDefault()
    MyBase.OnLoad(e)
  End Sub

  Private Sub mdiClient_ControlAdded(sender As Object, e As ControlEventArgs) Handles mdiClient.ControlAdded
    Dim child = TryCast(e.Control, Form)
    If child IsNot Nothing Then
      child.MdiParent = Nothing
      child.TopLevel = False
      child.Parent = Me.Panel2  '右側の Dock パネル
    End If
  End Sub


  Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
    'Form2: MDI 子フォーム
    Dim c As New Form2() With {.MdiParent = Me}
    c.Show()
  End Sub
End Class


この場合、MdiClient が Panel で覆われていることから、
実質的に MDI としての役割を果たせないので、
実際には IsMdiContainer を True にする必要も無いのですけれども。

[ 親 103769 / □ Tree ] 返信 編集キー/

▲[ 103770 ] / ▼[ 103773 ]
■103772 / 2階層)  Re[2]: MDI子フォームの最大化時のウインドウキャプション
□投稿者/ まりもん (6回)-(2025/07/11(Fri) 17:27:11)
No103770 (魔界の仮面弁士 さん) に返信
>>最大化した子フォームのウインドウキャプションをMdiClientの領域のみに表示することは可能なのでしょうか?
> MDI であることに拘りが無いのなら、Left パネルの隣に
>  Dock = Fill
>  BackColor = AppWorkspace
>  BorderStyle = Fixed3D
> なパネルを置いて、それを元の MdiClient 代わりにするのはどうでしょうか。

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

提示いただいたサンプルを試してみたのですが、子フォームをMDIの領域の外に出るように移動したところ
Panel2にはスクロールバーが表示されません。

Panel2のAutoScrollプロパティをTrueにしてもスクロールバーが表示されませんでしたが子フォームが複数あり
子フォームのZオーダーを変更するとスクロールバーが表示されました。
またスクロールバーが表示された状態で子フォームを最小化した後元に戻したときなどにフォームを動かせなくなったり
など挙動がおかしい時がありました。

上記のことからこの方法を使用するときは子フォームが外に出ないよう移動制限をかけて使用したいと思います。

現在は通常のMDIとして子フォームが最大化された時に子フォーム側で
最大化解除&ボーダーなし&クライアント領域のサイズにサイズ変更&キャプションを自前で描画
といった処理を行うようにするといったことも考えています。
こちらの場合は子フォームに配置するコントロールをどうするかといったことを考えないといけないかと思いますが
[ 親 103769 / □ Tree ] 返信 編集キー/

▲[ 103772 ] / 返信無し
■103773 / 3階層)  Re[3]: MDI子フォームの最大化時のウインドウキャプション
□投稿者/ 魔界の仮面弁士 (3863回)-(2025/07/11(Fri) 19:19:18)
2025/07/11(Fri) 19:40:55 編集(投稿者)

No103772 (まりもん さん) に返信
> 提示いただいたサンプルを試してみたのですが、子フォームをMDIの領域の外に出るように移動したところ
> Panel2にはスクロールバーが表示されません。

移動時に PerformLayout を呼び出してみると、
スクロールバーが追従されるかと思います。

Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
 'Form2: MDI 子フォーム
 Dim c As New Form2() With {.MdiParent = Me}
 c.Show()
 AddHandler c.Move, Sub() Panel2.PerformLayout()
End Sub
 
あー。でも、Panel2 を AutoScroll にした状態だと
子フォームを最大化しているときに、余計な余白が空いてしまいますね。

そもそも、AutoScorll が有効な場合の最大化領域ってどうあるべきなのだろう…。
最大化時は AutoScroll をオフにするなどの制御も必要なのかも。


子フォームを最大化している最中に親フォームがリサイズされた場合に
子フォームをリサイズする必要もありますね。色々大変そう。
[ 親 103769 / □ Tree ] 返信 編集キー/

▲[ 103770 ] / 返信無し
■103771 / 2階層)  Re[2]: MDI子フォームの最大化時のウインドウキャプション
□投稿者/ 魔界の仮面弁士 (3862回)-(2025/07/11(Fri) 17:11:44)
2025/07/11(Fri) 17:13:44 編集(投稿者)

No103770 (魔界の仮面弁士) に追記
> MDI であることに拘りが無いのなら、Left パネルの隣に
>  Dock = Fill
>  BackColor = AppWorkspace
>  BorderStyle = Fixed3D
> なパネルを置いて、それを元の MdiClient 代わりにするのはどうでしょうか。

この似非MDIフォーム案の場合、本来の MDIフォームとは下記の差異が生じます。

1) 子フォームを最大化した場合、
 MDIフォームなら、親フォームのタイトルが "Form1 - [Form2]" 形式になるが
 似非MDIの場合は変化しない。

2) 親子双方が MenuStrip を装備していた場合、
 MDIフォームなら、親子のメニューが統合され、メニューが親側だけに配置されるが
 似非MDIの場合はメニューは統合されず、それぞれ独立して表示される。

3) 親子双方が MenuStrip を装備していない状態で子フォームが最大化した場合、
 MDIフォームなら、MdiClient の上部に子フォームのタイトルバー部が現れる(Panel1がその分下に下がる)が
 似非MDIの場合は、Panel1には変化が無く、Panel2内の上部に子フォームのタイトルバーが来る。
 ※この時、要件次第では子フォームをボーダーレスフォームに変更した方が良いかもしれない。

4) 似非MDIフォームの場合、MdiChildren が機能しない(MdiParent を使わないため)
[ 親 103769 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -