你能在WPF中使用参数化样式吗?

时间:2018-05-24 13:03:25

标签: c# wpf templates button styles

我正在尝试在WPF中找到在XAML中重用代码的解决方案: 我有3个按钮,风格非常相似,唯一的区别是BorderThickness。它们都有一个样式触发器设置,如果用户将鼠标移到它们上面,则BorderThickness设置为1.

<Button Width="50" Height="50" BorderBrush="#66CCFF" >
  <Button.Style>
    <Style TargetType="{x:Type Button}">
      <Setter Property="BorderThickness" Value="0,0,0,1" />
      <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
          <Setter Property="BorderThickness" Value="1"/>
        </Trigger>
      </Style.Triggers>
      </Style>
  </Button.Style>
  <Image Margin="12" Source="picture1.png"/>
</Button>

<Button Width="50" Height="50" BorderBrush="#66CCFF">
  <Button.Style>
    <Style TargetType="{x:Type Button}">
      <Setter Property="BorderThickness" Value="0,1,0,1" />
      <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
          <Setter Property="BorderThickness" Value="1"/>
        </Trigger>
      </Style.Triggers>
      </Style>
  </Button.Style>
  <Image Margin="12" Source="picture2.png"/>
</Button>

<Button Width="50" Height="50"BorderBrush="#66CCFF">
  <Button.Style>
    <Style TargetType="{x:Type Button}">
      <Setter Property="BorderThickness" Value="1,0,1,1" />
      <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
          <Setter Property="BorderThickness" Value="1"/>
        </Trigger>
      </Style.Triggers>
    </Style>
  </Button.Style>
  <Image Margin="12" Source="picture3.png"/>
</Button>

由于除了IsMouseOver为false时应用的BorderThickness之外,样式实际上是相同的,我想删除代码重复,并在ResourceDictionary中有一些Style,我可以在其中指定初始BorderThickness作为参数(或者某些东西)沿线)其余的是相同的。

我尝试将BorderThickness="p,q,r,s"部分移动到<Button ...>标记,但是当鼠标悬停时,样式不会被应用(我的假设是它们之间存在层次结构)。

2 个答案:

答案 0 :(得分:2)

不确定这是否是您的目标,但常见的方法是在app.xaml中创建样式定义并在模板或页面上使用这些styes,它使用常用的重用基本样式,可重用厚度(这里只使用一次)和继承:

<Application.Resources>
    <ResourceDictionary>
        <!-- not really parameters, more like static values. -->
        <!-- these could be bind dynamically and -->
        <!-- controlled from code if you like. -->
        <!-- ps: i used different values. -->
        <Thickness x:Key="topThickness">10,0,0,0</Thickness>
        <Thickness x:Key="middleThickness">0,10,0,0</Thickness>
        <Thickness x:Key="bottomThickness">0,0,10,0</Thickness>

        <Style x:Key="buttonBase" TargetType="{x:Type Button}">
            <Setter Property="Width" Value="50" />
            <Setter Property="Height" Value="50" />
            <Setter Property="BorderBrush" Value="#66CCFF" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="BorderThickness" Value="1"/>
                </Trigger>
            </Style.Triggers>
        </Style>

        <Style x:Key="buttonTop" 
               BasedOn="{StaticResource buttonBase}" 
               TargetType="{x:Type Button}">
            <Setter Property="BorderThickness" 
                    Value="{StaticResource topThickness}" />
        </Style>

        <Style x:Key="buttonMiddle" 
               BasedOn="{StaticResource buttonBase}" 
               TargetType="{x:Type Button}">
            <Setter Property="BorderThickness" 
                    Value="{StaticResource middleThickness}" />
        </Style>

        <Style x:Key="buttonBottom" 
               BasedOn="{StaticResource buttonBase}" 
               TargetType="{x:Type Button}">
            <Setter Property="BorderThickness" 
                    Value="{StaticResource bottomThickness}" />
        </Style>
    </ResourceDictionary>
</Application.Resources>

在你的窗口中:请注意,实际样式是在资源字典中控制的

<Button Style="{StaticResource buttonTop}" >
    <Image Margin="12" Source="picture1.png"/>
</Button>
<Button Style="{StaticResource buttonMiddle}" >
   <Image Margin="12" Source="picture1.png"/>
</Button>
<Button Style="{StaticResource buttonBottom}" >
    <Image Margin="12" Source="picture1.png"/>
</Button>

答案 1 :(得分:0)

您可以使用动画,因为它的优先级高于本地值: https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/dependency-property-value-precedence

<Style TargetType="Button">
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard x:Name="BorderAnimation">
                    <Storyboard TargetProperty="BorderThickness">
                        <ThicknessAnimation To="1" Duration="0"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <RemoveStoryboard BeginStoryboardName="BorderAnimation"/>
            </Trigger.ExitActions>
        </Trigger>
    </Style.Triggers>
</Style>

<UniformGrid Columns="2" Rows="2" Width="100" Height="100">
    <Button BorderThickness="1 1 0 0"/>
    <Button BorderThickness="0 1 1 0"/>
    <Button BorderThickness="1 0 0 1"/>
    <Button BorderThickness="0 0 1 1"/>
</UniformGrid>