.NET ROOM.NET ROOMトップへCOMRADE総合トップへ
「3:デザイン時に自作コントロールの設定を変更する方法」へ

ネストしたプロパティの展開


 「ネストしたプロパティ」とは、ひとつ以上のプロパティを持つクラスをプロパティにした場合のことを指します。
先のサンプルMyPoint1のMyPointControlで実装している、MyPoint型のPointもそのひとつです。
これをプロパティウィンドウで表示すると、図5のように表示されます。
通常のPoint型のLocation(図6)と比較するとわかりますが、図5では十字型のアイコンが表示されていません。


図5:MyPoint型のPointプロパティ



図6:Point型のLocationプロパティ



 これを表示するようにするのも、TypeConverterの仕事です。
GetPropertiesSupportedとGetPropertiesをリスト1のようにオーバーライドすればいいのです。

リスト1:ネストしたプロパティを表示する処理
public override bool
GetPropertiesSupported(ITypeDescriptorContext context) {
 return true;
}
public override PropertyDescriptorCollection GetProperties(
     ITypeDescriptorContext context,
     object value,
     Attribute[] attributes) {
 return base.GetProperties(context, value, attributes);
}
*)ExpandableObjectConverterクラスを利用すれば、リスト1を記述しなくても同じ効果を実現できる


 ただし、この実装は多くのプロパティで使用されるため、
