mikeo_410


 カスタムコントロールのXAMLとコード

  プロジェクトにカスタムコントロールを追加すると、Themes フォルダが作られ generic.xaml が生成されます。
  このファイルは、プロジェクトに1つ生成されます。
  これは、複数のコントロールが1つのXAMLに記述されることになり、流用しようとすると切り出す必要が生じることになると考え避けていました。

コントロール

  コントロールの概念を少し整理しておきます。
  デザイナでWindowをデザインする際の、操作する単位を、普通、コントロールと呼んでいると思います。
  WPFやSilvrerlightは、このコントロールをデザインすることができるようになっています。
  Windowに配置できるパーツの分類は、以下のように見えます。

UIElement FrameworkElement Panel Canvas
Grid
 
Control Button
TextBox
ComboBox
 
Shape Line
Ellipse
 
TextBlock
Border

  パーツに共通するのは、FrameworkElement のようです。
  Control は、FrameworkElemet を集めて作られているもので、Windowに配置できるものの1つのようです。

カスタムコントロール

  カスタムコントロールをプロジェクトに追加してみます。
  generic.xaml には、Style が作られます。

  1. <Style TargetType="{x:Type local:CustomControl1}">
  2.     <Setter Property="Template">
  3.         <Setter.Value>
  4.             <ControlTemplate TargetType="{x:Type local:CustomControl1}">
  5.                 <Border Background="{TemplateBinding Background}"
  6.                         BorderBrush="{TemplateBinding BorderBrush}"
  7.                         BorderThickness="{TemplateBinding BorderThickness}">
  8.                 </Border>
  9.             </ControlTemplate>
  10.         </Setter.Value>
  11.     </Setter>
  12. </Style>

  CustomControl1.csには、以下のCustomControl1クラスが作られます。

  1. public class CustomControl1 : Control
  2. {
  3.     static CustomControl1()
  4.     {
  5.         DefaultStyleKeyProperty.OverrideMetadata(
  6.             typeof(CustomControl1), 
  7.             new FrameworkPropertyMetadata(typeof(CustomControl1)));
  8.     }
  9. }

  Control のTemplate を定義すれば、ButtonでもTextBlockでも任意のものが作れると言う仕組みです。

XAML記述とコードの関係

  CustomControl1クラスに、property1 と言うプロパティを追加して、XAML記述で値を設定してみます。
  generic.xaml には、以下のような記述を追加します。

  1. <Setter Property="property1">
  2.     <Setter.Value>
  3.         <DoubleCollection>
  4.             0,1,2,3
  5.         </DoubleCollection>
  6.     </Setter.Value>
  7. </Setter>
  8.             0,1,2,3
  9.         </DoubleCollection>
  10.     </Setter.Value>
  11. </Setter>
  12.             0,1,2,3
  13.         </DoubleCollection>
  14.     </Setter.Value>
  15. </Setter>

  プロパティの名前は、CustomControl1クラスに、public なプロパティが宣言されていればコンパイルができます。
  しかし、実行時にはエラーになります。
  エラーにならないようにするには、依存関係プロパティとして宣言する必要があるようです。
  このプロパティの登録や変更イベント処理はスタティックで、コンストラクト前にアクセスされるもののようです。

  1. public class CustomControl1 : Control
  2.  {
  3.      // プロパティを追加
  4.      public DoubleCollection property1 { get; set; }
  5.      // このプロパティを依存関係プロパティに登録
  6.      public static readonly DependencyProperty property1Property =
  7.          DependencyProperty.Register(
  8.              "property1",
  9.              typeof(DoubleCollection),
  10.              typeof(CustomControl1),
  11.              new PropertyMetadata(property1PropertyChanged));
  12.      // 依存関係プロパティの変更イベント(スタティック)
  13.      static void property1PropertyChanged(DependencyObject d, 
  14.                              DependencyPropertyChangedEventArgs e)
  15.      {
  16.          ((CustomControl1)d).property1=
  17.              (DoubleCollection)e.NewValue;
  18.      }
  19.      // スタティックなコンストラクタ
  20.      static CustomControl1()
  21.      {
  22.          DefaultStyleKeyProperty.OverrideMetadata(
  23.              typeof(CustomControl1), 
  24.              new FrameworkPropertyMetadata(typeof(CustomControl1)));
  25.      }
  26.      // 通常のコンストラクタ
  27.      public CustomControl1()
  28.      {
  29.          // この段階では、property1はnull
  30.          // Loadedイベント処理を登録
  31.          Loaded += new RoutedEventHandler(CustomControl1_Loaded);
  32.      }
  33.      // Loadedイベント
  34.      void CustomControl1_Loaded(object sender, RoutedEventArgs e)
  35.      {
  36.          Debug.WriteLine(property1);// 0 1 2 3 と表示
  37.      }
  38.  }

参照

  問題を整理すると、

  1. XAMLを分割して記述する方法
  2. 記述1つから複数のインスタンスを得る方法

  と、言うことになります。

XAMLとビハインドコード
カスタムコントロールのXAMLとコード
Styleとプロパティ
Styleとバインディング
DataContextとインスタンス
XAML記述とVisualの変換
1つのStyle記述から複数のインスタンス


mikeo_410@hotmail.com