如何使用绑定从标准控件引用控件模板?

时间:2013-05-21 09:58:29

标签: .net wpf xaml custom-controls controltemplate

我正在构建一个继承自标准System.Windows.Controls.Calendar控件的自定义控件。我正在关注代码项目的这篇文章。我还想使CalendarItem子对象可以调整大小,如MSDN上的这篇文章。

我将Calendar,CalendarDayButton和CalendarItem的样式从Calendar控件的源代码复制到我的Generic.xaml中的自定义控件ResourceDictionary。 CalendarItem样式引用3个按钮模板(上个月,下个月和标题按钮),如下所示:

<!-- Start: Previous button content -->
<Button x:Name="PART_PreviousButton" 
        Grid.Row="0" Grid.Column="0"
        Template="{StaticResource PreviousButtonTemplate}" 
        Height="20" Width="28" 
        HorizontalAlignment="Left" 
        Focusable="False"
        />
<!-- End: Previous button content -->

<!-- Start: Header button content -->
<Button x:Name="PART_HeaderButton"                                             
        Grid.Row="0" Grid.Column="1" 
        Template="{StaticResource HeaderButtonTemplate}" 
        HorizontalAlignment="Center" VerticalAlignment="Center" 
        FontWeight="Bold" FontSize="10.5" 
        Focusable="False"
        />
<!-- End: Header button content -->

<!-- Start: Next button content -->
<Button x:Name="PART_NextButton" 
        Grid.Row="0" Grid.Column="2" 
        Height="20" Width="28" 
        HorizontalAlignment="Right" 
        Template="{StaticResource NextButtonTemplate}" 
        Focusable="False"
        />
<!-- End: Next button content -->

现在因为这个绑定使用StaticResource,我需要将三个按钮的样式复制到我的ResourceDictionary中。我不打算对这些按钮进行任何更改,所以我希望可以避免在我的ResourceDictionary中为它们设置样式。

有什么方法可以通过绑定来引用这些按钮的原始样式吗?

1 个答案:

答案 0 :(得分:1)

是的,有:

在继承自Calendar的自定义控件上,您可以为三种样式中的每一种公开类型ControlTemplate的依赖项属性

public class MyCalender : Calendar
{
    public static readonly DependencyProperty PreviousButtonTemplateProperty =
        DependencyProperty.Register("PreviousButtonTemplate", typeof (ControlTemplate), typeof (MyCalender), new PropertyMetadata(default(ControlTemplate)));

    public ControlTemplate PreviousButtonTemplate
    {
        get { return (ControlTemplate) GetValue(PreviousButtonTemplateProperty); }
        set { SetValue(PreviousButtonTemplateProperty, value); }
    }

    // Same for other button templates
}

并使用ControlTemplate绑定从TemplatedParent内为这些日历绑定这些样式。

<ControlTemplate x:Key="MyCalender" TargetType="viewModels:MyCalendar">
    <Grid>
        <Button x:Name="PART_PreviousButton" 
        Grid.Row="0" Grid.Column="0"
        Template="{TemplateBinding  Property=PreviousButtonTemplate}" 
        Height="20" Width="28" 
        HorizontalAlignment="Left" 
        Focusable="False"
        />
    </Grid>
</ControlTemplate>

然后我会在最高级别定义一个默认样式,它将按钮模板(PreviousButtonTemplate等)分配给自定义日历控件的依赖项属性。尽可能高的级别,我指的是所有模板存在的对象,它们连接在一起,例如 app.xaml 或您的窗口。

<Style TargetType="viewModels:MyCalendar">
    <Setter Property="PreviousButtonTemplate" Value="{StaticResource PreviousButtonTemplate}" />
</Style>

或者,您可以保持原样,只要控件模板在运行时引用的StaticResources存在,它们就会被正确解析。不好,但没有设计时间支持。

修改

好吧,我没有说你指的是'原创'按钮模板,我认为你的意思是你已经在其他地方定义的模板。然后:不,你不能这样做。我一直在尝试同样的事情,但你不能创建使用原始部分的控制模板。 ControlTemplates没有“BasedOn”这样的东西。