none
MDI子フォームのコントロールボックスを非表示にするには RRS feed

  • 質問

  • 題名の通りなのですが、MSDNの説明ではVB2005では「ControlBox=Falseでは非表示になりません」と有りました。

    これを実現するにはどのようにしたら良いのでしょうか?

     よろしくお願いいたします。

    2008年3月30日 8:53

回答

  • Me.Text = String.Empty は追加されていますでしょうか?

    2008年4月2日 15:49
    モデレータ
  • 外池です。対症療法的な回答で申し訳ありませんが、次の手順であれば大丈夫のようです。

     

    子フォームについて、WindowStateをMaximizeに、Textをリセットに、IDEのプロパティーウィンドウで設定する。つぎに、LoadイベントにおいてControlBoxをFalseにする。具体的にコードで書くと、少し長くなりますが以下の通りです。

     

    ここに示すコードのうち、「Partial Class 」で始まる部分は、ご存知かもしれませんが、IDEのプロパティーウィンドウで設定すると自動的に書き込まれるコードで、~.Designer.vbという拡張子のファイルに入っています。あと、Loadイベントに書く代わりに、私の趣味でProtectedなOnLoadメソッドに書くようにしていますが、ここらへんはネット移行者さんの流儀で書いてもらっても大丈夫かと思います。

     

    Code Snippet

    Public Class Form2
        Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
            MyBase.OnLoad(e)
            Me.ControlBox = False
        End Sub
    End Class

     

    <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
    Partial Class Form2
        Inherits System.Windows.Forms.Form

        'フォームがコンポーネントの一覧をクリーンアップするために dispose をオーバーライドします。
        _
        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            Try
                If disposing AndAlso components IsNot Nothing Then
                    components.Dispose()
                End If
            Finally
                MyBase.Dispose(disposing)
            End Try
        End Sub

        'Windows フォーム デザイナで必要です。
        Private components As System.ComponentModel.IContainer

        'メモ: 以下のプロシージャは Windows フォーム デザイナで必要です。
        'Windows フォーム デザイナを使用して変更できます。 
        'コード エディタを使って変更しないでください。
        _
        Private Sub InitializeComponent()
            Me.SuspendLayout()
            '
            'Form2
            '
            Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 12.0!)
            Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
            Me.ClientSize = New System.Drawing.Size(292, 273)
            Me.Name = "Form2"
            Me.WindowState = System.Windows.Forms.FormWindowState.Maximized
            Me.ResumeLayout(False)

        End Sub
    End Class

     

    親フォームは、以下のとおりです。

     

    Code Snippet

    Public Class Form1
        Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
            MyBase.OnLoad(e)
            Dim cf As New Form2
            cf.MdiParent = Me
            cf.Show()
        End Sub
    End Class

     

    <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
    Partial Class Form1
        Inherits System.Windows.Forms.Form

        'フォームがコンポーネントの一覧をクリーンアップするために dispose をオーバーライドします。
        <System.Diagnostics.DebuggerNonUserCode()> _
        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            Try
                If disposing AndAlso components IsNot Nothing Then
                    components.Dispose()
                End If
            Finally
                MyBase.Dispose(disposing)
            End Try
        End Sub

        'Windows フォーム デザイナで必要です。
        Private components As System.ComponentModel.IContainer

        'メモ: 以下のプロシージャは Windows フォーム デザイナで必要です。
        'Windows フォーム デザイナを使用して変更できます。 
        'コード エディタを使って変更しないでください。
        <System.Diagnostics.DebuggerStepThrough()> _
        Private Sub InitializeComponent()
            Me.SuspendLayout()
            '
            'Form1
            '
            Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 12.0!)
            Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
            Me.ClientSize = New System.Drawing.Size(292, 273)
            Me.IsMdiContainer = True
            Me.Name = "Form1"
            Me.Text = "Form1"
            Me.ResumeLayout(False)

        End Sub

    End Class

     

     

    2008年4月7日 0:08
  • 外池です。コメントアウトした行は、本来、必要なものでしょう・・・。うーん、手詰まりですね。

     

    ここまでの試行錯誤で、

      共存するコントロールとの関係で挙動が変化する、

    あるいは、

      子フォームのプロパティーを、Newで設定するか、Loadイベントで設定するか、によって挙動が変化する、

    ということが判ってきたわけで、

     

    すいません、申し上げにくいことですが、私のコメントと申しますか、私ならこうする、というのは、

      MDIを諦めては?

    ということになりそうです。

     

    すでにご説明いただいているように、

      親フォームの中で子フォームが常に最大化されており、

      子フォームが複数あるものの、そのうちの一つだけを選択して(切り替えて)表示する

    ということでしたよね? これは、本来のMDIとは違うように思うのです。

     

    子フォームが一つの種類しかないのであれば、なおさらですし、複数の種類ある場合でも、親フォームに貼り付けるコンテナ(Panel、GroupBox、TabControlなどのコントロールのこと)を使うことを検討されてはいかがでしょうか? それほど大きな変更にはならないと思います。子フォームのコードを、コントロールの定義も含めて、移植すればなんとかなるかと。

     

    あるいは、子フォームが一つの種類しかない場合(つまり、表示の切り替えを行っても、画面上に現れているコントロールの種類や数に変更がないのであれば)、

      1) コントロールのプロパティーを保存する変数と、表示するデータを保存する変数を内蔵する独自のクラスを作り、

      2) インスタンスを複数つくってやります。

      3) で、表示するインスタンスを切り替えるごとに、コントロールのプロパティーや表示データを、

      インスタンスが内蔵しているデータを作って更新してやる。

    こんな感じの設計も考えられます。

     

     

     

     

     

    2008年4月8日 4:08
  • 今頃ですが試しに作成してみましたところ、何の問題もなく簡単にできてしまいました。

     

    まず、ヘルプに書かれている「作成時に最大表示されるマルチ ドキュメント インターフェイス (MDI) 子フォームの場合、ControlBox プロパティを false に設定しても影響はありません。」についてですが、これは間違いだと思います。親メニューの左隅や右隅のアイコンの有無に影響しますので。また、最大表示でない場合は通常のフォームと同様の動作になります。

     

    終わりかけの話を蒸し返すようですが、試しに以下の手順どおりに行ってみてもらえませんでしょうか?
    この結果とご要望の話とは異なりますでしょうか?
    # これはあくまで検証用のため、Form1 をメインフォームのままにしています。

     

    1. VS2005 にてプロジェクトを新規作成する(Windows アプリケーションを選択)。
    2. ソリューションエクスプローラのプロジェクト名("Windows.Application1" など)で右クリックし、
       「追加」、「新しい項目」を順にポイントし、「MDI 親フォーム」を選択する。
    3. 作成された MDIParent1 フォームにて、メニューの「ファイル」の「新規作成」をダブルクリックする。
    4. ShowNewForm メソッドの最後にある ChildForm.Show() の直前に、次のコードを追加する。
            ChildForm.ControlBox = False
            ChildForm.WindowState = FormWindowState.Maximized
    5. ソリューションエクスプローラの "Form1.vb" をダブルクリックする。
    6. Form1 フォームをダブルクリックし、Form1_Load イベントハンドラに次のコードを記述する。
            Dim f As New MDIParent1
            f.ShowDialog()
    7. アプリケーションを実行し、メニューの「ファイル」、「新規作成」を実行する。

     

    この手順にて、タイトルバーが見えず、コントロールボックス等も表示されない MDI 子フォームが表示されることが確認できると思います。

     

    ネット移行者さんのアプリケーションでは、MDI 子フォームは通常のフォームで作成されていると思いますが、もしかすると上記 ShowNewForm メソッドの中にある ChildForm.MdiParent = Me のようなコードを書かれてないために、通常のフォームになっているのではないでしょうか?

    2008年4月8日 5:38
  • 外池です。

     

    私も、当初、TH01さんが仰るとおり、なんの問題も内容に思えたのですが・・・、相当面倒なことになりそうな気がします。

     

    ネット移行者さんが既にお手元にいろいろなコントロールが載っているFormがあって苦戦なされていることに比べて、TH01さんや私は、まったく新しいプロジェクトから始めて、素っぴんの親フォームと子フォームで挙動を調べているわけで・・・、

     

    素っぴんフォームでやっていると、TH01さんが仰るように、「お? これなら望みの挙動になる」という書き方は比較的簡単に見つかります。

     

    ただ、子フォームのNewに書くか(IDEでプロパティーを設定することに相当)それともLoadイベントに書くか(これは私がやってみたパターン)、あるいは、親フォームで子フォームを表示する直前にプロパティーで設定するか(TH01さんのパターン)によって、挙動がいろいろ変わるようで・・・

     

    そうなると、ネット移行者さんの現状のコードの場合、どれだと上手く行って、どれだとダメなのか・・・、きちっと理由もわかった上で納得できるコードを書くことが非常に難しくなりそうです。

     

    んで・・・、将来のVBのバージョンアップでも動作が一貫していることの約束はとても出来ない・・・。

     

    私が諦める方向の発言をした真意は、こんな感じです。
    2008年4月8日 6:08

