Home > Blockchain >  Is it possible to handle the Storyboard.Completed Event in such a way that a command from the ViewMo
Is it possible to handle the Storyboard.Completed Event in such a way that a command from the ViewMo

Time:12-12

I solved the problem in such a way that there is an EventHandler in the Code-Behind which then calls the corresponding Command of the ViewModel.

<Storyboard x:Key="StartNewGameAnimation" RepeatBehavior="1x"
            Completed="StartAnimationCompleted">
private void StartAnimationCompleted(object sender, EventArgs e)
{
    var gameBoardViewModel = (GameBoardViewModel)this.DataContext;
    gameBoardViewModel.StartGameWhenStartanimationCompletedCommand.Execute(null);
}

This solution works fine, but I want to handle the Event directly in Xaml and also call the Command. It is simply important to me whether this path exists.

CodePudding user response:

You can use the Microsoft.Xaml.Behaviors.Wpf NuGet package that replaces the legacy Interactivity types. There is an InvokeCommandAction type that can invoke a command through an EventTrigger.

However, the direct way inside Storyboard does not work.

<Storyboard x:Key="StartNewGameAnimation" RepeatBehavior="1x">
   <b:Interaction.Triggers>
      <b:EventTrigger EventName="Completed">
         <b:InvokeCommandAction Command="{Binding StartGameWhenStartanimationCompletedCommand}"/>
      </b:EventTrigger>
   </b:Interaction.Triggers>
</Storyboard>

It will throw an exception at runtime, because the Storyboard cannot be frozen with the binding.

'Microsoft.Xaml.Behaviors.Interactivity.EventTrigger' must have IsFrozen set to false to modify

A workaround is to move the interaction block to a parent element, e.g. BeginStoryboard and refer to the Storyboard with an ElementName binding.

<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>

Depending on the context, setting the SourceName instead of SourceObject works, too.

<b:EventTrigger EventName="Completed" SourceName="StartNewGameAnimation">

By the way, you have to add the following XML namespace in your control, to refer to the types:

xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
  • Related