Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVVM when to create a viewmodel for a control?

Tags:

c#

mvvm

xaml

Or should I only create viewmodels for the domain data being represented? While reading on MVVM, I came across this:

"The ViewModel is responsible for these tasks. The term means "Model of a View", and can be thought of as abstraction of the view, but it also provides a specialization of the Model that the View can use for data-binding. In this latter role the ViewModel contains data-transformers that convert Model types into View types, and it contains Commands the View can use to interact with the Model. "

http://blogs.msdn.com/b/johngossman/archive/2005/10/08/478683.aspx

If the viewmodel is a model of the view, then doesn't it make sense to put properties of the view in the viewmodel rather than on the code behind of the view itself?

I guess in making a custom control I just have a hard time deciding when I should just add a property to the control's code behind and when it is worthwhile to make a viewmodel for the control to represent it. Honestly I kind of feel that moving all of the control's view related properties to the viewmodel would clean up the code behind of the control leaving only the control logic.

However, if I were to change things like this, then at times when an item needs properties from the control itself I can no longer use {Binding ElementName = control, Path=property} and have to instead get the data context of the parent (because the current datacontext would be on the individual subitem of the observable collection.

Basically I was considering whether I should move properties from Class GraphViewer into a GraphViewerViewModel and then just bind to it.

Code is worth a million words so: public class GraphViewerViewModel :DependencyObject { private const int DEFAULT_PEN_WIDTH = 2; private const int DEFAULT_GRAPH_HEIGHT = 25;

    public SignalDataViewModel _SignalDataViewModel
    {
      get;
      set;
    }
    public PreferencesViewModel _PreferencesViewModel
    {
      get;
      set;
    }
}

Meanwhile

public class SignalDataViewModel : INotifyPropertyChanged
  {
    public event PropertyChangedEventHandler PropertyChanged;

    ObservableCollection<SignalViewModel> _signals;
    public ObservableCollection<SignalViewModel> Signals
    {
      get
      {
        return _signals;
      }
      private set
      {
        _signals = value;
      }
    }

    ObservableCollection<SignalViewModel> _AddedSignals;
    public ObservableCollection<SignalViewModel> AddedSignals
    {
      get
      {
        return _AddedSignals;
      }
      private set
      {
        _AddedSignals = value;
      }
    }

it is a pain to type:

PenWidth="{Binding RelativeSource = {RelativeSource AncestorType={x:Type DaedalusGraphViewer:GraphViewer}}, 
                                  Path = _GraphViewerViewModel._SignalDataViewModel._AxisDivisionUnit.GraphPenWidth, Mode=OneWay}"

and I'm wondering if it is worthwhile to make the change or whether I'm misunderstanding what a view model should be used for in mvvm.

like image 716
James Joshua Street Avatar asked Mar 23 '23 07:03

James Joshua Street


1 Answers

I guess in making a custom control I just have a hard time deciding when I should just add a property to the control's code behind and when it is worthwhile to make a viewmodel for the control to represent it. Honestly I kind of feel that moving all of the control's view related properties to the viewmodel would clean up the code behind of the control leaving only the control logic.

In general, a custom control is 100% View layer code. As such, it really falls outside of MVVM entirely.

The main goal when making a custom control to be used within an application being designed with MVVM is to make sure that you design and build the custom control in a way that it is fully compatible with data binding. This will allow it to be used within your View layer of your application exactly like other controls.

As such, this pretty much guarantees that you'll have code behind, since implementing Dependency Properties really requires code behind. You also don't want to set the DataContext of a custom control within the control (since you want to inherit the data context of the user control or window using the control).

Basically I was considering whether I should move properties from Class GraphViewer into a GraphViewerViewModel and then just bind to it.

If the types are specific to your domain, then this is really typically more of a UserControl being used by your application. In that case, creating a ViewModel and just binding is likely good.

If this is, on the other hand, a true custom control that's made to be completely general purpose (ie: usable by anybody in any application), then keeping it as a "pure view" custom control typically means that you 1) won't take a dependency on any ViewModels or domain specific objects, and 2) not set the data context (which means no view model).

like image 113
Reed Copsey Avatar answered Apr 01 '23 19:04

Reed Copsey