是否可以通过在 Xaml 中调用来自 ViewModel 的命令的方式来处理 Storyboard.Completed 事件

Posted

技术标签:

【中文标题】是否可以通过在 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 【发布时间】:2022-01-10 05:46:54 【问题描述】:

我以这样一种方式解决了这个问题,即代码隐藏中有一个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。这条路是否存在对我来说很重要。

【问题讨论】:

也许您可以使用EventToCommand 实现。 你所做的没有错。您可以通过向控件添加 ICommand 类型的 StartGameCommand 属性来改进您的代码,以便将其与实际视图模型分离(考虑让它实现 ICommandSource)。然后在代码隐藏中调用此命令 - 此时视图模型/DataContext 是未知的。然后在 XAML 中将视图模型命令绑定到控件的 StartGameCommand 属性。这样控件就不必知道视图模型(类型转换被删除)。它现在可以使用任何类型进行操作,即 DataContext 独立。 【参考方案1】:

您可以使用 Microsoft.Xaml.Behaviors.Wpf NuGet 包来替换旧的 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”必须将 IsFrozen 设置为 false 才能修改

解决方法是将交互块移动到父元素,例如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"

【讨论】:

谢谢,这正是我想要的。

以上是关于是否可以通过在 Xaml 中调用来自 ViewModel 的命令的方式来处理 Storyboard.Completed 事件的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用带有附加事件的 Microsoft.Xaml.Behaviors.EventTrigger 调用命令?

XAML 在 ListView 中具有来自 AppResources 的 Labeltext

在 MainPage.xaml.cs 中使用 Android 特定代码

Xamarin Forms 使用 XAML 显示来自嵌入式资源的图像

是否可以在非异步方法中调用等待方法? [复制]

是否可以在 XAML 中绑定 Canvas 的 Children 属性?