【问题标题】:How to reference a control template from a standard control using bindings?如何使用绑定从标准控件引用控件模板?
【发布时间】:2013-05-21 09:58:29
【问题描述】:

我正在构建一个继承自标准 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 -->

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

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

【问题讨论】:

    标签: .net wpf xaml custom-controls controltemplate


    【解决方案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
    }
    

    并使用TemplatedParent 绑定从您的日历的ControlTemplate 中绑定到这些样式。

    <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”之类的东西。

    【讨论】:

    • 嗨,Marc,这是一种使用依赖属性的非常有趣的技术。但我不认为它可以解决任何问题。使用您的方法,我仍然需要为按钮创建样式/控件模板,只是它们的绑定方式非常不同?我正在寻找的是一种从 Controls.Calendar 控件中引用现有模板的方法。当然,我可能误解了一些东西:)
    • 好吧,我没听懂您指的是“原始”按钮模板,我以为您指的是您已经在其他地方定义的模板。然后:不,你不能这样做。我已经多次尝试同样的事情,但是您不能创建使用原始模板的一部分的控制模板。 ControlTemplates 没有“BasedOn”之类的东西。
    • 谢谢 Marc :) 我相信尽可能多地重用代码,所以我非常希望有这样的可能性。
    • 我也是,这很痛苦,尤其是在设计更复杂的控件时。理解具有视觉状态等的复杂控件模板可能需要一天的时间。无论如何,祝你好运。
    猜你喜欢
    • 2011-01-08
    • 2012-08-18
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多