カスタム コントロールをウィンドウとしてモックアップし、すべての動作が正しくなったので、適切なカスタム コントロール ("When" と呼ばれる、日時ウィジェット) に変えようとしています。
サブ要素の名前が PART_xxx である When.XAML ファイルを用意しました。
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:glob="clr-namespace:System.Globalization;assembly=mscorlib"
xmlns:local="clr-namespace:Widgets">
<local:DatePartPositionValueConverter x:Key="DatePartPositionValueConverter" />
<local:DatePartVisibilityValueConverter x:Key="DatePartVisibilityValueConverter" />
<Style TargetType="{x:Type local:When}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:When}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Border BorderThickness="1" BorderBrush="{DynamicResource
{x:Static SystemColors.ControlDarkBrushKey}}">
<Grid HorizontalAlignment="Left" Margin="4,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
...
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock x:Name="PART_year" Grid.Column="{Binding
Converter={StaticResource DatePartPositionValueConverter},
ConverterParameter=y}">
<TextBlock.Text>
...
カスタム コントロール プロジェクト Generic.XAML ファイルは When.XAML を参照します。
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Widgets;component/Themes/When.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
ただし、私のコードは PART_ 名を解決できないようです。
_focussedElement を (たとえば) PART_year と比較して、検証チェックのコンテキストを提供できるようにしたいと考えています。カスタム コントロールのコードから PART_xxx を直接参照できるようにする必要があります。そうしないと、コードを使用してイベント ハンドラーをテンプレートの要素にバインドすることができなくなります。
私は何を理解できなかったのですか?
以下の優れた回答を言い換えて拡張すると、IDE のコード生成マジックがそれをスコープに入れる機会がないため、PART_yearはスコープに含まれません。したがって、次のように、自分でスコープに入れます。
MenuItem PART_MenuItemToday, PART_MenuItemNow,
PART_MenuItemMonthEnd, PART_MenuItemMonthStart;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
PART_MenuItemMonthEnd = GetTemplateChild("PART_ContextMenuMonthEnd") as MenuItem;
PART_MenuItemMonthEnd.Click += PART_ContextMenuMonthEnd_Click;
...
}
同じハンドラーのセットを複数のウィジェットにフックする必要がある場合は、これを行うことができます
private void BindGenericHandlers(TextBlock textBlock)
{
textBlock.GotFocus += PART_GotFocus;
textBlock.LostFocus += PART_LostFocus;
textBlock.MouseDown += PART_MouseDown;
textBlock.MouseEnter += PART_MouseEnter;
textBlock.MouseLeave += PART_MouseLeave;
}
TextBlock _focussedElement, PART_year, PART_month, PART_day, PART_hour, PART_minute, PART_second, PART_designator;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
BindGenericHandlers(PART_day = GetTemplateChild("PART_day") as TextBlock);
BindGenericHandlers(PART_designator = GetTemplateChild("PART_designator") as TextBlock);
BindGenericHandlers(PART_hour = GetTemplateChild("PART_hour") as TextBlock);
BindGenericHandlers(PART_minute = GetTemplateChild("PART_minute") as TextBlock);
BindGenericHandlers(PART_month = GetTemplateChild("PART_month") as TextBlock);
BindGenericHandlers(PART_second = GetTemplateChild("PART_second") as TextBlock);
BindGenericHandlers(PART_year = GetTemplateChild("PART_year") as TextBlock);
...
}