【问题标题】:WPF, button inheriting Foreground for its contentWPF,按钮继承 Foreground 的内容
【发布时间】:2020-03-03 15:33:06
【问题描述】:

问题:如何设计按钮,它从其父级继承Foreground,但允许通过样式进行更改?

更准确地说,给定以下按钮:

<StackPanel TextBlock.Foreground="Red">
<ToggleButton Width="16" Height="16" FontSize="10" Style="{StaticResource ...}">
    <Grid>
        <Path Width="8" Height="8" Fill="...">
            <Path.Data>
                <PathGeometry Figures="M 1 0 L 1 4 L 0 4 L 0 5 L 3 5 L 3 8 L 4 8 L 4 5 L 7 5 L 7 4 L 6 4 L 6 0 L 1 0 z M 2 1 L 4 1 L 4 4 L 2 4 L 2 1 z " FillRule="NonZero"/>
            </Path.Data>
        </Path>
    </Grid>
</ToggleButton>
</StackPanel>

我需要,那个:

  • 路径的填充颜色与 StackPanel 的当前前景颜色相匹配,并且
  • 当用户将鼠标悬停在按钮上时,路径的填充颜色会变为某种特定的恒定颜色。

我尝试了按钮的设计风格,包括ControlTemplate,但Foreground有问题。 Button 通过主题将其Foreground 属性设置为某个DynamicResource,因此它与StackPanel 的Foreground 不匹配。

显然我可以绑定它,但随后样式和控制模板触发器停止工作,因为我已经为依赖属性设置了一个立即值,这推翻了所有其他为其提供值的方法。

为了给出问题的背景,这就是我想要实现的目标:

【问题讨论】:

  • StackPanel 什么时候有了Foreground 属性?
  • 附加 - TextBlock.Foreground.

标签: wpf wpf-style


【解决方案1】:

您可以像这样绑定到ToggleButton 的父Panel 的附加TextBlock.Foreground:

<Path Width="8" Height="8"
       Fill="{Binding (TextBlock.Foreground), 
           RelativeSource={RelativeSource AncestorType=Panel, AncestorLevel=2}}">
...

如果您希望Fill 在鼠标悬停时更改,您可以使用DataTrigger 定义Style:

<StackPanel TextBlock.Foreground="Red">
    <ToggleButton Width="16" Height="16" FontSize="10">
        <Grid>
            <Path Width="8" Height="8">
                <Path.Data>
                    <PathGeometry Figures="M 1 0 L 1 4 L 0 4 L 0 5 L 3 5 L 3 8 L 4 8 L 4 5 L 7 5 L 7 4 L 6 4 L 6 0 L 1 0 z M 2 1 L 4 1 L 4 4 L 2 4 L 2 1 z "
                                  FillRule="NonZero"/>
                </Path.Data>
                <Path.Style>
                    <Style TargetType="Path">
                        <Setter Property="Fill" Value="{Binding (TextBlock.Foreground), 
                     RelativeSource={RelativeSource AncestorType=Panel, AncestorLevel=2}}" />
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding IsMouseOver, 
                    RelativeSource={RelativeSource AncestorType=ToggleButton}}" Value="True">
                                <Setter Property="Fill" Value="Blue" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Path.Style>
            </Path>
        </Grid>
    </ToggleButton>
</StackPanel>

【讨论】:

    【解决方案2】:

    我自己想出来的——我忘了​​,样式设置器也可以设置绑定。解决方法如下。

    风格:

    <Style TargetType="ButtonBase" x:Key="DocumentTabButtonStyle">
        <Style.Setters>
            <Setter Property="TextBlock.Foreground" Value="{Binding Path=(TextBlock.Foreground), RelativeSource={RelativeSource AncestorType=StackPanel}}" />
            <Setter Property="Template">
                ...                
            </Setter>
        </Style.Setters>
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="TextBlock.Foreground" Value="{StaticResource DocumentButtonHoverForegroundBrush}"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    

    按钮:

    <Button Style="{StaticResource DocumentTabButtonStyle}">
        <Path Fill="{Binding Path=(TextBlock.Foreground), RelativeSource={RelativeSource AncestorType={x:Type Button}}}">
            <Path.Data>
                <PathGeometry Figures="M 0 1 L 3 4 L 0 7 L 2 7 L 4 5 L 6 7 L 8 7 L 5 4 L 8 1 L 6 1 L 4 3 L 2 1 Z" />
            </Path.Data>
        </Path>
    </Button>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多