3

私は次のシナリオを持っています:

[TemplatePart(Name = GoToEditModeButtonPart, Type = typeof(DoubleClickButton))]
public class ValueBoxWithLabel : ContentControl
{
    public const string GoToEditModeButtonPart = "GoToEditModeButtonPart";

    #region LabelText Dependency Property ...

    #region IsInEditMode Dependency Property ...

    public event EventHandler<ModeChangedEventArgs> ModeChanged;

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

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        //IsInEditMode invokes ModeChanged in the dependency property
        ((DoubleClickButton) GetTemplateChild(GoToEditModeButtonPart)).DoubleClick += (sender, args) => IsInEditMode = true;
    }

    private void InvokeModeChanged(ModeChangedEventArgs e)
    {
        EventHandler<ModeChangedEventArgs> mode = ModeChanged;
        if (mode != null)
            mode(this, e);
    }
}

ValueBoxは、あらゆる入力ボックスにとって不可欠なパネルです。今ではシンプルですが、アプリケーション全体で再利用され、より複雑な動作とレイアウトが含まれます。

入力としてのTextBoxを使用する必要があるため、このコントロールを作成します。

public class TextBoxWithLabel : ValueBoxWithLabel
{
    #region Text Dependency Property ...

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

次に、現在のgeneric.xamlがありますが、これは機能しませんが、必要なものがわかります。

<ResourceDictionary>

<ControlTemplate x:Key="ValueBoxWithLabelTemplate">
    <StackPanel Style="{StaticResource ValueBoxWithLabelPanelStyle}">
        <TextBlock Style="{StaticResource LabelStyle}" Text="{TemplateBinding LabelText}" />
        <Grid>
            <ContentPresenter Content="{TemplateBinding Content}" />
            <local:DoubleClickButton Background="Black" x:Name="GoToEditModeButtonPart"></local:DoubleClickButton>
        </Grid>
    </StackPanel>
</ControlTemplate>

<Style TargetType="local:ValueBoxWithLabel">
    <Setter Property="Template" Value="{StaticResource ValueBoxWithLabelTemplate}" />
</Style>

<Style TargetType="local:TextBoxWithLabel">
    <Setter Property="Template" Value="{StaticResource ValueBoxWithLabelTemplate}" />
    <Setter Property="Content">
        <Setter.Value>
            <TextBox Style="{StaticResource ValueBoxStyle}" Text="{TemplateBinding Text}" />
        </Setter.Value>
    </Setter>
</Style>

ValueBoxWithLabelはTextBoxで最もよく使用されるため、同じテンプレートを再利用するコントロールを作成したいので、テンプレートをコピーして貼り付ける必要はなく、両方を同じもので最新の状態に保つことができます。変更します。

ValueBoxWithLabelTemplateを再利用し、テンプレートの残りの部分を保持したままコンテンツプロパティのみをオーバーライドするにはどうすればよいですか?

4

1 に答える 1

1

その興味深いアプローチ。自分で試したことはありませんが、うまくいくようです。

Content現在発生している問題は、のプロパティを使用しようとしていることですContentPresenter。ただし、これには、コントロールの具体的なインスタンスを割り当てる必要があります。この場合は、を使用して実行していTextBoxます。の一部ではないため、TemplateBindingでは使用できません。TextBoxControlTemplate

問題がなくても、同じインスタンスを複数の場所でTemplateBinding「再利用」することはできないため、とにかくそれを使用して1つのコントロールしか作成できません。TextBoxそもそもテンプレートがあるのはそのためです。

ずっとテンプレート

テンプレートの問題を解決するのはそれほど難しいことではありません。本当にトリッキーなことは、特殊なコントロールの内部コンテンツコントロールを特殊なクラスのプロパティにバインドする方法を見つけることです。使用できない場合は難しいですTemplateBinding

まず、コントロールをレンダリングするために少なくとも行う必要のある変更の概要を説明します。-

<ControlTemplate x:Key="ValueBoxWithLabelTemplate">
    <StackPanel Style="{StaticResource ValueBoxWithLabelPanelStyle}">
        <TextBlock Style="{StaticResource LabelStyle}" Text="{TemplateBinding LabelText}" />
        <Grid>
            <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" />
            <local:DoubleClickButton Background="Black" x:Name="GoToEditModeButtonPart"></local:DoubleClickButton>
        </Grid>
    </StackPanel>
</ControlTemplate>

TextBoxWithLabelなります:-

<Style TargetType="local:TextBoxWithLabel">
    <Setter Property="Template" Value="{StaticResource ValueBoxWithLabelTemplate}" />
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <TextBox Style="{StaticResource ValueBoxStyle}"  />
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

これは(テストせずに)レンダリングされると思います。

拘束力のある問題

ただし、ご覧のとおり、Textプロパティのバインディングがありません。ここで、このバインディングの問題を解決するのに役立つと思われることがいくつかありますが、それらは、外部制御から内部制御へのパススループロパティを支援するためDataContextに、のサブクラスを悪用または作成することを含みます。ContentPresenterどちらも本当に醜いです。

結論

このような単純なベーステンプレートの場合、ある種の再利用を実現するために必要なすべてのフープをジャンプするよりも、テンプレートを複製する方がおそらく良いでしょう。

于 2010-02-12T14:48:59.757 に答える