いろいろなコントロールのCursorプロパティを動的に変更させたいと思い、Cursorsクラスのプロパティ一覧をコンボボックスに設定しようと考えました。
で、コンボボックスの選択を変更することによりCursorプロパティが動的に変更されたらいいなと思っていたのですが・・・。
思ったより手こずったので、方法をこちらで紹介します。
最終的にできるようになったこととして
- 静的クラスの全プロパティを取得し、オブジェクトとして生成できる。
- 列挙体の全列挙値を取得できる。
- コンボボックスにプロパティ・列挙値の一覧を設定し、その値から対象のコントロールのプロパティを変更することができる。
- 特殊なパターンとして、StringからBrushオブジェクトを生成することができる。
です。
まずはComboBoxに引数のTypeのプロパティをすべて設定するメソッドです。
private void SetObjectFromType(ComboBox combo, Type t)
{
foreach (PropertyInfo info in t.GetProperties())
{
combo.Items.Add(info.GetValue(null, null));
}
}
TypeのGetPropertiesメソッドでそのTypeのすべてのプロパティがPropertyInfoオブジェクトとして取得できます。
PropertyInfoオブジェクトのGetValueメソッドでプロパティのオブジェクトが取得できるので、それをComboBoxのアイテムとして設定しています。
ポイントとして、GetValueメソッドの引数ですが、
| 第1引数 |
プロパティ値が返されるオブジェクト |
| 第2引数 |
インデックス付きプロパティのインデックス値 (省略可能) |
| 戻り値 |
第1引数のプロパティ値 |
となっており、実は静的クラスのPropertyInfoからGetValueを呼び出す場合は第1引数はnullでOKなんです。
ここ、気づくのに結構かかっちゃいました・・・。
そうすると晴れて、静的クラスのプロパティが取得できるわけです。
動的クラスの場合はクラスのインスタンスを作成し、それを渡してあげるんですけどね。
次に上のメソッドを呼び出す部分。
これはCursorsクラスのプロパティ一覧を設定するのに特化したメソッドになります。
private void SetComboFromCursor(ComboBox combo)
{
SetObjectFromType(combo, typeof(Cursors));
}
typeofメソッドでCursorsクラスのType型オブジェクトを取得してそれを渡しています。
ここで渡しているCursorsを別の静的クラスに変えればそのクラスのプロパティ一覧をComboBoxに設定することができます。
あとはComboBoxのSelectionChangedイベントで、選択されたアイテムを対象のコントロールのCursorプロパティに設定してあげればOKです。
private void cboCursor_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
↓こんな感じ
同様に、列挙体の一覧をComboBoxに設定するには、
private void SetEnumFromType(ComboBox combo, Type t)
{
foreach (FieldInfo info in t.GetFields(BindingFlags.Static | BindingFlags.Public))
{
combo.Items.Add(info.GetValue(null));
}
}
このようにTypeのGetFieldsメソッドで列挙体の全列挙値が取得できます。
StaticとPublicに絞らないといらないものも取れちゃいますが。
↓こんな感じ
特殊なパターンとして、Brushの設定についても紹介します。
private void cboBackground_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
dgTarget.Background =
new SolidColorBrush
((Color)ColorConverter.
ConvertFromString(cboBackground.
SelectedItem.
ToString()); }
このように、BackGround等に設定するSolidColorBrushは文字列を基にColorConverterクラスのConvertFromStringメソッドにより
Colorオブジェクトが取得できるので、それを基に作成することができます。
なので、
private void SetNameFromType(ComboBox combo, Type t)
{
foreach (PropertyInfo info in t.GetProperties())
{
combo.
Items.
Add(info.
Name); }
}
のようにPropertyInfoのNameプロパティをComboBoxに設定しておけばOKとなります。
↓こんな感じ
以上です。
どれだけ需要があるか分かりませんが、かなり自己満足しました(笑)
最終更新:2009年05月18日 12:05