【问题标题】:Style inherittance between different target types不同目标类型之间的样式继承
【发布时间】:2021-11-26 16:17:14
【问题描述】:

我不知道我是不是理解不正确。我正在尝试为我的应用程序制作 2 种不同的按钮样式:BlueOnWhiteButton 和 WhiteOnBlueButton。

这两个按钮应该是相同的,但前景和背景是相反的。到目前为止,哦,这么简单。

这里有一个问题:我需要我的按钮有圆角。这个简单的需求,终究似乎没有那么简单。两个版本上也可能有不同颜色的小边框。

使用我在 google 和 stack 上找到的一些东西,我为第一个设计了这种风格,看起来很有希望:

<Style  x:Key="WhiteOnBlueButton"
        TargetType="Button">

    <Setter Property="Background" Value="{StaticResource MainBlue}" />
    <Setter Property="Foreground" Value="White" />
    <Setter Property="FontWeight" Value="bold" />

    <Style.Resources>
        <Style TargetType="Border">
            <Setter Property="CornerRadius" Value="5" />
            <Setter Property="BorderThickness" Value="2" />
            <Setter Property="BorderBrush" Value="{StaticResource LightBlue}" />
        </Style>
    </Style.Resources>
</Style>

到目前为止一切顺利,我的按钮看起来像我想要的那样。但是,当我尝试在下面创建第二个样式时,由于 Style.Resources 重新定义,我在运行时遇到错误。我会把代码块保存给你,用不同的名称和相反的颜色来显示相同​​的图形。

我试图让样式的使用尽可能简单,我尝试过带有模板的版本,但它使样式变得更加复杂,我什至丢失了按钮文本...

我想要的是这样的:

<Style x:Key="RoundedButtonCornersNoBorder" TargetType="Border">
    <Setter Property="CornerRadius" Value="4"/>
    <Setter Property="BorderThickness" Value="0" />
</Style>
                    
<Style x:Key="RoundedButtonCorners" TargetType="Border">
    <Setter Property="CornerRadius" Value="4"/>
    <Setter Property="BorderBrush" Value="{StaticResource LightBlue}" />
    <Setter Property="BorderThickness" Value="2" />
</Style>

<Style  x:Key="WhiteOnBlueButton"
        TargetType="Button">

    <Setter Property="Background" Value="{StaticResource MainBlue}" />
    <Setter Property="Foreground" Value="White" />
    <Setter Property="FontWeight" Value="bold" />
    <!-- Somehow tell the borders should be taken from the style RoundedButtonCornersNoBorder-->
</Style>

<Style  x:Key="BlueOnWhiteButton"
    TargetType="Button">

    <Setter Property="Background" Value="White" />
    <Setter Property="Foreground" Value="{StaticResource MainBlue}" />
    <Setter Property="FontWeight" Value="bold" />
    <!-- Somehow tell the borders should be taken from the style RoundedButtonCorners-->
</Style>

有没有什么方法可以在不写 300 行难以理解的代码的情况下进行编码?

最终目标是通过简单地应用样式:

<Button
    Style="{DynamicResource WhiteOnBlueButton}"
    Content="CLICK ME!" />

【问题讨论】:

  • 查看 Style.BasedOn 属性,了解如何声明一个通用的基本样式。
  • Clemens,仅当两种样式都针对同一类型时才有效。
  • 他们会做什么。边框样式将位于基本按钮样式的资源中。你自己写的时候没有注意到我的回答。但是,您的帖子实际上并没有回答这个问题。这只是说一些库控件最终会神奇地做你需要的事情。

标签: wpf xaml


【解决方案1】:

您可以在公共基本样式的资源中移动边框样式,并通过BasedOn 属性从公共基本样式派生最终的按钮样式。

不要在边框样式中设置BorderBrush,而是在基本或最终按钮样式中设置。 Button Template 中的 Border 将通过 TemplateBinding 从 Button 中拾取它。

<Style x:Key="RoundedButtonCorners" TargetType="Button">
    <Style.Resources>
        <Style TargetType="Border">
            <Setter Property="CornerRadius" Value="5"/>
            <Setter Property="BorderThickness" Value="2"/>
        </Style>
    </Style.Resources>
    <Setter Property="BorderBrush" Value="{StaticResource LightBlue}"/>
    <Setter Property="FontWeight" Value="Bold" />
</Style>

<Style x:Key="WhiteOnBlueButton" TargetType="Button"
       BasedOn="{StaticResource RoundedButtonCorners}">
    <Setter Property="Background" Value="{StaticResource MainBlue}"/>
    <Setter Property="Foreground" Value="White"/>
</Style>

<Style x:Key="BlueOnWhiteButton" TargetType="Button"
       BasedOn="{StaticResource RoundedButtonCorners}">
    <Setter Property="Background" Value="White"/>
    <Setter Property="Foreground" Value="{StaticResource MainBlue}"/>
</Style>

【讨论】:

  • 谢谢!我不确定我是否理解你的评论。这很有意义!
【解决方案2】:

原来我们有一个库,它有一个直接暴露边框的按钮。

最终样式如下所示:

<Style x:Key="WhiteOnBlueButton" TargetType="telerik:RadButton">
    <Setter Property="Foreground" Value="White" />
    <Setter Property="Background" Value="{StaticResource MainBlue}" />
    <Setter Property="FontWeight" Value="bold" />
                        
    <Setter Property="CornerRadius" Value="5" />
    <Setter Property="BorderBrush" Value="{StaticResource LightBlue}" />
    <Setter Property="BorderThickness" Value="0" />
</Style>

<Style x:Key="BlueOnWhiteButton" TargetType="telerik:RadButton">
    <Setter Property="Foreground" Value="{StaticResource MainBlue}" />
    <Setter Property="Background" Value="White" />
    <Setter Property="FontWeight" Value="bold" />

    <Setter Property="CornerRadius" Value="5" />
    <Setter Property="BorderBrush" Value="{StaticResource LightBlue}" />
    <Setter Property="BorderThickness" Value="0" />
</Style>

然后构建我的按钮:

<telerik:RadButton
    x:Name="xamlFullTextSearchButton"
    Style="{StaticResource BlueOnWhiteButton}"
    Grid.Column="2"
    Grid.Row="0"
    Content="CLICK ME"
    CornerRadius="4"/>

有了这个,我什至没有松开点击动画!它非常适合我的需要!

【讨论】:

  • 遵循@Clemens 的建议可以使您的解决方案变得更简单;考虑在您的样式中使用 BasedOn。
猜你喜欢
  • 1970-01-01
  • 2016-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-21
  • 2015-08-25
  • 1970-01-01
  • 2019-06-23
相关资源
最近更新 更多