魔界の仮面弁士さま 適切な回答ありがとうございます。 コードで生成しているので同名です。diposeは追加しました。 とりあえず大した要素数ではなかったので、頭からやり直すようにしました。 後ろからアクセスする、事前に列挙す retry: foreach (Control ctr in Controls) { if (ctr.Name == "AccountElement") { AccountElement ae = (AccountElement)ctr; if (ae.Checked) { Controls.Remove(ctr); ctr.Dispose(); goto retry; } } } ■No95115 (魔界の仮面弁士 さん) に返信 > 2020/06/24(Wed) 11:34:02 編集(投稿者) > > ■No95114 (chobi さん) に返信 >> if (ctr.Name == "AccountElement") >> { > Controls 内に、同じ Name を持つコントロールが複数あるのでしょうか。 > デザイナー画面で貼った場合、同名コントロールは同時に存在できないハズです。 > (デザイナーを用いず、コードで生成していた場合は、同名コントロールや無名コントロールも配置可能です) > > もし、 "AccountElement" なコントロールがひとつだけなら、 > 発見した時点で break; して、ループを抜けてしまえば良いと思います。 > > > >>Controls.Remove(ctr); > > ctr.Dispose(); が漏れているように見えます。 > > Panel に貼ったコントロールは、親フォームが閉じられたときに、 > 一緒に Dispose されるのですが、Remove や RemoveAt した場合は、 > Controls の管理下から外れてしまうので、明示的に Dispose(); する必要があります。 > > >>以下のようにforeachで列挙しながらチェック、削除していますが、 >>foreach (Control ctr in Controls) > > > // 修正案1: 後ろから前に探索するようにする > for ( int i = Controls.Count - 1 ; i >= 0 ; i-- ) > { > Control ctrl = Controls[i]; > > > // 修正案2: Controls そのものではなく、そこから取り出した「削除前のコントロール一覧」を列挙する > foreach (var ctrl in Controls.Cast<Control>().ToArray() )
- Child Tree -