【问题标题】:Can you have parameterized Style in WPF?您可以在 WPF 中参数化样式吗?
【发布时间】:2018-11-03 17:31:20
【问题描述】:

我正在尝试找到一种解决方案,以便在 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 中有某种样式,我可以在其中指定初始 BorderThickness 作为参数(或其他东西沿线),其余的都是一样的。

我试图将BorderThickness="p,q,r,s" 部分移动到&lt;Button ...&gt; 标记,但是当我将鼠标悬停时,样式并没有应用(我的假设是它们之间存在层次结构)。

【问题讨论】:

  • 嗨,我认为很多关于 wfp 样式的在线教程都涵盖了这一点。
  • @Stefan 我知道一般是如何使用样式的,但在使用稍微不同的样式时就不知道了。我不想在 3 个地方维护类似的代码。 3 种样式之间存在差异,但只有很小的一种,可以参数化 - 如果有此选项的话。
  • 那么文章中提到的Style inheritance不够?
  • @Stefan 这可能就足够了,但是我只能移出 部分,而不是完整的

标签: c# wpf templates button styles


【解决方案1】:

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

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

【讨论】:

  • 我认为有一个选项可以让您不必创建 4 种不同的样式。这和我做的类似,只是更复杂一点。谢谢!
【解决方案2】:

您可以使用动画,因为它的优先级高于本地值: 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 2020-11-05
    • 2011-03-17
    相关资源
    最近更新 更多