Neutral Scent

App developments & Gadgets

generic.xamlを使用したシンプルなWindows Phone 7用カスタムコントロールの作成

UserControlとカスタムコントロール(Control継承クラス)の違い等はここでは割愛。
Download Source Code

基本的なカスタムコントロールの作り方

  • プロジェクトにControl(もしくはControl派生クラス)の継承クラスを追加
  • プロジェクトルートにThemesフォルダを追加
  • Themesフォルダに[追加]/[新しい項目]/[XML ファイル]でgeneric.xamlを作成
  • ルート要素を作成各種xmlnsを追加(通常のxamlと同じ)
  • <Style TargetType="名前空間:クラス名"> を追加しテンプレート・スタイル定義
    • generic.xaml内でイベント・トリガー定義は使えません
    • generic.xaml内で複数のコントロールのStyleを定義できます
  • 最初に作成したクラスのコンストラクターで DefaultStyleKey = typeof(クラス名);
  • OnApplyTemplate()をオーバーライド

プロジェクトファイル構成


generic.xaml


<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:my="clr-namespace:CustomControlSample1"
>
<Style TargetType="my:LabelBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="my:LabelBox">
<Grid>
<Border BorderThickness="4" CornerRadius="8" BorderBrush="White" >
<TextBlock x:Name="labelText" Text="foo" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
LabelBox.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace CustomControlSample1
{
public class LabelBox : Control
{
private TextBlock labelText;

public LabelBox()
{
DefaultStyleKey = typeof(LabelBox);
}

public override void OnApplyTemplate()
{
this.labelText = GetTemplateChild("labelText") as TextBlock;
this.labelText.MouseLeftButtonDown += new MouseButtonEventHandler(labelText_MouseLeftButtonDown);

base.OnApplyTemplate();
}

void labelText_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MessageBox.Show("ラベルだよ");
}
}
}

generic.xamlを使ったカスタムコントロールの作成は、メンバーやイベントハンドラのコードビハインド実装が多少面倒ですが、基本的な段取りとDefaultStyleKeyやGetTemplateChild()など通常の*.xaml.csと違う点さえわかってしまえば、UserControlで面倒なことになる既存のコントロールを継承したコントロールの作成が簡単に行えるようになります。
generic.xaml内で定義するStyleは通常のXAMLページ内のStyleと変わらないため、Expression Blendで生成した既存コントロールのテンプレートをそのまま流用することも可能です。
コントロールの作成に関しては、MSDNまとめ記事があるのですが、非常に冗長な上に翻訳精度の問題で難解な文章になってしまっているため、最小限の要素だけにまとめてみました。