MVVM Madness: Commands

后端 未结 7 1092
星月不相逢
星月不相逢 2021-01-30 01:38

I like MVVM. I don\'t love it, but like it. Most of it makes sense. But, I keep reading articles that encourage you to write a lot of code so that you can write XAML and don\'t

相关标签:
7条回答
  • 2021-01-30 01:54

    I think the fault lies in the purity requirement. Design patterns, MVVM included, are a tool in the toolbox, not an end unto themselves. If it makes more sense to break with the purity of the model for a well-considered case (and it clearly looks like you've considered this case), then break with the model.

    If that works for you, and you don't believe it's an undue maintenance burden, then I'd say that nothing is wrong with what you've done. I think that you've clearly met the burden of proof for showing that this is a reasonable solution to your problem in spite of what a pure MVVM implementation might be.

    (I consider this argument similar to the arguments for multiparadigm languages. While a Pure OO approach can be applied, sometimes doing things in a more functional way is more appropriate. While a Pure Functional approach can be applied, sometimes the trade offs show that OO techniques are more than worth the while.)

    0 讨论(0)
  • 2021-01-30 01:55

    Commanding is for chumps. Real men wire up their entire ui to events in codebehind.

    0 讨论(0)
  • 2021-01-30 01:56

    I believe that the goal of having "No code in the code-behind" is exactly that, a goal to reach for - not something that you should take as an absolute dogma. There are appropriate places for code in the View - and this isn't necessarily a bad example of where or how code may be simpler than an alternative approach.

    The advantage of the other approaches you list, including attached properties or attached events, is that they are reusable. When you hook up an event directly, then do what you did, it's very easy to end up duplicating that code throughout your application. By creating a single attached property or event to handle that wiring, you add some extra code in the plumbing - but it's code that is reusable for any ListView where you want double-click handling.

    That being said, I tend to prefer using the more "purist" approach. Keeping all of the event handling out of the View may not effect the testing scenario (which you specifically address), but it does effect the overall designability and maintainability. By introducing code into your code behind, you're restricting your View to always using a ListView with the event handler wired - which does tie your View into code, and restrict the flexibility to redesign by a designer.

    0 讨论(0)
  • 2021-01-30 02:06

    Although I prefer not to write code-behind when using the MVVM pattern, I think it's OK to do it as long as that code is purely related to the UI.

    But this is not the case here : you're calling a view-model command from the code-behind, so it's not purely UI-related, and the relation between the view and the view-model command is not directly apparent in XAML.

    I think you could easily do it in XAML, using attached command behavior. That way you can "bind" the MouseDoubleClick event to a command of your view-model :

    <ListView ItemSource="{Binding Items}">
       <local:CommandBehaviorCollection.Behaviors>
          <local:BehaviorBinding Event="MouseDoubleClick" Action="{Binding DoSomething}" />
       </local:CommandBehaviorCollection.Behaviors>
    
        ...
    </ListView>
    

    You can also easily access the selected item of the ListView without referring to it directly, using the ICollectionView interface :

    private ICommand _doSomething;
    
    public ICommand DoSomething
    {
        get
        {
            if (_doSomething == null)
            {
                _doSomething = new DelegateCommand(
                    () =>
                    {
                        ICollectionView view = CollectionViewSource.GetDefaultView(Items);
                        object selected = view.CurrentItem;
                        DoSomethingWithItem(selected);
                    });
            }
            return _doSomething;
        }
    }
    
    0 讨论(0)
  • 2021-01-30 02:07

    I agree with you that many MVVM-Command solutions are too complicated. Personally, I use a mixed approach and define my Commands in the View rather than in the ViewModel, using methods and properties from the ViewModel.

    XAML:

    <Window.Resources>
        <RoutedCommand x:Key="LookupAddressCommand" />
    </Window.Resources>
    <Window.CommandBindings>
        <CommandBinding Command="{StaticResource LookupAddressCommand}" x:Name="cmdLookupAddress" />
    </Window.CommandBindings>
    

    Code (View):

    Private Sub cmdLookupAddress_CanExecute(ByVal sender As System.Object, ByVal e As System.Windows.Input.CanExecuteRoutedEventArgs) Handles cmdLookupAddress.CanExecute
        e.CanExecute = myViewModel.SomeProperty OrElse (myViewModel.SomeOtherProperty = 2)
    End Sub
    
    Private Sub cmdLookupAddress_Executed(ByVal sender As System.Object, ByVal e As System.Windows.Input.ExecutedRoutedEventArgs) Handles cmdLookupAddress.Executed
        myViewModel.LookupAddress()
    End Sub
    

    It's not pure MVVM, but it simple, it works, it does not need special MVVM-command-classes and it makes your code much easier to read for non-MVVM-experts (= my co-workers).

    0 讨论(0)
  • 2021-01-30 02:10

    Decoupling is one of the major feature of MVVM. If suppose you want to change say view or binded model to it. How much easy it is for your application?

    Take an example where View1 and View2 both share the same ViewModel. Now will you implement the code behind method for both.

    Also, suppose if you need to change the viewmodel for a view on later stage your command will get fail as view model is changed and statement

    MyViewModel vm = this.DataContext as MyViewModel;
    

    will return null and hence code crash. So there comes an extra burden to change the code behind also. These kind of scenarios will arise if you do it in this way.

    Of course there are many ways to achieve the same thing in programming but which one is best will lead to best approach.

    0 讨论(0)
提交回复
热议问题