【问题标题】:WPF Generic style that can be inherited by other stylesWPF 可以被其他样式继承的通用样式
【发布时间】:2016-03-23 09:59:40
【问题描述】:

我首先说我没有太多使用 WPF 的经验,因为我刚开始使用它(我之前的所有 C# 经验都是使用 Windows 窗体和 ASP.net)。

假设我在 App.xaml 中定义了两种样式,一种定义蓝色按钮,另一种定义红色按钮:

<Style x:Key="BlueButton" TargetType="Button">
    <Setter Property="Foreground" Value="White" />
    <Setter Property="Background">
        <Setter.Value>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF50D0FF"/>
                <GradientStop Color="#FF0092C8" Offset="1"/>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border CornerRadius="2" Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsPressed" Value="True">
            <Setter Property="Background">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF0092C8"/>
                        <GradientStop Color="#FF50D0FF" Offset="1"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
</Style>
<Style x:Key="RedButton" TargetType="Button">
    <Setter Property="Foreground" Value="White" />
    <Setter Property="Background">
        <Setter.Value>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FFFFAE00" Offset="0"/>
                <GradientStop Color="Red" Offset="1"/>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border CornerRadius="2" Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsPressed" Value="True">
            <Setter Property="Background">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Red" Offset="0"/>
                        <GradientStop Color="#FFFFAE00" Offset="1"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
</Style>

我怎样才能合并这两种样式以创建一个“包含两者”的通用样式?

编辑:

Dmitriy Polyanskiy 的回答有效,但每次我想创建新样式时,我仍然必须设置每个属性。有没有办法做这样的事情:&lt;Style x:Key="RedButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}" Color1="#FFFFAE00" Color2="Red" /&gt;

<Style x:Key="RedButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
    <Setter Property="Color1" Value="#FFFFAE00" />
    <Setter Property="Color2" Value="Red" />
</Style>

然后自动设置两种渐变色?

【问题讨论】:

  • 合并两种样式是什么意思?你怎么能有一个蓝色和红色的按钮?
  • 我的意思是有一个通用的样式,这样如果我想添加一个绿色按钮,我就可以做到,而无需重新编写所有内容。
  • 我想你在找BasedOn
  • 在复制现有问题之前,请寻找能够回答您问题的问题。

标签: c# wpf wpf-style


【解决方案1】:

基本上,您想要创建的是基于“参数化”样式的样式。

您需要做的是使用 DynamicResources 为 GradientStop 的颜色创建基本样式。然后,在您基于它的样式中,覆盖资源颜色。

基本按钮样式:

<Style x:Key="BaseButtonStyle" TargetType="Button">
    <Style.Resources>
        <Color x:Key="Color1">White</Color>
        <Color x:Key="Color2">Gray</Color>
    </Style.Resources>
    <Setter Property="Foreground" Value="White" />
    <Setter Property="Background">
        <Setter.Value>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="{DynamicResource Color1}"/>
                <GradientStop Color="{DynamicResource Color2}" Offset="1"/>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border CornerRadius="2" Background="{TemplateBinding Background}">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsPressed" Value="True">
            <Setter Property="Background">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="{DynamicResource Color2}" />
                        <GradientStop Color="{DynamicResource Color1}" Offset="1" />
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Trigger>
    </Style.Triggers>
</Style>

基于样式:

<Style x:Key="RedButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
    <Style.Resources>
        <Color x:Key="Color1">#FFFFAE00</Color>
        <Color x:Key="Color2">Red</Color>
    </Style.Resources>
</Style>
<Style x:Key="BlueButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
    <Style.Resources>
        <Color x:Key="Color1">#FF50D0FF</Color>
        <Color x:Key="Color2">#FF0092C8</Color>
    </Style.Resources>
</Style>
<Style x:Key="GreenButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
    <Style.Resources>
        <Color x:Key="Color1">Green</Color>
        <Color x:Key="Color2">LightGreen</Color>
    </Style.Resources>
</Style>
<Style x:Key="PurpleYellowButton" TargetType="Button" BasedOn="{StaticResource BaseButtonStyle}">
    <Style.Resources>
        <Color x:Key="Color1">Purple</Color>
        <Color x:Key="Color2">Yellow</Color>
    </Style.Resources>
</Style>

按钮堆栈面板的屏幕截图:

【讨论】:

    【解决方案2】:

    我刚刚为您创建了一个快速示例,向您展示如何做到这一点。您应该使用通用属性来描述基本样式。然后只需使用 BaseOn={StaticResource BaseStyle}

    <Style x:Key="BaseButtonStyle" TargetType="Button">
        <Setter Property="Foreground" Value="White" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border
                        CornerRadius="2"
                        Background="{TemplateBinding Background}">
                        <ContentPresenter
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    
    <Style x:Key="RedButton" TargetType="Button"
           BasedOn="{StaticResource BaseButtonStyle}">
        <Setter Property="Background">
            <Setter.Value>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FFFFAE00" Offset="0"/>
                    <GradientStop Color="Red" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsPressed" Value="True">
                <Setter Property="Background">
                    <Setter.Value>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="Red" Offset="0"/>
                            <GradientStop Color="#FFFFAE00" Offset="1"/>
                        </LinearGradientBrush>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
    

    【讨论】:

      【解决方案3】:

      实现此目的的一种方法是定义样式,而不是在样式本身中提供渐变,您可以使用如下所示的 DynamicResource。然后对于每个按钮,您可以定义将要使用的本地资源 LinearGradientBrush 并在那里设置颜色。

      <Window x:Class=""
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              Title="MainWindow" Height="350" Width="525">
          <Window.Resources>
              <Style x:Key="BaseButtonStyle" TargetType="Button">
                  <Setter Property="Foreground" Value="White" />
                  <Setter Property="Background" Value="{DynamicResource GradientBrushNormal}">
                  </Setter>
                  <Setter Property="Template">
                      <Setter.Value>
                          <ControlTemplate TargetType="{x:Type Button}">
                              <Border CornerRadius="2" Background="{TemplateBinding Background}">
                                  <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                              </Border>
                          </ControlTemplate>
                      </Setter.Value>
                  </Setter>
                  <Style.Triggers>
                      <Trigger Property="IsPressed" Value="True">
                          <Setter Property="Background" Value="{DynamicResource GradientBrushPressed}">
                          </Setter>
                      </Trigger>
                  </Style.Triggers>
              </Style>
          </Window.Resources>
          <StackPanel>
             <Button Style="{StaticResource BaseButtonStyle}" Content="Blue Button">
                  <Button.Resources>
                      <LinearGradientBrush x:Key="GradientBrushPressed" EndPoint="0.5,1" StartPoint="0.5,0">
                          <GradientStop Color="#FF0092C8"/>
                          <GradientStop Color="#FF50D0FF" Offset="1"/>
                      </LinearGradientBrush>
                      <LinearGradientBrush x:Key="GradientBrushNormal" EndPoint="0.5,1" StartPoint="0.5,0">
                          <GradientStop Color="#FF50D0FF"/>
                          <GradientStop Color="#FF0092C8" Offset="1"/>
                      </LinearGradientBrush>
                  </Button.Resources>
             </Button>
              <Button Style="{StaticResource BaseButtonStyle}" Content="Red Button">
                  <Button.Resources>
                      <LinearGradientBrush x:Key="GradientBrushPressed" EndPoint="0.5,1" StartPoint="0.5,0">
                          <GradientStop Color="Red" Offset="0"/>
                          <GradientStop Color="#FFFFAE00" Offset="1"/>
                      </LinearGradientBrush>
                      <LinearGradientBrush x:Key="GradientBrushNormal" EndPoint="0.5,1" StartPoint="0.5,0">
                          <GradientStop Color="#FFFFAE00" Offset="0"/>
                          <GradientStop Color="Red" Offset="1"/>
                      </LinearGradientBrush>
                  </Button.Resources>
              </Button>
          </StackPanel>
      </Window>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-07
        • 2010-11-09
        • 2021-05-13
        • 1970-01-01
        相关资源
        最近更新 更多