いろいろ備忘録日記

主に .NET と Python絡みのメモを公開しています。

特定のコントロールの取得方法および削除方法

たとえば、独自のコントロールを作成してそれをフォーム内に
配置します。そのコントロール内のイベントで別のコントロールの
状態を更新したい場合(たとえばステータスバーを更新など)が多々あります。
やり方はいろいろあると思いますが、一番ベタなのが更新される
コントロールを渡す方法でしょうか。

    class 独自コントロール : UserControl{
        private Label _statusLabel;
        public Label StatusLabel{
            set{
                _statusLabel = value;
            }
        }
    }

でも、これだと更新する対象のコントロールが増えるたびに
プロパティを外部に公開する処理を追加していかなければなりません。
もうひとつは、トップレベルもしくは該当のコントロールを保持している
コンテナからNameプロパティをキーにして取得する方法があります。
たとえば、先ほどの例の場合、あるボタンが押下されたら処理完了時に
ステータスバーを更新する場合、

    _btn.Click += _btn_Clicked;

    private void _btn_Clicked(object sender, EventArgs args){
        //
        // なんらかの処理......
        //

        //
        // トップレベルのコントロール(通常、メインフォーム)から
        // 更新対象コントロールを取得。
        // Nameプロパティは、"_statusLabel"だとします。
        //
        bool recurse = true;
        TopLevelControl.Controls.Find("_statusLabel", recurse).Text = "メッセージ";
        
    }

という事もできます。
また、自分自身が配置されているフォームを取得する場合はFindFormメソッドを使用します。

    _btn.Click += _btn_Clicked;

    private void _btn_Clicked(object sender, EventArgs args){
        //
        // なんらかの処理......
        //

        //
        // 更新対象コントロールを取得。
        // Nameプロパティは、"_statusLabel"だとします。
        //
        bool recurse = true;
        FindForm().Controls.Find("_statusLabel", recurse).Text = "メッセージ";
        
    }

Findメソッドに指定している第二引数は、コントロールを検索する際に
再帰的に検索するかどうかの指定です。これをfalseにして渡すと自分の持っている
コントロールのみを対象として検索されます。(つまり、その中にパネルなどが
あってもパネル内のコントロールは検索対象外となるという事です)


Control.Controlsプロパティは、ControlCollectionを返します。
ControlCollectionには、上記のFindや、其の他にコンポーネントを削除する
RemoveByKeyメソッドなどもあります。
以下、RemoveByKeyメソッドのサンプルです。

    _btn.Click += _btn_Clicked;

    private void _btn_Clicked(object sender, EventArgs args){
        //
        // 対象コントロールの削除。
        // Nameプロパティは、"_statusLabel"だとします。
        //
        // RemoveByKeyメソッドには、再帰的に探す指定ができません。
        // なので、実際に対象のコントロールを保持しているコンテナの
        // ControlCollectionから実行する必要があります。
        //
        Form form = FindForm();
        form.Controls.RemoveByKey("_statusLabel");
        form.Refresh();
        
    }

なお, Findメソッド、RemoveByKeyメソッド共に.NET 2.0から追加されたメソッドです。
JavaのSwingには、これがないんですよね。
自前でそのような処理を行うメソッドを用意すればいいんですが、最初から
用意されているとかなりうれしいのですが。


================================
過去の記事については、以下のページからご参照下さい。