34

我正在编写一个子类化按钮的 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)提供默认外观,仍然可以由用户自定义。如何在我的控制下做到这一点?

谢谢!

迈克尔莫顿的解决方案:

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

<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

4 回答 4

22

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

例如,一些通用定义:

<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}" />
于 2009-11-25T00:26:33.593 回答
5
<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-11-17T02:10:45.347 回答
3

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

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

于 2009-11-24T23:29:38.173 回答
2

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

<Button x:Key="DefaultButton"/>

<Style TargetType="{x:Type TestTemplate:MyButton}">
        <Setter Property="Background"
                Value="{Binding Path=Background, Source={StaticResource DefaultButton}}" />
</Style>
于 2012-03-26T12:20:06.753 回答