使用ViewStateManager为自定义按钮设置动画

时间:2014-03-15 11:46:15

标签: c# wpf xaml visualstatemanager

我正在为我的项目制作自定义按钮 我没有使用默认Button,只是ContentControl分配了ControlTemplate

刚开始只是一个简单的模板:

<ControlTemplate x:Key="MySampleTemplate">
    <Image x:Name="img" Source="/AppName;component/Res/Img/normalstate.png" />
</ControlTemplate>

现在我想使用VisualStateManager为图像添加动画效果 首先,我创建了一个&#34; Hover&#34;和#34;正常&#34;状态:

<ControlTemplate x:Key="MySampleTemplate">
    <Image x:Name="img" Source="/AppName;component/Res/Img/normalstate.png">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup Name="CommonStates">
                <VisualState Name="Normal" />
                <VisualState Name="Hover">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames BeginTime="0"
                                                       Storyboard.TargetName="img" Storyboard.TargetProperty="Source">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <BitmapImage UriSource="/AppName;component/Res/Img/hoverstate.png" />
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Image>
</ControlTemplate>

在代码背后:

btnSampleButton.MouseEnter += (s,e) => VisualStateManager.GoToState(btnSampleButton, "Hover", false);
btnSampleButton.MouseLeave += (s,e) => VisualStateManager.GoToState(btnSampleButton, "Normal", false);

一切正常。如果我将鼠标悬停在显示的按钮hoverstate.png上,则显示我是否将鼠标悬停在normalstate.png上。
现在,如果用户点击按钮,我想动画LeftMouseButtonDownLeftMouseButtonUp来实现动画效果。

我创建了一个名为&#34; Pressed&#34;的VisualState并将其设置为&#34; Hover&#34; (刚刚用pressedstate.png替换了hoverstate.png) 在后面的代码中我做了这个:

btnSampleButton.MouseLeftButtonDown += (s,e) => VisualStateManager.GoToState(btnSampleButton, "Pressed", false);
btnSampleButton.MouseLeftButtonUp += (s,e) => VisualStateManager.GoToState(btnSampleButton, btnSampleButton.IsMouseOver ? "Hover" : "Normal", false);

然而它不起作用。 MouseEnterMouseLeave工作正常,但如果按下/释放鼠标左键,我无法看到按钮的任何更改。

你有任何建议让它发挥作用吗?

编辑: 控制:

<ContentControl x:Name="btnSampleButton" Template="{StaticResource SamplButtonTemplate}" />

的ControlTemplate:

<ControlTemplate x:Key="SamplButtonTemplate">
    <Image x:Name="Image" Source="/AppName;component/Res/Img/normalstate.png">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup Name="CommonStates">
                <VisualState Name="Normal" />
                <VisualState Name="Hover">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames BeginTime="0"
                                                       Storyboard.TargetName="Image" Storyboard.TargetProperty="Source">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <BitmapImage UriSource="/AppName;component/Res/Img/hoverstate.png" />
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState Name="Pressed">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames BeginTime="0" FillBehavior="Stop"
                                                       Storyboard.TargetName="Image" Storyboard.TargetProperty="Source">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <BitmapImage UriSource="/AppName;component/Res/Img/pressedstate.png" />
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Image>
</ControlTemplate>

代码背后:

btnSampleButton.MouseEnter += (s, e) => VisualStateManager.GoToState(btnSampleButton, "Hover", false);
btnSampleButton.MouseLeave += (s, e) => VisualStateManager.GoToState(btnSampleButton, "Normal", false);
btnSampleButton.PreviewMouseLeftButtonDown +=
            (s, e) => VisualStateManager.GoToState(btnSampleButton, "Pressed", false);
btnSampleButton.PreviewMouseLeftButtonUp +=
            (s, e) => VisualStateManager.GoToState(btnSampleButton, btnSampleButton.IsMouseOver ? "Hover" : "Normal", false);

1 个答案:

答案 0 :(得分:1)

MouseLeftButtonDownMouseLeftButtonUp被Button的Click事件吞没,这就是为什么这些事件永远不会为按钮引发而VisualState中没有变化的原因。

相反挂钩相应的预览事件,即 PreviewMouseLeftButtonDown PreviewMouseLeftButtonUp

btnSampleButton.PreviewMouseLeftButtonDown += (s,e) => 
          VisualStateManager.GoToState(btnSampleButton, "Pressed", false);

btnSampleButton.PreviewMouseLeftButtonUp += (s,e) => 
      VisualStateManager.GoToState(btnSampleButton, btnSampleButton.IsMouseOver ?
                                                      "Hover" : "Normal", false);

从第二个StoryBoard中删除 FillBehavior="Stop" ,您的代码运行正常。

<VisualState Name="Pressed">
   <Storyboard>
     <ObjectAnimationUsingKeyFrames BeginTime="0"
                                    FillBehavior="Stop" <-- Remove this
                                    Storyboard.TargetName="Image" 
                                    Storyboard.TargetProperty="Source">