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"