【问题标题】:WPF ControlTemplate: How to provide a default value for TemplateBinding?WPF ControlTemplate:如何为 TemplateBinding 提供默认值?
【发布时间】:2010-12-20 02:23:44
【问题描述】:

我正在编写一个子类化按钮的 WPF 控件。然后我在 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 为空(= 不存在),但标准 Windows 控件(如 Button)提供默认外观,仍然可以由用户自定义。如何在我的控制下做到这一点?

谢谢!

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>

【问题讨论】:

    标签: wpf styles default controltemplate templatebinding


    【解决方案1】:

    当你为你的控件声明一个依赖属性时,你也声明了默认的 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));
    

    另一种方法是在自定义控件的构造函数中设置默认颜色,因为构造函数总是在用户设置任何属性之前被调用,如果用户未能设置它们,它们将默认为你的.事实上,它们总是由您设置,然后任何用户设置都会覆盖您的设置。如果您想设置诸如背景之类的属性,这尤其有效,您实际上并没有创建这些属性,这些属性来自您要继承的基类。

    【讨论】:

    • 谢谢,但我使用的是祖先的附加属性,所以默认值的技巧是不可能的。至于在构造函数中设置 - 那是在代码中编写xaml(这应该不是必需的),并且它不能被模板更改,所以我认为微软的控件不是这样做的。
    【解决方案2】:

    您可以为所讨论的两个属性在您的样式上定义设置器。

    例如一些通用定义:

    <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}" />
    

    【讨论】:

    • 酷,这就是我想知道的。我在问题中添加了您的解决方案。谢谢!
    【解决方案3】:

    还可以通过创建示例实例并引用其属性来“继承”Button 元素的默认样式:

    <Button x:Key="DefaultButton"/>
    
    <Style TargetType="{x:Type TestTemplate:MyButton}">
            <Setter Property="Background"
                    Value="{Binding Path=Background, Source={StaticResource DefaultButton}}" />
    </Style>
    

    【讨论】:

      【解决方案4】:
      <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>
      

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

      【讨论】:

      • 很好的答案!现在我可以在特定控件上指定自定义背景...
      猜你喜欢
      • 2013-05-23
      • 2019-01-22
      • 2015-02-28
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多