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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1793611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:15:24  来源:igfitidea点击:

WPF ControlTemplate: How to provide a default value for TemplateBinding?

wpfstylesdefaultcontroltemplatetemplatebinding

提问by Tomá? Kafka

I am writing a WPF control that subclasses a Button. I then provide a default style in Themes\generic.xaml, that looks like this (simplified):

我正在编写一个子类化按钮的 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>

I would like the user to have the opportunity to change the control's background, but if he doesn't, I'd like to provide default value. How do I do it?

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

When I do it like in the posted code, the Background and BorderBrush is null (= nonexistent) unless user explicitly specifies them (which effectively forces user to always provide some value), but the standard windows controls (like Button) provide a default look, that can still be customized by user. How to do this in my control?

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

Thank you!

谢谢!

Solution by Michael Morton:

Michael Morton 的解决方案:

You can provide defaults as setters in style:

您可以在样式中提供默认值作为设置器:

<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>

Usage:

用法:

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

采纳答案by Michael Morton

You can just define setters on your style for the two properties in question.

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

For example, some general definitions:

例如,一些通用定义:

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

Then, in your style definition:

然后,在您的样式定义中:

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

回答by Marat Batalandabad

<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>

Pay attention on seccond string, I set Black color to Background default value.

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

回答by Marcin Wisnicki

It is also possible to "inherit" default style of the Buttonelement by creating sample instance and referencing its properties:

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

<Button x:Key="DefaultButton"/>

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

回答by Aran Mulholland

When you declare a dependency property for your controls you also declare the default as UIPropertyMetadata

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

this property defaults to Brushes.Red, as you can see in the last line.

此属性默认为 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));

the other way you could do it is by setting the default colour in the constructor of your custom control, as the constructor always gets called before any properties are set by the user if the user fails to set them they would default to yours. In fact they would always get set by you and then any user setting will override yours. This is esp effective if you want to set the properties such as Background that you are not actually creating, the ones that are coming from your the base classes that you are inheriting from.

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