将按钮设置为选中状态并更改样式

时间:2013-04-04 22:31:43

标签: c# wpf button styles visualstatemanager

这是我的实际按钮样式:

<Style x:Key="CategoryButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="Padding" Value="1"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid x:Name="grid">
                    <Path x:Name="TabPath" StrokeThickness="2"
                          Margin="{Binding ElementName=buttonContent, Converter={x:Static c:ContentToMarginConverter.Value}}"
                          Stroke="{StaticResource BorderBrush1}"
                          Fill="{StaticResource TabItemPathBrush}">
                        <Path.Data>
                            <PathGeometry>
                                <PathFigure IsClosed="False" StartPoint="1,0" 
                                            Segments="{Binding ElementName=buttonContent, Converter={x:Static c:ContentToPathConverter.Value}}">
                                </PathFigure>
                            </PathGeometry>
                        </Path.Data>
                        <Path.LayoutTransform>
                            <!-- For some reason  -->
                            <ScaleTransform ScaleY="-1"/>
                        </Path.LayoutTransform>
                    </Path>
                    <Rectangle x:Name="TabItemTopBorder" Height="2" Visibility="Visible"
                               VerticalAlignment="Bottom" Fill="{StaticResource BorderBrush1}"
                               Margin="{Binding ElementName=TabPath, Path=Margin}" />
                    <ContentPresenter x:Name="buttonContent" Margin="10,2,10,2" VerticalAlignment="Center"
                                      TextElement.Foreground="{StaticResource ForegroundBrush}"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Fill" TargetName="TabPath">
                            <Setter.Value>
                                <SolidColorBrush Color="#FFe4f6fa"/>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="BitmapEffect">
                            <Setter.Value>
                                <DropShadowBitmapEffect Direction="302" Opacity="0.4" 
                                                        ShadowDepth="2" Softness="0.5"/>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Opacity" TargetName="grid" Value="0.25"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我需要添加代码,我可以将按钮设置为选中状态,看起来就像按下按钮一样。我正在考虑使用VisualStateManager,但我不确定它是否是好方法,我怎么能这样做。我从这样的事情开始:

<VisualStateManager.VisualStateGroups>
     <VisualState x:Name="Normal" />
     <VisualState x:Name="Selected">
        <Storyboard>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TabPath" 
                                   Storyboard.TargetProperty="Fill">
                                    <DiscreteObjectKeyFrame KeyTime="0" Value="#FFe4f6fa" />
             </ObjectAnimationUsingKeyFrames>
         </Storyboard>
     </VisualState>
</VisualStateManager.VisualStateGroups>

但它不起作用。我只是不知道在故事板中使用什么。

修改 - 几乎正常工作:

<VisualState x:Name="Selected">
     <Storyboard>
        <ColorAnimation Storyboard.TargetName="TabPath" Storyboard.TargetProperty="Fill.(LinearGradientBrush.GradientStops)[0].(GradientStop.Color)" To="#FFe4f6fa" Duration="0:0:0" />
        <ColorAnimation Storyboard.TargetName="TabPath" Storyboard.TargetProperty="Fill.(LinearGradientBrush.GradientStops)[1].(GradientStop.Color)" To="#FFa9cde7" Duration="0:0:0" />               
      </Storyboard>
 </VisualState>

忘记添加我的画笔:

<LinearGradientBrush x:Key="TabItemSelectedPathBrush" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Color="#FFe4f6fa" Offset="0"/>
    <GradientStop Color="#FFa9cde7" Offset="1"/>
</LinearGradientBrush>

<LinearGradientBrush x:Key="TabItemPathBrush" StartPoint="0,0" EndPoint="0,1">
    <GradientStop Color="#FFa9cde7" Offset="0"/>
    <GradientStop Color="#FF3164a5" Offset="1"/>
</LinearGradientBrush>

3 个答案:

答案 0 :(得分:3)

使用使用相同样式和模板的ToggleButton

以您的样式(原始问题中的样式)将样式和控件模板上的TargetType更改为ButtonBase

在控制模板触发器中添加此触发器:

 <Trigger Property="ToggleButton.IsChecked" Value="True">
     <Setter Property="Fill" TargetName="TabPath">
         <Setter.Value>
             <SolidColorBrush Color="#FFe4f6fa"/>
         </Setter.Value>
     </Setter>
     <Setter Property="BitmapEffect">
         <Setter.Value>
             <DropShadowBitmapEffect Direction="302" Opacity="0.4" ShadowDepth="2" Softness="0.5"/>
         </Setter.Value>
     </Setter>
 </Trigger>

现在,您可以将此样式用于按钮,切换按钮,单选按钮和复选框。

答案 1 :(得分:2)

我个人会将Blend用于此类任务,它实际上是Visual Studio开发WPF应用程序的伴侣。

只需点击几下,您就无法使用它,或者只是将它生成的XAML复制到项目中。

编辑按钮样式

enter image description here

触发

enter image description here

以下是您所有的按钮状态

enter image description here

混合就像黄油面包,WPF更美味,除非你更喜欢纯黄油: - )

请注意,如果您使用的是VS2012并且正在使用WPF项目,则Microsoft Blend + SketchFlow Preview for Visual Studio 2012是允许您编辑WPF项目的版本。与VS2012捆绑在一起的版本仅适用于Windows应用商店应用。

答案 2 :(得分:2)

应在VisualStates的根元素上声明

ControlTemplate。使用以下代码,

        <Grid>
    <Grid.Resources>
        <SolidColorBrush x:Key="FillBrush" Color="Magenta" />
        <Color x:Key="StateBrush" >#a3bfb1</Color>
        <Style x:Key="CategoryButtonStyle" TargetType="{x:Type Button}">
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>

            <Setter Property="Padding" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Border Background="Green" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" x:Name="root">

                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TabPath" 
                               Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)">
                                                <DiscreteObjectKeyFrame KeyTime="0"  Value="{StaticResource StateBrush}">

                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Grid x:Name="grid">
                                <Path x:Name="TabPath" StrokeThickness="1" 

                      Stroke="Blue"
                      Fill="{StaticResource FillBrush}" Canvas.Left="16.75"
          Canvas.Top="14"
          Width="50"
          Height="40"
          Data="F1 M 26.75,24L 16.75,34L 23.5,34L 34,24L 23.5,14L 16.75,14L 26.75,24 Z ">
                                    <Path.LayoutTransform>
                                        <!-- For some reason  -->
                                        <ScaleTransform ScaleY="-1"/>
                                    </Path.LayoutTransform>
                                </Path>
                                <ContentPresenter x:Name="buttonContent" Margin="10,2,10,2" VerticalAlignment="Center"
                                  TextElement.Foreground="{TemplateBinding Foreground}"/>
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </Grid.Resources>
    <Button x:Name="test" Style="{StaticResource CategoryButtonStyle}" Content="Test"  VerticalAlignment="Center" Width="200px" BorderBrush="#888" BorderThickness="1px"/>
</Grid>

此代码将按预期更改状态。

  

VisualStateManager.GoToState(test,“TestState”,true);

根据需要更改模板,但请确保将VisualState声明放在ControlTemplate的根元素中(在此示例中为Border

修改: 我已使用正确的属性路径更新了Selected VisualState的转换声明。如果它能解决您的问题,请告诉我。