是否可以通过在 Xaml 中调用来自 ViewModel 的命令的方式来处理 Storyboard.Completed 事件
Is it possible to handle the Storyboard.Completed Event in such a way that a command from the ViewModel is called in Xaml
我解决问题的方式是代码隐藏中有一个 EventHandler
,然后调用 ViewModel
的相应 Command
。
<Storyboard x:Key="StartNewGameAnimation" RepeatBehavior="1x"
Completed="StartAnimationCompleted">
private void StartAnimationCompleted(object sender, EventArgs e)
{
var gameBoardViewModel = (GameBoardViewModel)this.DataContext;
gameBoardViewModel.StartGameWhenStartanimationCompletedCommand.Execute(null);
}
此解决方案工作正常,但我想直接在 Xaml 中处理 Event
并调用 Command
。这条路是否存在对我来说很重要。
您可以使用 Microsoft.Xaml.Behaviors.Wpf NuGet package that replaces the legacy Interactivity 类型。有一种 InvokeCommandAction
类型可以通过 EventTrigger
.
调用命令
但是里面的直接方式Storyboard
不行
<Storyboard x:Key="StartNewGameAnimation" RepeatBehavior="1x">
<b:Interaction.Triggers>
<b:EventTrigger EventName="Completed">
<b:InvokeCommandAction Command="{Binding StartGameWhenStartanimationCompletedCommand}"/>
</b:EventTrigger>
</b:Interaction.Triggers>
</Storyboard>
它会在运行时抛出异常,因为Storyboard
不能用绑定冻结。
'Microsoft.Xaml.Behaviors.Interactivity.EventTrigger' must have IsFrozen set to false to modify
解决方法是将交互块移动到父元素,例如BeginStoryboard
并使用 ElementName
绑定引用 Storyboard
。
<BeginStoryboard>
<b:Interaction.Triggers>
<b:EventTrigger EventName="Completed" SourceObject="{Binding ElementName=StartNewGameAnimation}">
<b:InvokeCommandAction Command="{Binding StartGameWhenStartanimationCompletedCommand}"/>
</b:EventTrigger>
</b:Interaction.Triggers>
<!-- ...other code. -->
</Storyboard>
</BeginStoryboard>
根据上下文,设置 SourceName
而不是 SourceObject
也可以。
<b:EventTrigger EventName="Completed" SourceName="StartNewGameAnimation">
顺便说一下,您必须在控件中添加以下 XML 命名空间,以引用类型:
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
我解决问题的方式是代码隐藏中有一个 EventHandler
,然后调用 ViewModel
的相应 Command
。
<Storyboard x:Key="StartNewGameAnimation" RepeatBehavior="1x"
Completed="StartAnimationCompleted">
private void StartAnimationCompleted(object sender, EventArgs e)
{
var gameBoardViewModel = (GameBoardViewModel)this.DataContext;
gameBoardViewModel.StartGameWhenStartanimationCompletedCommand.Execute(null);
}
此解决方案工作正常,但我想直接在 Xaml 中处理 Event
并调用 Command
。这条路是否存在对我来说很重要。
您可以使用 Microsoft.Xaml.Behaviors.Wpf NuGet package that replaces the legacy Interactivity 类型。有一种 InvokeCommandAction
类型可以通过 EventTrigger
.
但是里面的直接方式Storyboard
不行
<Storyboard x:Key="StartNewGameAnimation" RepeatBehavior="1x">
<b:Interaction.Triggers>
<b:EventTrigger EventName="Completed">
<b:InvokeCommandAction Command="{Binding StartGameWhenStartanimationCompletedCommand}"/>
</b:EventTrigger>
</b:Interaction.Triggers>
</Storyboard>
它会在运行时抛出异常,因为Storyboard
不能用绑定冻结。
'Microsoft.Xaml.Behaviors.Interactivity.EventTrigger' must have IsFrozen set to false to modify
解决方法是将交互块移动到父元素,例如BeginStoryboard
并使用 ElementName
绑定引用 Storyboard
。
<BeginStoryboard>
<b:Interaction.Triggers>
<b:EventTrigger EventName="Completed" SourceObject="{Binding ElementName=StartNewGameAnimation}">
<b:InvokeCommandAction Command="{Binding StartGameWhenStartanimationCompletedCommand}"/>
</b:EventTrigger>
</b:Interaction.Triggers>
<!-- ...other code. -->
</Storyboard>
</BeginStoryboard>
根据上下文,设置 SourceName
而不是 SourceObject
也可以。
<b:EventTrigger EventName="Completed" SourceName="StartNewGameAnimation">
顺便说一下,您必须在控件中添加以下 XML 命名空间,以引用类型:
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"