Pragmatic use of code-behind in MVVM pattern Pragmatic use of code-behind in MVVM pattern wpf wpf

Pragmatic use of code-behind in MVVM pattern


Specifically for this problem

The simplest solution to this specific case is adding an attached property that does it or a behavior. Behaviors can be a silver bullet for most of these rich-gui-not-supported cases in mvvm.

As for the general case

ViewModel should never ever under any circumstance know about the view, and not even about an IView. in MVVM its "always look up", which means a View can look @ the VM, and the VM can look at the Model. never the other way around. This creates much better maintainability, since this way the ViewModel doesn't do two things (incharge of logic AND the gui), but only one thing. This is where MVVM is superior to any prior MV* pattern.

I would also try to refrain from having the View rely on the ViewModel in a coupled way. this creates ugly code, and a breakable dependency between the two classes, but sometimes this is more pragmatic as you said.A prettier way is to send a Loose Message (e.g. Messenger in MVVMLight, or EventAggregator in Prism) from the ViewModel to the View, and thus there is no strong dependency between the two. Some think this is better although IMO this is still a dependency.

Writing code in the View is OK in some situations, and this could be one of those situation. You could achieve a perfect solution using attached-behaviors, but the priniciple is important, like you asked.

MVVM is problematic when you need GUI that is very rich or the UI doens't have the right Properties to bind to.In those situations you would resort to one of three things:

  1. Attached Behaviors.
  2. Deriving from existing controls and adding the properties you'd like.
  3. Actually writing code in the View.

All of those ways are legitimate, but I've ordered them according to what you should resort to first.

To Summarize

The most important thing you have to keep in MVVM is not to keep the codebehind free, but to keep all logic & data to the ViewModel, where as the View must only contain View-related code. The reason architects tell you not to write code behind at all is only because it's a slippery slope. You start writing something small, and you end up doing logical stuff or maintaining application state in the View, which is the big no-no.

Happy MVVMing :)


Developing WPF applications I found both ways useful. If you need just one call from ViewModel to View, the second option, with event handler, looks simpler and good enough. But if you are requiring more complex interface between these layers, then it makes sense to introduce interface.

And my personal preference is to revert your option one and have a IViewAware interface implemented by my ViewModel and inject this ViewModel into View. Looks like an option three.

public interface IViewAware{    void ViewActivated();    void ViewDeactivated();    event Action CloseView;}public class TaskViewModel : ViewModelBase, IViewAware{    private void FireCloseRequest()    {        var handler = CloseView;        if (handler != null)            handler();    }    #region Implementation of IViewAware            public void ViewActivated()    {        // Do something     }    public void ViewDeactivated()    {        // Do something     }    public event Action CloseView;        #endregion}

And this a simplified code for your View:

    public View(IViewAware viewModel) : this()    {        _viewModel = viewModel;        DataContext = viewModel;        Loaded += ViewLoaded;    }    void ViewLoaded(object sender, RoutedEventArgs e)    {        Activated += (o, v) => _viewModel.ViewActivated();        Deactivated += (o, v) => _viewModel.ViewDeactivated();        _viewModel.CloseView += Close;    }

In real application I usually use an external logic to connect V and VM, for example Attached Behaviors.


I'd try to keep away from having the ViewModel a reference to the View.

A way of doing that in this case:

Derive from TextBox and add a dependency property that wraps the CaretIndex by subscribing to the OnSelectionChanged event that lets you know the caret has moved.

This way the ViewModel is able to know where the caret is by binding to it.