首页 文章

WPF ControlTemplate:如何为TemplateBinding提供默认值?

提问于
浏览
24

我正在编写一个WPF控件,它是Button的子类 . 然后我在Themes \ generic.xaml中提供了一个默认样式,它看起来像这样(简化):

<Style TargetType="{x:Type WPFControls:MyButton}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type WPFControls:MyButton}">
                <Button 
                    x:Name="PART_Button"
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我希望用户有机会更改控件的背景,但如果他没有,我想提供默认值 . 我该怎么做?

当我在发布的代码中执行它时,Background和BorderBrush为null(=不存在),除非用户明确指定它们(这有效地强制用户总是提供一些值),但标准的Windows控件(如Button)提供了默认的外观,仍然可以由用户定制 . 如何在我的控制下做到这一点?

谢谢!

Solution by Michael Morton:

您可以在样式中提供默认设置:

<Style TargetType="{x:Type TestTemplate:MyButton}">
    <Setter Property="Background" Value="Red" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TestTemplate:MyButton}">
                <Button 
                    x:Name="PART_Button"
                    IsEnabled="{TemplateBinding IsEnabled}"
                    Content="{TemplateBinding Content}"
                    Background="{TemplateBinding Background}"
                    />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

用法:

<StackPanel>
    <TestTemplate:MyButton Background="Blue">Explicitly blue</TestTemplate:MyButton>
    <TestTemplate:MyButton>Naturally red</TestTemplate:MyButton>
</StackPanel>

4 回答

  • 2

    您可以在样式上为这两个属性定义setter .

    例如,一些一般定义:

    <LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="#F3F3F3" Offset="0"/>
        <GradientStop Color="#EBEBEB" Offset="0.5"/>
        <GradientStop Color="#DDDDDD" Offset="0.5"/>
        <GradientStop Color="#CDCDCD" Offset="1"/>
    </LinearGradientBrush>
    
    <SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
    

    然后,在你的风格定义中:

    <Setter Property="Background" Value="{StaticResource ButtonNormalBackground}" />
    <Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}" />
    
  • 17

    为控件声明依赖项属性时,还会将默认值声明为UIPropertyMetadata

    此属性默认为Brushes.Red,如最后一行所示 .

    public Brush MyBrush {
         get { return (Brush)GetValue(MyBrushProperty); }
         set { SetValue(MyBrushProperty, value); }
      }
    
      public static readonly DependencyProperty MyBrushProperty =
          DependencyProperty.Register("MyBrush", typeof(Brush), typeof(MyQsFeature), new UIPropertyMetadata(Brushes.Red));
    

    你可以做的另一种方法是在自定义控件的构造函数中设置默认颜色,因为在用户设置任何属性之前总是会调用构造函数,如果用户未能设置它们,它们将默认为你的 . 实际上,它们总是由您设置,然后任何用户设置都将覆盖您的设置 . 如果要设置实际上不创建的后台属性,以及来自您继承的基类的属性,这是特别有用的 .

  • 1

    通过创建示例实例并引用其属性,也可以 Button 元素的"inherit"默认样式:

    <Button x:Key="DefaultButton"/>
    
    <Style TargetType="{x:Type TestTemplate:MyButton}">
            <Setter Property="Background"
                    Value="{Binding Path=Background, Source={StaticResource DefaultButton}}" />
    </Style>
    
  • 2
    <Style TargetType="{x:Type WPFControls:MyButton}">
        <Setter Property="Background" Value="Black">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type WPFControls:MyButton}">
                    <Button 
                        x:Name="PART_Button"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    注意第二个字符串,我将黑色设置为背景默认值 .

相关问题