0

カスタム コントロールをウィンドウとしてモックアップし、すべての動作が正しくなったので、適切なカスタム コントロール ("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);
  ...
}
4

1 に答える 1

2

GetTemplateChildオーバーライド内のメソッドを使用して、コード内の PART への参照を取得しOnApplyTemplateます。したがって、コントロールのコードには次のようになります。

private const string PART_TEXTINPUT = "PART_TEXT";
private TextBox _textInput;

public override void OnApplyTemplate()
{
   base.OnApplyTemplate();
   _textInput = GetTemplateChild(PART_TEXTINPUT) as TextBox;
}

PART を使用しているため、見た目の悪いコントロールを作成しているように見えるため、XAML から要素を直接参照することはできません (カスタムControlTemplateによって予期しないものに置き換えられる可能性があるため)。したがって、メソッドを使用して PART への参照を取得しますGetTemplateChild

注: 誰かが予想されるコントロールを別の実装に置き換えた場合に備えて、パーツ (コード内) には可能な限り低い型を使用してください。

于 2013-01-21T22:57:24.293 に答える