以编程方式点击按钮并显示按下的动画

3

WPF/.NET4 我有一个Button1,它有MouseOver和Pressed动画。我想用键盘上的一个键来点击该按钮。我尝试过自动化,例如:

ButtonAutomationPeer peer= new ButtonAutomationPeer(Button1);
IInvokeProvider invokeProv = peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProv.Invoke();

这会触发Button1的点击事件处理程序。我也尝试过以下方法:
Button1.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));

这两个功能很好,但是没有一个显示按钮按下状态。它们会触发事件处理程序并运行按钮内部代码,但是当点击按钮时不显示按钮的反应。未显示按下状态。我该怎么办?谢谢。

1个回答

3
您可以在引发事件之前调用VisualStateManager.GoToState方法。
VisualStateManager.GoToState(Button1, "Pressed", true);
Button1.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));

这样做的问题在于动画是异步运行的,所以任何在事件触发后的代码行都会立即执行。解决方法之一是获取在调用GoToState时调用的Storyboard
为此,您可以使用GetVisualStateGroups
var vsGroups = VisualStateManager.GetVisualStateGroups(VisualTreeHelper.GetChild(Button1, 0) as FrameworkElement);
VisualStateGroup vsg = vsGroups[0] as VisualStateGroup;

if (vsg!= null)
{
    //1 may need to change based on the number of states you have
    //in this example, 1 represents the "Pressed" state
    var vState = vsg.States[1] as VisualState;
    vState.Storyboard.Completed += (s,e)
            {
                VisualStateManager.GoToState(Button1, "Normal", true);

                //Now that the animation is complete, raise the Button1 event
                Button1.RaiseEvent(new RoutedEventArgs(ButtonBase.ClickEvent));
            };
}

//Animate the "Pressed" visual state
VisualStateManager.GoToState(Button1, "Pressed", true);

您可能希望存储Storyboard(在vState.Storyboard中),以便您不必每次执行搜索,但这应该让您知道动画何时完成,然后您可以继续进行其余的代码(在此示例中,我们触发Button1事件)。


谢谢,非常好用。您能告诉我如何将其恢复到正常状态吗?实际上,我需要按下按钮,然后在大约10毫秒后恢复到正常状态。我尝试了:VisualStateManager.GoToState(Button1,“Normal”,true);但是这会立即更改,所以按钮始终显示正常状态,我甚至在“Normal”状态之前添加了线程休眠,但它并没有显示。 - Hossein Amini
我已更新我的答案。 它展示了如何获取“ Pressed”动画的“ Storyboard”,您可以使用它来检测动画何时完成,方法是将事件处理程序附加到“ Complete”事件。 在此事件处理程序中,您可以触发“ Button1”事件。 - keyboardP
非常感谢,但是Completed事件没有触发,就像第一个解决方案一样,它按下按钮但从未返回到正常状态。 - Hossein Amini
你的 vState 的值是多少? - keyboardP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接