スポンサーリンク

2010年11月11日木曜日

PropertyGrid で独自クラスのコレクションを編集する方法

 今回は珍しく、C#でもASP.NETでのお話。

 Visual Studioでお世話になるPropertyGrid。コントロールを選択するとプロパティウィンドウに表示されるアレ。色とかサイズとかを画面で変更するのにコードを書くことなく設定してくれるアレ。

 独自クラスをプロパティに持つ場合もその設定をPropertyDialogで行うことが可能で、サンプルもちょっとグーグル先生に聞けばちゃら~んと出てくる。が、しかし……これのコレクションを持つパターンが見つからない。

 とりあえずMSDNを見ながら試行錯誤してみたけど、設定値が反映されてなかったり、デザイナー上でエラーが表示されたり(実行時に設定値は反映されエラーも表示されない)……。

 結局どうにもならなくてMSDNのフォーラムに質問投稿。無事に解決?できました。

 結果から言えば、解決になってないような気がする(汗。


 とりあえず、以下のような独自クラスがあったとして。
public class PropSet
{
    public string A { get; set; }
    public string B { get; set; }

    public PropSet()
    {
    }

    public PropSet(string a, string b)
    {
        this.A = a;
        this.B = b;
    }
}
このコレクションを持つTexbBoxを作ったとして。
public class TextBoxEx : TextBox
{
    public TextBoxEx()
    {
        this.PropSets = new PropSetCollection();
    }

    public PropSetCollection PropSets { get; set; }
}
このコントロールをフォームに張り付けたとき、デザイナ上からPropSetのそれぞれの要素を編集したい、というのが今回の目標。

 PropertyGridにこんな感じに表示されて、

f:id:ristezza:20101108100132p:image

 各要素をコレクションエディターで編集できる。

f:id:ristezza:20101108100131p:image

 まず、PropSetのコレクションクラスを用意。List<T>でもいいけど、今回はCollection<T>を継承。
public class PropSetCollection : Collection<PropSet>
{
    public PropSetCollection()
    {
    }

    public PropSetCollection(IList<PropSet> list)
    {
    }
}
とりあえずこれだけで、デザイナ上でコレクションエディタは表示できる。自動ってやってくれます、簡単便利!

 ただ、新規作成した要素とその値を設定反映させるとなると一苦労。

 ASP.NETだと各コントロールとその設定はASPで記述されるわけで、オブジェクトが文字列として表現されるわけです。逆に言えば、オブジェクトの内容を復元できる文字列に変換してやらないとダメ。変換と言ってもシリアライズするとかではなくても良くて、自前のルールに従って変換できればそれでOK。

 今回の場合では、PropSetクラスのstring型のAとBというプロパティだけなので、それらをハイフン「-」で繋ぎ、コレクションの各要素はカンマ「,」で繋いで文字列に変換することにします。
{
    new PropSet{ A = 'a1', B = '10' },
    new PropSet{ A = 'a2', B = '20' }
}

a1-10,a2-20
が相互変換可能なようにします。

 コントロールを文字列に変換、という異なる型の変換を行うのでコンバータを使用します。

 今回はコレクションを変換させたいのでCollectionConverterクラスを継承して作成します。と言ってますが、他にStringConverterとかTypeConverterとかいろいろあるけど、どういうときにどれを使うべきかはまだしっかり理解できてません。とりあえず今回の例では、TypeConverterでもCollectionConverterでも動作しました。

 では、次回からCollectionConverterクラスを継承したPropSetCollectionConverterの実装とその使用方法を記述しようと思います。

0 件のコメント:

コメントを投稿