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

わんくま同盟

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

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


(過去ログ 165 を表示中)
■95116 / )  Re[2]: 仕様?誤使用?
□投稿者/ chobi (4回)-(2020/06/24(Wed) 11:46:57)
魔界の仮面弁士さま

適切な回答ありがとうございます。
コードで生成しているので同名です。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 -