我如何拥有一个只为控件的默认,未改变的可视树创建容器的ControlTemplate?

时间:2015-01-19 18:26:32

标签: c# .net wpf xaml

我试图弄清楚如何将控件的模板更改为将其保存在Grid内的内容,如下所示:

<ControlTemplate x:Key="containedTemplate">
    <Grid>
        <!-- place templated control here -->
    </Grid>
</ControlTemplate>

我当然希望任何内部控件的属性能够与模板化控件自动同步。

这可以完成吗?

以下是TextBox模板的假设示例:

<ControlTemplate x:Key="textTemplate" TargetType="{x:Type TextBox}">
    <Grid Background="Red">
        <TextBox Name="InnerTextBox" Margin="5,5,5,5"/>
    </Grid>
</ControlTemplate>

现在,如果我在TextBox实例上应用模板,请执行以下操作:

<TextBox Text="{Binding MyTextProperty}" Template="{StaticResource textTemplate}"/>

...然后控件会神奇地成为Grid,其中包含TextBox,边距为少,Text的属性将绑定到{{1}已设置MyTextProperty个实例的任何内容:

DataContext

如果我有以下代码:

<!-- runtime visual tree I'd like to be produced by the above XAML -->
<Grid Background="Red">
    <TextBox Text="{Binding MyTextProperty}" Margin="5,5,5,5"/>
</Grid>

结果树将是:

<StackPanel>
    <TextBox Text="{Binding MyTextProperty}" Template="{StaticResource textTemplate}"/>
    <TextBox Text="{Binding MyOtherTextProperty}" Template="{StaticResource textTemplate}"/>
    <TextBox Text="{Binding YetAnotherTextProperty}" Template="{StaticResource textTemplate}"/>
</StackPanel>

在这些示例中,您可以看到<!-- runtime visual tree I'd like to be produced by the above XAML --> <StackPanel> <Grid Background="Red"> <TextBox Text="{Binding MyTextProperty}" Margin="5,5,5,5"/> </Grid> <Grid Background="Red"> <TextBox Text="{Binding MyOtherTextProperty}" Margin="5,5,5,5"/> </Grid> <Grid Background="Red"> <TextBox Text="{Binding YetAnotherTextProperty}" Margin="5,5,5,5"/> </Grid> </StackPanel> &#39; TextBox属性已正确传播到&#34;内部&#34; Text个实例。控件的默认可视树也会被保留(边框,打字区域等)。

我知道模板部件但正如我所说的那样,我试图在这里找到一种全局方法,而我不要想要改变控件的外观;只把它放在一个容器里。

1 个答案:

答案 0 :(得分:1)

坦率地说,这个问题让我筋疲力尽,我有这个答案,但没有说服我很多。

首先,您应为要设置模板的每个控件创建多个ControlTemplates,然后创建此类

public class ControlTemplateConverter
{
    public static readonly DependencyProperty IsEnabledProperty =
            DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(ControlTemplateConverter), new UIPropertyMetadata(false, IsEnabledChanged));

    private static void IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ControlTemplate t;
        if (d == null) return;
        if (d is TextBlock)
            t = App.Current.FindResource("TextBoxTemplate") as ControlTemplate;
        else if (d is CheckBox)
            t = App.Current.FindResource("CheckBoxTemplate") as ControlTemplate;
        // and So On

        (d as Control).Template = t;
    }

    public static bool GetIsEnabled(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsEnabledProperty);
    }
    public static void SetIsEnabled(DependencyObject obj, bool value)
    {
        obj.SetValue(IsEnabledProperty, value);
    }
} 

你的控制应该是这样的:

<TextBox local:ControlTemplateConverter.IsEnabled="True"></TextBox>
<CheckBox local:ControlTemplateConverter.IsEnabled="True"></CheckBox>