WPF,XAML関連で一番理解しにくいのが、Template
なぜ、こんなややこしい記述になるのか、調べてみた。
TargetTypeを2回指定したり、RelativeSourceの記述も何これ、という感じで疑問が色々わいていた。
コメント化されてるXAML部分をC#で記述した。


//<Canvas.Resources>
// <Style TargetType="{x:Type my:CustomControl1}">
// <Setter Property="Template">
// <Setter.Value>
// <ControlTemplate TargetType="{x:Type my:CustomControl1}">
// <Grid>
// <TextBlock Foreground="Blue" Text="{Binding Path=txt, RelativeSource={RelativeSource TemplatedParent}}"></TextBlock>
// </Grid>
// </ControlTemplate>
// </Setter.Value>
// </Setter>
// </Style>
//</Canvas.Resources>

// TextBlock
Binding bin = new Binding();
bin.Path = new PropertyPath("txt");
bin.RelativeSource = new RelativeSource( RelativeSourceMode.TemplatedParent );

FrameworkElementFactory fac2 = new FrameworkElementFactory(typeof(TextBlock));
fac2.SetValue( TextBlock.ForegroundProperty, Brushes.Green);
fac2.SetValue( TextBlock.TextProperty, bin );


// Grid
FrameworkElementFactory fac = new FrameworkElementFactory(typeof(Grid));
fac.AppendChild(fac2);

// ControlTemplate
ControlTemplate ctempl = new ControlTemplate();
ctempl.TargetType = typeof(WpfCustomControlLibrary1.CustomControl1);
ctempl.VisualTree = fac;

// Setter
Setter stt = new Setter();
stt.Property = Control.TemplateProperty;
stt.Value = ctempl;

// Style
Style st = new Style();
st.TargetType = typeof(WpfCustomControlLibrary1.CustomControl1);
st.Setters.Add( stt );

control2.Style = st; // control2 <-- WpfCustomControlLibrary1.CustomControl1のインスタンス

入り組んでるXAMLは、オブジェクトクラスの構成が理由でそうなるようだ。

ctempl.TargetTypeは便箋の拝啓XXX様の宛名で、st.TargetTypeは封筒に書かれる宛名と理解した。概念として。

Templateを使用できるのは、Templateプロパティをもつクラスで、調べると、System.Windows.Controls.Controlの下位クラスにしかない。


WPFのクラス構成図

↓UIElement
↓FrameworkElement
Border
Image
MeiaElement
TextBlock
↓Panel
Canvas
Grid
StackPanel
↓Control
ContentControl
Calendar
ListBoxItem
ItemsControl
TextBox
Button
DataGrid
UserControl

Button、TextBoxにTemplateを適用できるのはControlの下位クラスだから。
TextBoxに似ているTextBlockには適用できない。ふーーーん。