【问题标题】:How do I force Button to look like pressed/hovered?如何强制 Button 看起来像按下/悬停?
【发布时间】:2016-02-03 16:26:04
【问题描述】:

我正在创建包含各种样式控件的演示应用程序。它让我可以快速预览更改。

我的问题是下面的代码不起作用:

<Button IsPressed="True">Pressed button</Button>

它说IsPressed 的设置器受到保护。我明白,但我需要破解它并将该按钮添加到 EnabledDisabled 按钮演示旁边。

我可能需要对IsMouseOver 属性执行相同的操作。这不是一个真正的应用程序,只是展示。您能帮我找到快速且可能最简单的方法吗?

【问题讨论】:

  • IsPressed 不是现有的按钮属性,因此您需要将其添加为依赖属性。
  • 存在,只是setter受保护,getter是public。
  • 为什么要使用受保护的设置器?
  • 谷歌搜索VisualStateManager你可能会发现一些有用的东西。
  • 将自己的 DP 设置为 IsPressOver 并在鼠标上下设置 true 和 false 并相应地应用样式

标签: c# wpf xaml


【解决方案1】:

改用 ToggleButton 并将 IsChecked 属性设置为“True”。这将模拟一个看起来被点击的按钮。

<ToggleButton IsChecked="True">Toggle Button</ToggleButton>

引用@rmoore 的这个 SO 答案。 WPF Checkbox with Button Appearance

【讨论】:

    【解决方案2】:

    有一种非常简单但冗长的方法来做到这一点 - 假设您可以访问按钮控件的样式。如果您使用的是标准 WPF 按钮,则样式可从 MSDN

    在那里你会找到一个VisualState 部分。每种状态一个:Normal、MouseOver、Pressed 等。诀窍很简单,但你最终会得到很多重复的代码(尽管这对于展示来说应该不是什么大问题。

    当您希望您的按钮看起来像按下时,您只需将&lt;VisualState x:Name="Pressed"&gt; 的内容添加到&lt;VisualState x:Name="Normal"&gt;。所以它应该是这样的:

    <VisualState x:Name="Normal">
        <Storyboard>
            <ColorAnimation Duration="0" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="#FF6DBDD1"/>
            <DoubleAnimation Duration="0" Storyboard.TargetName="BackgroundAnimation" Storyboard.TargetProperty="Opacity" To="1"/>
            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" To="#D8FFFFFF"/>
            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" To="#C6FFFFFF"/>
            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" To="#8CFFFFFF"/>
            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" To="#3FFFFFFF"/>
        </Storyboard>
    </VisualState>
    

    在默认样式中,Normal 部分为空。类似的操作也适用于MouseOver

    在我的结果的打印屏幕下方以及看起来像按下的按钮的完整 XAML 之后:

    <!--Button with Pressed style-->
    <Button Height="25" Width="50">
        <Button.Style>
            <Style TargetType="Button">
                <Setter Property="Background" Value="#FF1F3B53"/>
                <Setter Property="Foreground" Value="#FF000000"/>
                <Setter Property="Padding" Value="3"/>
                <Setter Property="BorderThickness" Value="1"/>
                <Setter Property="BorderBrush">
                    <Setter.Value>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="#FFA3AEB9" Offset="0"/>
                            <GradientStop Color="#FF8399A9" Offset="0.375"/>
                            <GradientStop Color="#FF718597" Offset="0.375"/>
                            <GradientStop Color="#FF617584" Offset="1"/>
                        </LinearGradientBrush>
                    </Setter.Value>
                </Setter>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="Button">
                            <Grid>
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Normal">
                                            <Storyboard>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="#FF6DBDD1"/>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="BackgroundAnimation" Storyboard.TargetProperty="Opacity" To="1"/>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" To="#D8FFFFFF"/>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" To="#C6FFFFFF"/>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" To="#8CFFFFFF"/>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" To="#3FFFFFFF"/>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="MouseOver">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="BackgroundAnimation" Storyboard.TargetProperty="Opacity" To="1"/>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" To="#F2FFFFFF"/>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" To="#CCFFFFFF"/>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" To="#7FFFFFFF"/>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Pressed">
                                            <Storyboard>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="#FF6DBDD1"/>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="BackgroundAnimation" Storyboard.TargetProperty="Opacity" To="1"/>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Color)" To="#D8FFFFFF"/>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)" To="#C6FFFFFF"/>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)" To="#8CFFFFFF"/>
                                                <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Rectangle.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)" To="#3FFFFFFF"/>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Disabled">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="Opacity" To=".55"/>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                    <VisualStateGroup x:Name="FocusStates">
                                        <VisualState x:Name="Focused">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Opacity" To="1"/>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Unfocused" />
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <Border x:Name="Background" CornerRadius="3" Background="White" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
                                    <Grid Background="{TemplateBinding Background}"  Margin="1">
                                        <Border Opacity="0"  x:Name="BackgroundAnimation" Background="#FF448DCA" />
                                        <Rectangle x:Name="BackgroundGradient" >
                                            <Rectangle.Fill>
                                                <LinearGradientBrush StartPoint=".7,0" EndPoint=".7,1">
                                                    <GradientStop Color="#FFFFFFFF" Offset="0" />
                                                    <GradientStop Color="#F9FFFFFF" Offset="0.375" />
                                                    <GradientStop Color="#E5FFFFFF" Offset="0.625" />
                                                    <GradientStop Color="#C6FFFFFF" Offset="1" />
                                                </LinearGradientBrush>
                                            </Rectangle.Fill>
                                        </Rectangle>
                                    </Grid>
                                </Border>
                                <ContentPresenter
                            x:Name="contentPresenter"
                            Content="{TemplateBinding Content}"
                            ContentTemplate="{TemplateBinding ContentTemplate}"
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                            Margin="{TemplateBinding Padding}"/>
                                <Rectangle x:Name="DisabledVisualElement" RadiusX="3" RadiusY="3" Fill="#FFFFFFFF" Opacity="0" IsHitTestVisible="false" />
                                <Rectangle x:Name="FocusVisualElement" RadiusX="2" RadiusY="2" Margin="1" Stroke="#FF6DBDD1" StrokeThickness="1" Opacity="0" IsHitTestVisible="false" />
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Button.Style>
    </Button>
    

    【讨论】:

      【解决方案3】:

      您可以简单地使用 Blend 来获取按钮的模板。 在那里你会找到 IsPressedBorderbrush/Background 的颜色。 与其他按钮(普通按钮)相比,设置这些按钮会让它们看起来像是被按下了。

      【讨论】:

        猜你喜欢
        • 2011-03-13
        • 2021-11-28
        • 2010-09-05
        • 1970-01-01
        • 1970-01-01
        • 2018-10-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-30
        相关资源
        最近更新 更多