MVVM How to get away from code behind events

After looking at some of the MVVM suites (MVVM Light, SimpleMVVM), the general theme seems to be trying to use as many mixed events as possible, rather than using codebehind.

I'm not sure how to do all the events. For example, when window 7 of the phone is executed, 2 events are bound.

  • OnNavigatedTo / From
  • While loading

Does anyone have any examples on how to do this in MVVM? I am using SimpleMVVM, but I would like to hope that the examples can be similar and the MVVM light tool, or even a regular MVVM tutorial showing this might be helpful.

I only found the ones that show how to do, how to press the button.

Edit

I'm a little confused about when to use code behind events or use blend events for commands.

For example, in the MVVM Light tutorials, they use MVVM for navigation, but why is this better than using the codebehind event?

I'm a little confused too when people say

Codebehind is not evil; his combination of business logic and code is problematic. Let your UI handle UI tasks in your code.

Well in MVVM examples they have "isbusy" in one of the examples, when when a list or something else (forgotten) is loaded, a "loading sign" appears. This was all done in the ViewModel and not in the codebehind event.

So this seems contradictory to me (maybe I'm missing something). What also puzzles me is that if the ViewModel doesn't know anything about the download, how do you know when the download started or ended?

+3


source to share


2 answers


As HighCore comments, use EventToCommand

. It's pretty easy 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 common point in the code: having UI-related functionality in your code isn't the worst thing in the world! It is separate from your ViewModel and it sits in a logical place. However, I find the behavior to be easier to test. For example, using a class that inherits from TargetedTriggerAction

allows you to control the storyboard both through property changes and through 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 behavior with the PropertyChangedTrigger

following:

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

      

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

+2


source


1) Unfortunately I haven't found any good examples, so you are on your own.

2) if you keep your code blank (using commands instead of clicking a button), you are concentrating your code only in the ViewModel. I see two benefits:

a) if you are using the same ViewModel for different views (and have some common commands across multiple versions),



b) if you are using some private variables / methods of your ViewModel that are not available in the view.

3) You can use RaisePropertyChanged to load (reload) data, load data into ViewModel constructor to avoid using OnNavigatedTo or whatever.

0


source







All Articles