|
# 追加質問があったようなので、解決済みチェックを外しておきます。
■No84214 (KAZ さん) に返信 >>配列や List(Of ) で管理すれば OK かと。 > List関数ですか。。。 List は関数ではありません。ジェネリックなクラスです。
配列はコレクションの一種です。List もコレクションです。 Controls プロパティの戻り値もコレクションですね。
> 扱いが変数の配列と同様であればマスターできそうな予感がします。 配列でも同じことができますね。
Private panels() As Control Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load panels = New Control() {Panel1, Panel2, Panel3, Panel1} End Sub Private Sub PictureBoxes_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click, PictureBox2.Click, PictureBox3.Click Dim c As Control = DirectCast(sender, Control) Dim i As Integer = Array.IndexOf(panels, sender) c.Parent = panels(i + 1) c.BringToFront() End Sub
> イメージとして Ctrl.Parent が示すものは Control だと思っていたので、これが単なるプロパティなんだというのはホントに目鱗でした。 はい。Parent プロパティが示すものは Control クラスです。
ご存知のように、Panel や Form では、その上に他のコントロール(Button など)を 載せることができるわけですが、やろうと思えば Form の上に Button を貼るのではなく、 その逆に Button の上に Form を貼ることさえできます。
以下サンプル。Button1 は少し大きめに貼っておいてください。
Dim f As New Form() f.TopLevel = False f.Parent = Button1 'または Button1.Controls.Add(f) f.Show()
といっても、実際にのような画面デザインが必要になる機会はそうそう無いでしょうけれどね。
> Remove には Dispose がつきもので、廃棄に必要な事は学びましたが、Ctrl.Clear とした場合は Dispose は必要ないのでしょうか?
Ctrl.Clear ではなく、Controls.Clear ですよね?
Ctrl.Clear というと、たとえば TextBox1.Clear() などが該当するかと思います、 たとえばこの場合は「TextBox1.Text = Nothing」と同義であり、Dispose とは無関係です。
一方、Panel1.Controls.Clear() の場合は、先の回答でも述べましたように、 かつて Panel1 上に載っていた子コントロール達を Dispose する責務があります。 (それらの子コントールを Panel1 以外に載せ直して再利用するという場合は Dispose は不要ですが)
具体的にはこんな感じ。
'Panel1 の上に載っていたコントロールへの参照を、配列に退避しておく Dim children = Panel1.Controls.OfType(Of Control)().ToArray() 'Panel1 の上に載っていたすべての子コントロールを取り除く Panel1.Controls.Clear() 'Clear しただけでは、それらの子コントロールは Dispose されないので 'それぞれ Dispose しておかなければならない For Each child In children child.Dispose() Next
改めて、コントロールの Dispose について整理してみますと:
(1) 生成されたコントロールは、『使い終わった時点で』必ず Dispose しなければなりません。 (引き続き使用されるコントロールについては、まだ Dispose で処分してはいけません) なお、ここでいうコントロールとは、System.Windows.Forms.Control を継承したクラスを指します。
(2) 今回の Panel と PictureBox のように、親子関係にあるコントロールの場合、 親が Dispose された時点で、子も自動的に Dispose される仕様です。 (再帰的に処理されますので、子が Dispose されれば 孫も Dispose されます)
(3) そして Form もコントロールの一種であるため、フォームが破棄された時点で フォーム上に貼られていたコントロールも一緒に破棄されます。
(4) そのため、通常の使い方をしている分には、各コントロールの Dispose を明示的に呼ぶ必要は生じません。 しかし、Contols.Clear() を呼んでいたり、Parent = Nothing などを実行していた場合には、 その親子関係が切れてしまった状態となるため、個別に Dispose して処分する必要が生じるというわけです。
(5) なお、Form がモードレス表示されていた場合、Form が閉じられる際に、直ちに Dispose されるようになっています。 モードレスな Form とは、Show メソッドで表示されたフォームやスタートアップフォームのことです。
(6) 一方、Form がモーダル表示されていた場合、Form が閉じられたとしても、直ちに Dispose されませんので、 Form を呼び出した側で、明示的に Dispose しなければなりません。(Using ステートメントを使うと良いでしょう) なおモーダルな Form とは、ShowDialog メソッドで表示された Form のことです。
|