【问题标题】:Is it possible to handle the Storyboard.Completed Event in such a way that a command from the ViewModel is called in Xaml是否可以通过在 Xaml 中调用来自 ViewModel 的命令的方式来处理 Storyboard.Completed 事件
【发布时间】: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 独立。

标签: c# wpf events binding command


【解决方案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"

【讨论】:

  • 谢谢,这正是我想要的。
猜你喜欢
  • 2021-09-23
  • 2021-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多