Question

After looking at some of the MVVM toolkits(MVVM Light, SimpleMVVM) out there the common theme seems to try to use as many blendable events as possible and not use codebehind.

I am not sure how to do all the events. For instance 2 events come to bind when doing windows phone 7.

  1. OnNavigatedTo/From
  2. On Load

Does anyone have examples on how to do this in MVVM? I am using SimpleMVVM but I would hope that the examples might be similar and maybe MVVM light toolkit or even just general MVVM tutorial showing this might help.

I only found ones that show how to do like the button click.

Edit

I am sort of confused on when to use code behind events or use blend events to commands.

For instance in the the MVVM Light tutorials they use MVVM for navigation but why is that better than using a codebehind event?

I am also kinda confused now when people say

Codebehind isn't evil; its the mix of business logic and codebehind that is problematic. Let your UI handle UI tasks in your codebehind.

Well in the MVVM light examples they have "isbusy" in one of the examples where when the list or whatever it was(forgot) is loading a "loading sign comes up". This was all done in ViewModel and not a codebehind event.

So this seems kinda conflicting to me(maybe I am missing something). What also puzzles me is that if the ViewModel does not know anything about loading how do you know when the loading has started or finished?

Was it helpful?

Solution

As HighCore commented, use EventToCommand. It's pretty simple to use, although you'll need the Blend SDK first.

...
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL4"
xmlns:im="clr-namespace:Microsoft.Expression.Interactivity.Media;assembly=Microsoft.Expression.Interactions"
xmlns:ic="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
...
<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
            <cmd:EventToCommand Command="{Binding GetTweetsCommand}" CommandParameter="Twitter" />
        </i:EventTrigger>
</i:Interaction.Triggers>

Also, just a general point on the code-behind: having UI-related functionality in the code-behind isn't the worst thing in the world! It's separate from your ViewModel and it's in a logical place. However, I find behaviours easier to test. For example, using a class inheriting from TargetedTriggerAction allows a storyboard to be controlled by both property changes and controls:

public class ImageAnimationTrigger : TargetedTriggerAction<Storyboard>
{
    protected override void Invoke(object parameter)
    {
        if (Target == null)
            return;

        if (parameter is DependencyPropertyChangedEventArgs)
        {
            DependencyPropertyChangedEventArgs args = (DependencyPropertyChangedEventArgs)parameter;

            if ((bool)args.NewValue)
                Target.Begin();
            else
                Target.Stop();
        }
        else if (parameter is RoutedEventArgs)
        {
            RoutedEventArgs args = (RoutedEventArgs)parameter;

            if (!(args.OriginalSource as Button).IsEnabled)
                Target.Begin();
            else
                Target.Stop();
        }
    }
}

I use this behaviour with a PropertyChangedTrigger as follows:

<i:Interaction.Triggers>
    <ic:PropertyChangedTrigger Binding="{Binding Loading}">
        <behav:ImageAnimationTrigger TargetName="animStoryboard" />
    </ic:PropertyChangedTrigger>
</i:Interaction.Triggers>

As Laurent Bugnion says, use the code-behind if you need to!

OTHER TIPS

1) Unfortunately I didn't find good examples so you are on your own.

2) if you keep your code-behind blank (by using commands instead of button click) you concentrate your code in ViewModel only. I can see two points of benefits:

a) in case you use one ViewModel for different Views (and have some common commands in several vies),

b) in case you use some private variables/methods of your ViewModel which are not available in the View.

3) You may use RaisePropertyChanged to load (reload) data, load data in ViewModel constructor to avoid using OnNavigatedTo or something else.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top