Search code examples
wpfmvvmrelaycommandattachedbehaviors

What is the best way to handel click-events in MVVM?


What is the best way to handel click-events in MVVM? Are there a best way?

I have found two solutions:

with a relaycommand:

RelayCommand buttonAddCategory_Click;
public ICommand ButtonAddCategory_Click
{
    get
    {
        return buttonAddCategory_Click ?? (buttonAddCategory_Click = new RelayCommand(param => this.AddCategory(),
                                                                                      param => true));
    }
}

pro: ?; contra: need workaround with events if i would change ui elements like focus

with attached behaviour:

public static bool GetIsResetMouseLeftButtonDown(TreeView treeView)
{
    return (bool)treeView.GetValue(IsResetMouseLeftButtonDownProperty);
}
public static void SetIsResetMouseLeftButtonDown(TreeView treeViewItem, bool value)
{
    treeViewItem.SetValue(IsResetMouseLeftButtonDownProperty, value);
}
public static readonly DependencyProperty IsResetMouseLeftButtonDownProperty =
    DependencyProperty.RegisterAttached("PreviewMouseLeftButtonDown", typeof(bool), typeof(TreeViewBehavior),
    new UIPropertyMetadata(false, OnIsMouseLeftButtonDownChanged));

pro: you have RoutedEventArgs for changes on the ui; contra: access to other controls?

Right now i use both solutions. The RellayCommand in Buttons (with events for ui updates) and the attached behaviour for a treeview to deselect the treeviewitem if a user clicks.


Solution

  • To me there is no simple answer to this question. That's the way I see it:

    • if you have a defined state-change on the VM, expose a RelayCommand which then can be bound to something the triggers it. In 99,9% percent of the cases this is a button/menu-entry. Something where it can be easily used. The cases that are left -> well some workaround might be needed, like calling a method from the view. So a RelayCommand should imho be used if you are really targeting the VM.

    • Focus-changes on the other hand are view-related functionality. Imho this has nothing todo with the WM. That means for me it should be implemented in the view. So to me I'd even go for a straight-forward eventhandler that does the job.

    hth, Martin