専用のExpandableObjectConverterというクラスが用意されています。
そのため、ネストしたプロパティを表示する場合は、
このExpandableObjectConverterクラスから派生するようにしましょう。

    public class MyPointConverter : ExpandableObjectConverter {
    public override bool CanConvertFrom(
    ITypeDescriptorContext context, Type srcType) {
    (略)

  この変更を加えた結果、自作のMyPointクラスを、プロパティウィンドウ上で、
展開して表示/編集することができるようになりました(図7)。

ソースコードの詳細はサンプルMyPoint2を参照してください。

図7:展開されたMyPoint型のPointプロパティ


デザイン時の挙動をデバッグする方法


続いて、独自UIでのプロパティ操作の説明をする前に、
デザイン時の挙動をデバッグするための方法を説明しておきましょう。

 デザイン時のコントロールは、実行中のVS.NETの中で動作しているので、
VS.NETそのものをデバッガ上で実行することで、デザイン時の挙動を捉えることが出来ます。

 以下の手順でプロジェクトのデバッグの設定を変更してください。

手順1: ソリューションエクスプローラで、該当するプロジェクトを選択し、右クリックすると表示されるコンテキストメニューから「プロパティ」を選択してプロジェクトのプロパティ編集ダイアログ(図8)を表示

手順2: 左のビューで[構成プロパティ]-[デバッグ]を選択

手順3: 「開始動作」のカテゴリから、「デバッグモード」を選択し、「プログラム」を選択して、ダイアログの右下の[適用]ボタンをクリック

手順4: 「デバッグモード」の下の「スタートアプリケーション」でVS.NET 2003のパス
(通常はC:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe)を入力


 以上の設定を行うと、デバッガ上でVS.NETを走らせることができます。
この方法で、NUnitのエラーの原因を突き止めることもできます。


ページトップへ


独自ドロップダウンUIでのプロパティ操作

 サンプルMyPoint3を元に以下の解説を行います。

  このサンプルのMyPointControlコントロールでは、Pointプロパティの設定値が
ビジュアルに表示されように変更を加えました。

 [F5]キーを押して、デバッグを開始し、VS.NETが起動したら[プロジェクトを開く]ボタンで
MyPoint3\TestAppにある、TestApp.slnを選択してください。

 そして、Form1のデザインビューから、MyPointControlのプロパティウィンドウを表示して、
Pointプロパティを選択してみてください。
すると、新たにリストボックスの右端に▼のようなアイコンが表示されます。
これをクリックすると、図9のようなカスタムなUIが表示され、プロパティを編集できるようになっています。

図9:UITypeEditorによるプロパティの編集



  UITypeEditor自体の実装は、リスト2に示すようなものです。

リスト2:UITypeEditorの派生クラス(MyPointUIEditor)の実装
public class MyPointUIEditor : UITypeEditor {
 public override UITypeEditorEditStyle GetEditStyle(
  ITypeDescriptorContext context) {
  return UITypeEditorEditStyle.DropDown;
 }
 public override object EditValue(ITypeDescriptorContext context,
  IServiceProvider provider, object value) {
  IWindowsFormsEditorService edSvc =
   (IWindowsFormsEditorService)provider.GetService(typeof(
   IWindowsFormsEditorService));
  if (edSvc == null)
   return value;
  MyPoint p = value as MyPoint;
  System.Diagnostics.Debug.Assert(p != null);
  MyPointControl mpc = new MyPointControl();
  mpc.Size = new Size(200, 200);
  mpc.Point = p;
  edSvc.DropDownControl(mpc);
  return mpc.Point;
 }
}


 2つのメソッドのオーバーライドがあります。順番に説明してゆきます。

 まずは、GetEditStyleメソッドです。このメソッドは編集のスタイルを指定します。
UITypeEditorEditStyleというEnum型の値を返します。
UITypeEditorEditStyleに関しては表1に値とその意味を挙げておきます。
引数のITypeDescriptorContextに応じた値を返すことも可能になっています。
今回は単純に「UITypeEditorEditStyle.DropDown」を返すようにします。
ダイアログを使用したい場合は、ここで「UITypeEditorEditStyle.Modal」を返すように変更します。

表1:UITypeEditorEditStyle Enumの値
意味
DropDown 下向きの矢印ボタンを表示。
ユーザーインターフェイスはドロップダウンダイアログ内で管理される
Modal モーダルまたはウィンドウ付きのダイアログボックスを開く、
省略記号(...)ボタンを表示
None 対話形式のユーザーインターフェイス(UI)コンポーネントを提供しない
*)http://www.microsoft.com/japan/msdn/library/default.asp? url=/japan/msdn/library/ja/cpref/html/frlrfsystemdrawingdesignuitypeeditoreditstyleclasstopic.asp
より抜粋。


 次にEditValueメソッドです。引数のvalueが変更したい値で、変更後の値を返り値として返します。
この場合は、MyPointの値の変更専用に作成してあるので、valueはMyPoint型になるはずですが、
間違った使用を避けるため、異なる型が代入された場合はArgumentExceptionをThrowするようにします。

 IWindowsFormsEditorServiceのインスタンスの取得は興味深いのですが、
本筋とは関係ないので、詳細は割愛します。
このインスタンスは基本的にデザイン使用時以外は取得できないので、
必ずインスタンスが取得出来たことを確認してから使用してください。

 IWindowsFormsEditorServiceのDropDownControlメソッドで、
ドロップダウンで表示したいコントロールを指定します。
今回はMyPointControlそのものを指定していますが、
通常は値の設定専用のコントロールを作成することになるでしょう。
UITypeEditorを型に関連付けるには、EditorAttributeを使用します。
EditorAttributeのコンストラクタには以下のように、基底クラスも指定する必要があります。

   [Editor(typeof(MyPointUIEditor), typeof(UITypeEditor))]
   public class MyPoint {
   (略)

ソースコードの詳細はサンプルを参照してください。


ページトップへ


ダイアログでのプロパティ操作

 サンプルMyPoint4を元に以下の解説を行います。

 ダイアログの表示方法は、先ほどのドロップダウンの表示とほとんど変わりませんが、
IWindowsFormsEditorServiceのShowDialogメソッドを使用せずに、MyPoint4\MyPointUIEditor.csのように
EditValueメソッドの中でフォームのShowDialogメソッドを呼ぶことも出来ます。
実際、IWindowsFormsEditorServiceのShowDialogメソッドは、フォームのShowDialogメソッドを
呼び出しているだけだと考えられます。
ただし、どちらの場合もShowDialogメソッドの返り値を気にして、[Cancel]ボタンを押したときに、
編集をキャンセルできるようにする必要があるでしょう。

 [OK]ボタンを押した場合、(結果がDialogResult.OKの場合)は、
表示していたダイアログで編集されていた値を返すようにします。

   if (form.ShowDialog() == DialogResult.OK)
    return form.MPC.Point;
   return value;

 以上がプロパティウィンドウを使用したプロパティの変更方法です。

 続いて、より自由度の高いカスタムコントロールの編集方法の実装に関して説明します。


前へ | ページトップへ | 次へ