Prince Fowzan
Prince Fowzan

Reputation: 11

How to Start a storyboard animation from just ViewModel in WPF?

I've been trying to achieve a transition between a menu changing to another. I am using WPF .Net 8 and Caliburn Micro for MVVM.

so I have created the storyboard animation in the MainView.xaml with the name MenuChangeStart. In my MainViewModel.cs I have a method, called when the user clicks the home button. now I want to start this animation before changing the menu.

 public void ActivateHomeView()
 {
     
     
     CurrentMenuIcon = @"\Resources\home.png";
    
     //the MenuChangeStart animation goes here
     ActivateItemAsync(new HomeViewModel());

    

 }

I tried to do this in two ways but I have problems in both.

Method 01: Calling a method from View's CS

so initially I tried to use this block of code in my MainViewModel.cs but I found that FindResource does not exist in it.

//MainViewModel.cs
public void MenuChangeOpen()
 {
     Storyboard sb = this.FindResource("MenuChangeStart") as Storyboard;
     sb.Begin();
 }

then i can call this MenuChangeOpen() from the ActivateHomeView()

Method 2: Calling method in view from ViewModel

I Moved this MenuChangeOpen() method to the MainView.xaml.cs and then call it from the ViewModel but i could not find a way to correctly call it. I used the below-mentioned code but it throws an error saying _view is null.

//MainViewModel.cs
 private MainView _view; 
 public MainViewModel(MainView view) => _view = view;

//InHome menu change
public void ActivateHomeView()
{
    
    //the _view seems to be null
    CurrentMenuIcon = @"\Resources\home.png";
    if(_view != null)
    {
        _view.MenuChangeOpen();
    }
    
    ActivateItemAsync(new HomeViewModel());

   

}

Upvotes: 1

Views: 167

Answers (1)

farzad
farzad

Reputation: 7

use the EventTrigger in XAML along with an EventTriggerBehavior from the Microsoft.Xaml.Behaviors.Wpf NuGet package.

    private RelayCommand _startAnimationCommand;

    public RelayCommand StartAnimationCommand
    {
        get
        {
            return _startAnimationCommand ?? (_startAnimationCommand = new RelayCommand(param => StartAnimation()));
        }
    }

in xaml: add

<Window.Resources>
        <Storyboard x:Key="YourAnimationStoryboard">
            <!-- Define your animation here -->
        </Storyboard>
    </Window.Resources>
    <Grid>
        <Button Content="Start Animation">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <i:InvokeCommandAction Command="{Binding StartAnimationCommand}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
        </Grid>


Upvotes: 0

Related Questions