【问题标题】:Swapping Colors in Button-Template on pressed按下时在按钮模板中交换颜色
【发布时间】:2023-03-16 16:44:01
【问题描述】:

我正在尝试设计一个按钮模板,当按下时它会交换颜色。

不幸的是,我无法让它工作。

我使用 BorderBrush 作为临时变量。很可能有更复杂的解决方案。

这是我的代码。

    <Style TargetType="{x:Type Button}">
        <Style.Setters>
            <Setter Property="Foreground"
                    Value="{StaticResource RahmenFarbe}" />
            <Setter Property="Background"
                    Value="{StaticResource HintergrundFarbe}" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Grid Width="{TemplateBinding Width}"
                              Height="{TemplateBinding Height}"
                              ClipToBounds="True">
                            <Border BorderBrush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button, AncestorLevel=1}, Path=Foreground}"
                                    x:Name="ButtonBorder"
                                    CornerRadius="25"
                                    BorderThickness="4"
                                    Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button, AncestorLevel=1}, Path=Background}"
                                    RenderTransformOrigin="0.5,0.5">
                                <TextBlock  x:Name="ButtonTextBlock"
                                            Foreground="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button, AncestorLevel=1}, Path=Foreground}"
                                            VerticalAlignment="Center"
                                            HorizontalAlignment="Center">
                                <ContentPresenter x:Name="myContentPresenter"
                                                  Content="{TemplateBinding Content}" />
                                </TextBlock>
                            </Border>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsPressed"
                                     Value="True">
                                <Setter Property="BorderBrush"
                                        Value="{Binding Mode=OneTime, Path=Foreground}" />
                                <Setter Property="Foreground"
                                        Value="{Binding Mode=OneTime, Path=Background}" />
                                <Setter Property="Background"
                                        Value="{Binding Mode=OneTime, Path=BorderBrush}" />
                            </Trigger>
                        </ControlTemplate.Triggers >

                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style.Setters>
    </Style>

任何帮助将不胜感激。

问候塞巴斯蒂安

【问题讨论】:

    标签: wpf templates xaml triggers styles


    【解决方案1】:

    更新

    终于明白你真正想做的事了。这是您完成它的方法。绑定到TemplatedParentBackgroundForeground 并在setter 中设置TargetName。这样,颜色的来源将始终保持不变,您可以轻松交换它们

    <ControlTemplate.Triggers>
        <Trigger Property="IsPressed" Value="True">
            <Setter TargetName="ButtonBorder"
                    Property="Background"
                    Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Foreground}" />
            <Setter TargetName="ButtonTextBlock"
                    Property="Foreground"
                    Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}" />
        </Trigger>
    </ControlTemplate.Triggers>
    

    (可选)您还可以将Template 中的Bindings 更改为

    Background="{Binding Path=Background,
                         RelativeSource={RelativeSource FindAncestor,
                                                        AncestorType=Button,
                                                        AncestorLevel=1}}"
    

    只是

    Background="{TemplateBinding Background}"
    

    【讨论】:

    • 我完全同意。但我喜欢存档的另一件事是,当我更改按钮中的颜色时,行为(交换)保持不变。如果颜色是硬编码的,它看起来会很尴尬。我担心我必须去寻找背后的代码(borderbrush 只是被滥用为一个临时变量)
    • 但是你已经在模板里给静态资源设置了Foreground和Background,是怎么被滥用的?如果您想使其动态化,请改用 DynamicResource 并覆盖您需要的位置。另一种选择是使用附加属性。由于背景也在变化,您将无法通过将前景设置为背景来交换它们
    • 实际上我将边框的前端和背景绑定到按钮的前端和背景。这些绑定应该是静态的。在触发器中,我更改了按钮属性,因此其他绑定不应该受到影响。我试图避免使用“Binding Mode=OneTime”进行自动更改。 DynamicResource 没有按我的预期工作,但也许我没有正确使用它。
    • @Athanviel: 更新了,这次我想我明白你的问题了:)
    • 非常好,我没想到它会起作用,但它确实起作用了。坦克很多:)
    【解决方案2】:

    这是使用代码隐藏的解决方案。

    <Style TargetType="{x:Type Button}">
            <Style.Setters>
                <Setter Property="Foreground"
                        Value="{StaticResource RahmenFarbe}" />
                <Setter Property="Background"
                        Value="{StaticResource HintergrundFarbe}" />
                <Setter Property="FontSize"
                        Value="18" />
                <Setter Property="FontWeight"
                        Value="Bold" />
                <EventSetter Event="PreviewMouseDown"
                             Handler="vertauscheFarben" />
                <EventSetter Event="PreviewMouseUp"
                             Handler="vertauscheFarben" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Button}">
                            <Grid Width="{TemplateBinding Width}"
                                  Height="{TemplateBinding Height}"
                                  ClipToBounds="True">
                                <Border BorderBrush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button, AncestorLevel=1}, Path=Foreground}"
                                        x:Name="ButtonBorder"
                                        CornerRadius="25"
                                        BorderThickness="4"
                                        Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button, AncestorLevel=1}, Path=Background}"
                                        RenderTransformOrigin="0.5,0.5">
                                    <TextBlock  x:Name="ButtonTextBlock"
                                                Foreground="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Button, AncestorLevel=1}, Path=Foreground}"
                                                VerticalAlignment="Center"
                                                HorizontalAlignment="Center">
                                    <ContentPresenter x:Name="myContentPresenter"
                                                      Content="{TemplateBinding Content}" />
                                    </TextBlock>
                                </Border>
                            </Grid>
    
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style.Setters>
        </Style>
    

    这是代码隐藏

    Private Sub vertauscheFarben(sender As Object, e As MouseButtonEventArgs)
        Dim Button = DirectCast(sender, Button)
    
        Dim Temp = Button.Foreground
        Button.Foreground = Button.Background
        Button.Background = Temp
    End Sub
    

    它正在工作,但我更喜欢在 Xaml 中使用它 - 所以我不会将此标记为已回答。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-31
      • 2019-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      相关资源
      最近更新 更多