すべての返信

  • これはVB6.0では出来ていたのですが、この子フォームのキャプションバーが一行、必要なく無駄なスペースに成っていますので

    何とか削除してフォームをすっきりさせたいのですが・・・・・。

     

    2008年3月30日 15:19
  • ControlBox = False にして、Text をstring.Emptyにする方法はどうでしょう? (見た目が悪い?)
    2008年3月31日 1:08
    モデレータ
  • trapemiya様、コメント有難うございます。

     

    この部分が良く判らないのですが、「Text をstring.Emptyにする方法はどうでしょう?」

    つまり、子FormのLoadイベントに Me.Text =String.Emptyを追加すると言うことでしょうか?

     これは試して見ましたが、何も変わりませんでした。

    現在、子フォームのキャプションバーの左側にVB2005のアイコンと右側にMax、Miniと×のコントロールボックスが有り何も役目を持たずにスペースだけを占有しています。

    これによって子フォームの表示領域が削られてしまいますので何とかお願いいたします。

     

     

    2008年3月31日 16:01
  • 外池です。

     

    子Formのキャプションバーを丸ごと無しにしたい、ということでしょうか? 子FormのFormBorderStyleをNoneでキャプションバーも輪郭も全部なくなりますが・・・。ただ、親Formの中で子Formの位置を変更するためのプログラムは独自に書いてやらないとダメなようですが。

     

    ちょっと基本に立ち返ると・・・、

     

    MDIというスタイルと言いますか、文字通りインターフェイスの標準的なあり方を考えると、キャプションバーを無くすことはあまり好ましいとは思えないのですが。子フォームの表示領域の大きさについて、非常にシビアな譲れない仕様があるのでしょうか?

     

    ----- 追記します -----

     

    実行時じゃなくても、IDEのデザイナ(プロパティーの表示)での操作でも、

    子FormのFormBorderStyleをデフォルトのSizable、

    ControlBoxをFalse、

    Textを空

    にして実行すると、キャプションバーは、丸ごと無くなりますね・・・。で、輪郭は3D風に出ます。ただ・・・、やはり子Formの位置の変更は独自にプログラムしてやらないといけないようです。

     

     

     

    2008年4月1日 0:26
  •  ネット移行者 さんからの引用

    つまり、子FormのLoadイベントに Me.Text =String.Emptyを追加すると言うことでしょうか?

     これは試して見ましたが、何も変わりませんでした。

     

    その通りです。もしくはデザイナでTextプロパティを空白にしてしまっても良いです。

    あと、肝心なことを書くことを忘れていました。

    FormBorderStyleをSizableにして下さい。

    ごめんなさい。

     

    #あっ、外池さんが追記されていますね。

     

    これでダメならWndProcをオーバーライドする方法になると思いますが、どの程度見た目が変わるかですね。

    2008年4月1日 0:38
    モデレータ
  • trapemiya 様、外池様、ご教授有難うございます。

     

    子フォームのLoadイベントに

            Me.MinimizeBox = False
            Me.MaximizeBox = False
            Me.ControlBox = False
            Me.WindowState = System.Windows.Forms.FormWindowState.Maximized
            Me.FormBorderStyle = Windows.Forms.FormBorderStyle.Sizable
    をセットして見ましたが相変わらず、VB2005アイコン及びコントロールボックスを乗せたバーが表示されています。

    そのコントロールボックスにはアイコン化ボタン、標準化ボタン、×ボタンが表示されていて、標準化ボタンを押すとスクロールバーがついてキャプションバー付き子フォームが表示されます。

     

     親フォームのMDIForm1にはToolBar1が追加されていて、イメージリストからアイコンを数点並べてありその上部に今回の不要の子フォームのキャプションバーが有り、その上に親フォームのキャプションバーが有ります。

    当ソフトは一応、子フォームを最大表示し、子フォームの「NEXT」ボタンを押すと次の子フォームが最大表示されて順次同様にいく仕様なのでコントロールボックスは不要なのです。

     

     これを解決するには難しい手順を踏まなければならないようでしたらなんとか仕様を変更してコントロールボックスと共存するようにしたいと思います。

     

     

     

    2008年4月2日 13:44
  • Me.Text = String.Empty は追加されていますでしょうか?

    2008年4月2日 15:49
    モデレータ
  • 外池です。

     

    子フォームのLoadイベントに書くと、よろしくないようです。差し支えなければ、IDEのプロパティー設定でやっちゃってください。

     

    私の手元の環境(VS2005)でも、

     

    まず・・・、子フォームのLoadイベントに

            Me.WindowState = FormWindowState.Maximized
            Me.ControlBox = False
            Me.Text = ""
    と書くと、確かに、子フォームのコントロールボックスが現れてしまいます。これは、ネット移行者さんの仰るとおりです。

     

    しかし、 Me.WindowState = FormWindowState.Maximizedを削除して、IDEのプロパティーで同様の設定をしてやると、ネット移行者さんのご希望の動作になりました。コントロールボックスなし、タイトル行もなし。同様に、ControlBoxをFalseにするのも、Me.Textを空にするのも、IDEのプロパティーで設定した方が良いようです。

     

    ちなみに・・・、子フォームのインスタンスの作成、親フォームの登録、表示は、親フォームのLoadイベントでやっています。

     

     

    2008年4月3日 1:32
  •  trapemiya さんからの引用

    Me.Text = String.Empty は追加されていますでしょうか?

     

    子フォームのLoadイベントに追加しています。

     

    2008年4月4日 19:35
  •  外池 さんからの引用

    子フォームのLoadイベントに書くと、よろしくないようです。差し支えなければ、IDEのプロパティー設定でやっちゃってください。

     

    ちなみに・・・、子フォームのインスタンスの作成、親フォームの登録、表示は、親フォームのLoadイベントでやっています。

     

    デザインモードで

            Me.MinimizeBox = False
            Me.MaximizeBox = False
            Me.ControlBox = False
            Me.WindowState = System.Windows.Forms.FormWindowState.Maximized
            Me.FormBorderStyle = Windows.Forms.FormBorderStyle.Sizable

    を全てを設定しているのですが、駄目です。

     

    子フォームはインスタンスを作成しないで、ダイレクトにfrmMenu.show()を親MdiFormから表示しています。

    親MdiFormのToolbar1コントロールが有ると良くないのかも、しかし、これは削除できないし・・・・・。

     

    2008年4月4日 19:45
  •  ネット移行者 さんからの引用

    相変わらず、VB2005アイコン及びコントロールボックスを乗せたバーが表示されています。

    そのコントロールボックスにはアイコン化ボタン、標準化ボタン、×ボタンが表示されていて、標準化ボタンを押すとスクロールバーがついてキャプションバー付き子フォームが表示されます。

     

    と記述しましたが、標準化ボタンとは「元に戻すボタン」です。訂正します。

    そしてそのボタンを押すと望みどおりコントロールボックスを乗せたキャプションバーは表示されなくなり、水平・垂直スクロールバーが表示されます。出来れば、最初から、キャプションバー、スクロールバーが無い方が良いのです。

     

    2008年4月5日 16:14
  • 外池です。対症療法的な回答で申し訳ありませんが、次の手順であれば大丈夫のようです。

     

    子フォームについて、WindowStateをMaximizeに、Textをリセットに、IDEのプロパティーウィンドウで設定する。つぎに、LoadイベントにおいてControlBoxをFalseにする。具体的にコードで書くと、少し長くなりますが以下の通りです。

     

    ここに示すコードのうち、「Partial Class 」で始まる部分は、ご存知かもしれませんが、IDEのプロパティーウィンドウで設定すると自動的に書き込まれるコードで、~.Designer.vbという拡張子のファイルに入っています。あと、Loadイベントに書く代わりに、私の趣味でProtectedなOnLoadメソッドに書くようにしていますが、ここらへんはネット移行者さんの流儀で書いてもらっても大丈夫かと思います。

     

    Code Snippet

    Public Class Form2
        Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
            MyBase.OnLoad(e)
            Me.ControlBox = False
        End Sub
    End Class

     

    <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
    Partial Class Form2
        Inherits System.Windows.Forms.Form

        'フォームがコンポーネントの一覧をクリーンアップするために dispose をオーバーライドします。
        _
        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            Try
                If disposing AndAlso components IsNot Nothing Then
                    components.Dispose()
                End If
            Finally
                MyBase.Dispose(disposing)
            End Try
        End Sub

        'Windows フォーム デザイナで必要です。
        Private components As System.ComponentModel.IContainer

        'メモ: 以下のプロシージャは Windows フォーム デザイナで必要です。
        'Windows フォーム デザイナを使用して変更できます。 
        'コード エディタを使って変更しないでください。
        _
        Private Sub InitializeComponent()
            Me.SuspendLayout()
            '
            'Form2
            '
            Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 12.0!)
            Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
            Me.ClientSize = New System.Drawing.Size(292, 273)
            Me.Name = "Form2"
            Me.WindowState = System.Windows.Forms.FormWindowState.Maximized
            Me.ResumeLayout(False)

        End Sub
    End Class

     

    親フォームは、以下のとおりです。

     

    Code Snippet

    Public Class Form1
        Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
            MyBase.OnLoad(e)
            Dim cf As New Form2
            cf.MdiParent = Me
            cf.Show()
        End Sub
    End Class

     

    <Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
    Partial Class Form1
        Inherits System.Windows.Forms.Form

        'フォームがコンポーネントの一覧をクリーンアップするために dispose をオーバーライドします。
        <System.Diagnostics.DebuggerNonUserCode()> _
        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            Try
                If disposing AndAlso components IsNot Nothing Then
                    components.Dispose()
                End If
            Finally
                MyBase.Dispose(disposing)
            End Try
        End Sub

        'Windows フォーム デザイナで必要です。
        Private components As System.ComponentModel.IContainer

        'メモ: 以下のプロシージャは Windows フォーム デザイナで必要です。
        'Windows フォーム デザイナを使用して変更できます。 
        'コード エディタを使って変更しないでください。
        <System.Diagnostics.DebuggerStepThrough()> _
        Private Sub InitializeComponent()
            Me.SuspendLayout()
            '
            'Form1
            '
            Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 12.0!)
            Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
            Me.ClientSize = New System.Drawing.Size(292, 273)
            Me.IsMdiContainer = True
            Me.Name = "Form1"
            Me.Text = "Form1"
            Me.ResumeLayout(False)

        End Sub

    End Class

     

     

    2008年4月7日 0:08
  •  

    外池様、ご丁寧な回答有難うございます。

     

    ご教授の手順でためしてみましたが、同じ状態でした。

    その手順で、子フォームのデザイナーコードのToolbar1に関する記述に’を入れたら解決しました。

    しかし、デザイナーのこのコードを削除しても良いのでしょうか?

     

     <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
            Me.components = New System.ComponentModel.Container
            Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(frmBGDmenu))
            '
            '
            '
            '
            '
            '
            ' frmMenu
            '
            Me.AutoScaleDimensions = New System.Drawing.SizeF(7.0!, 16.0!)
            Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
            Me.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink
            Me.AutoValidate = System.Windows.Forms.AutoValidate.Disable
            Me.BackColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(0, Byte), Integer), CType(CType(128, Byte), Integer))
            Me.ClientSize = New System.Drawing.Size(955, 581)
            Me.Controls.Add(Me.Button1)
            Me.Controls.Add(Me.FramMaisyuu)
            Me.Controls.Add(Me.FramSaisyo)
            Me.Controls.Add(Me.TabStripMain)
            Me.Controls.Add(Me.cmdKukanYosouHozon)
            Me.Controls.Add(Me.Frame2)
            Me.Controls.Add(Me.cmdTokubetu)
            Me.Controls.Add(Me.fraWARS)
            Me.Controls.Add(Me.cmdExit)
            Me.Controls.Add(Me.Command1)
            Me.Controls.Add(Me.cmdPrint)
            Me.Controls.Add(Me.cmdEND)
            Me.Controls.Add(Me.cmdSEISEKI)
            Me.Controls.Add(Me.cmdYouso)
            Me.Controls.Add(Me.Frame1)
            Me.Controls.Add(Me.Label7)
            Me.Controls.Add(Me.Label6)
            Me.Controls.Add(Me.Label5)
            Me.Controls.Add(Me.Label3)
            Me.Controls.Add(Me.Label1)
            Me.Controls.Add(Me.Image1)
            Me.Cursor = System.Windows.Forms.Cursors.Default
            Me.DoubleBuffered = True
            Me.Font = New System.Drawing.Font("Century", 9.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
            Me.Name = "frmBGDmenu"
            Me.RightToLeft = System.Windows.Forms.RightToLeft.No
            Me.ShowIcon = False
            Me.ShowInTaskbar = False
            Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
            Me.StartPosition = System.Windows.Forms.FormStartPosition.Manual
            Me.WindowState = System.Windows.Forms.FormWindowState.Maximized
            Me.FramMaisyuu.ResumeLayout(False)
            Me.FramSaisyo.ResumeLayout(False)
            Me.Frame2.ResumeLayout(False)
            Me.fraWARS.ResumeLayout(False)
            Me.Frame1.ResumeLayout(False)
            CType(Me.Image1, System.ComponentModel.ISupportInitialize).EndInit()
            ' CType(Me.TabStripMain, System.ComponentModel.ISupportInitialize).EndInit() ← この行を削除したらcontrolBoxが消えました。
            Me.ResumeLayout(False)

        End Sub

     

    2008年4月7日 14:48
  • 外池です。コメントアウトした行は、本来、必要なものでしょう・・・。うーん、手詰まりですね。

     

    ここまでの試行錯誤で、

      共存するコントロールとの関係で挙動が変化する、

    あるいは、

      子フォームのプロパティーを、Newで設定するか、Loadイベントで設定するか、によって挙動が変化する、

    ということが判ってきたわけで、

     

    すいません、申し上げにくいことですが、私のコメントと申しますか、私ならこうする、というのは、

      MDIを諦めては?

    ということになりそうです。

     

    すでにご説明いただいているように、

      親フォームの中で子フォームが常に最大化されており、

      子フォームが複数あるものの、そのうちの一つだけを選択して(切り替えて)表示する

    ということでしたよね? これは、本来のMDIとは違うように思うのです。

     

    子フォームが一つの種類しかないのであれば、なおさらですし、複数の種類ある場合でも、親フォームに貼り付けるコンテナ(Panel、GroupBox、TabControlなどのコントロールのこと)を使うことを検討されてはいかがでしょうか? それほど大きな変更にはならないと思います。子フォームのコードを、コントロールの定義も含めて、移植すればなんとかなるかと。

     

    あるいは、子フォームが一つの種類しかない場合(つまり、表示の切り替えを行っても、画面上に現れているコントロールの種類や数に変更がないのであれば)、

      1) コントロールのプロパティーを保存する変数と、表示するデータを保存する変数を内蔵する独自のクラスを作り、

      2) インスタンスを複数つくってやります。

      3) で、表示するインスタンスを切り替えるごとに、コントロールのプロパティーや表示データを、

      インスタンスが内蔵しているデータを作って更新してやる。

    こんな感じの設計も考えられます。

     

     

     

     

     

    2008年4月8日 4:08
  • 今頃ですが試しに作成してみましたところ、何の問題もなく簡単にできてしまいました。

     

    まず、ヘルプに書かれている「作成時に最大表示されるマルチ ドキュメント インターフェイス (MDI) 子フォームの場合、ControlBox プロパティを false に設定しても影響はありません。」についてですが、これは間違いだと思います。親メニューの左隅や右隅のアイコンの有無に影響しますので。また、最大表示でない場合は通常のフォームと同様の動作になります。

     

    終わりかけの話を蒸し返すようですが、試しに以下の手順どおりに行ってみてもらえませんでしょうか?
    この結果とご要望の話とは異なりますでしょうか?
    # これはあくまで検証用のため、Form1 をメインフォームのままにしています。

     

    1. VS2005 にてプロジェクトを新規作成する(Windows アプリケーションを選択)。
    2. ソリューションエクスプローラのプロジェクト名("Windows.Application1" など)で右クリックし、
       「追加」、「新しい項目」を順にポイントし、「MDI 親フォーム」を選択する。
    3. 作成された MDIParent1 フォームにて、メニューの「ファイル」の「新規作成」をダブルクリックする。
    4. ShowNewForm メソッドの最後にある ChildForm.Show() の直前に、次のコードを追加する。
            ChildForm.ControlBox = False
            ChildForm.WindowState = FormWindowState.Maximized
    5. ソリューションエクスプローラの "Form1.vb" をダブルクリックする。
    6. Form1 フォームをダブルクリックし、Form1_Load イベントハンドラに次のコードを記述する。
            Dim f As New MDIParent1
            f.ShowDialog()
    7. アプリケーションを実行し、メニューの「ファイル」、「新規作成」を実行する。

     

    この手順にて、タイトルバーが見えず、コントロールボックス等も表示されない MDI 子フォームが表示されることが確認できると思います。

     

    ネット移行者さんのアプリケーションでは、MDI 子フォームは通常のフォームで作成されていると思いますが、もしかすると上記 ShowNewForm メソッドの中にある ChildForm.MdiParent = Me のようなコードを書かれてないために、通常のフォームになっているのではないでしょうか?

    2008年4月8日 5:38
  • 外池です。

     

    私も、当初、TH01さんが仰るとおり、なんの問題も内容に思えたのですが・・・、相当面倒なことになりそうな気がします。

     

    ネット移行者さんが既にお手元にいろいろなコントロールが載っているFormがあって苦戦なされていることに比べて、TH01さんや私は、まったく新しいプロジェクトから始めて、素っぴんの親フォームと子フォームで挙動を調べているわけで・・・、

     

    素っぴんフォームでやっていると、TH01さんが仰るように、「お? これなら望みの挙動になる」という書き方は比較的簡単に見つかります。

     

    ただ、子フォームのNewに書くか(IDEでプロパティーを設定することに相当)それともLoadイベントに書くか(これは私がやってみたパターン)、あるいは、親フォームで子フォームを表示する直前にプロパティーで設定するか(TH01さんのパターン)によって、挙動がいろいろ変わるようで・・・

     

    そうなると、ネット移行者さんの現状のコードの場合、どれだと上手く行って、どれだとダメなのか・・・、きちっと理由もわかった上で納得できるコードを書くことが非常に難しくなりそうです。

     

    んで・・・、将来のVBのバージョンアップでも動作が一貫していることの約束はとても出来ない・・・。

     

    私が諦める方向の発言をした真意は、こんな感じです。
    2008年4月8日 6:08
  • 外池様、プログラム構成上のアドバイス有難うございます。

     

    Toolbarコントロール自体VB6.0の引継ぎであり、VB2005では希望の動作が無理なのかと思います。

    これをToolStripに置き換えたり、MDIフォームをどのように使うか、または取りやめるかを含めて

    もう少し、プログラムの構成を練り直して見ることにしました。

     

    長い間、初心者の愚問にお付き合いいただき有難うございました。

     

    ----ネット移行者----

    2008年4月8日 11:54
  • TH01様、ご丁寧なご教授有難うございます。

    ChildForm.MdiParent = Meのコードは追加してありますが上手くいきません。

     

    しかし、VB2005から新規に作成したMDIフォームでは問題なく出来るみたいです。

     

     当プログラムはVBから引き継いできたものであり、MDIフォームにはToolBarが有りそこには10個のボタンと、2個のラベル、2個のテキストボックスが、乗っており、子フォームには20数点コントロールが乗っておりそれらのコントロールにはAxComCtl、Ax・・・、の参照設定が必要なものも含まれています。そしてこのフォームから多数のフォームへのリンクが有り、これらのフォームを新規プロジェクトへ追加してテストをすることは、初心者の私には簡単にはいかないのでこの件はこれから時間をかけて研究、検討させていきたいと思います。

     なるべく、VB6.0のコントロールをVB2005のコントロールに置き換えながら修正して予定です。

     

    外池様、TH01様、trapemiya様、長い間、当質問にお付き合いいただき有難うございました。

     

    今後ともよろしくお願いいたします。

     

     

     

     

    2008年4月8日 13:07