Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are WPF related properties inside a ViewModel a violation of MVVM best practices?

Here is an example case to elaborate:

I am dynamically creating a simple Bar Graph using an ItemsControl in my View and binding the items to a collection of BarViewModels (each containing percentage a value) in my BarGraphViewModel. Each bar should have a different color. The colors should be chosen from a collection e.g. {Color1, Color2, ..}

The collection itself is constant but the number of bars will depend on the circumstances.

A simple solution would be to create a simple BarViewModel like so:

public class BarViewModel
{
    public int Percentage { get; set; }

    public SolidColorBrush Stroke { get; private set; }

    public BarGraphViewModel(SolidColorBrush stroke)
    {
        Stroke = stroke;
    }
}

(I left out property changed and validation implementation for brevity)

Now I could just create a BarViewModels from my BarGraphViewModel for each percentage and pass in the appropriate ColorBrush created from my Color collection.

Then in Xaml I would create a simple ItemsTemplate that will bind to these properties.

Only now, since it contains a property of type SolidColorBrush, my ViewModel depends on the Presentation framework and should I want to use it in another environment it will have to be changed.

Does this therefore break MVVM best practices, or is it acceptable (you gotta draw the line somewhere or things get too complicated)

I just wanted to see what other people think about this and if there are other solutions that keep the ViewModel totally ignorant of the Presentation Layer without getting too complicated. I could imagine that ValueConverters could help?

like image 612
Thorsten Lorenz Avatar asked Dec 13 '09 14:12

Thorsten Lorenz


People also ask

Should a ViewModel have a constructor?

At present, this means that every ViewModel must have a public constructor which has either no parameters or which has only string parameters. So the reason your ViewModel isn't loading is because the MvxDefaultViewModelLocator can't find a suitable constructor for your ViewModel.

Should I use MVVM for WPF?

WPF assumes MVVM for most things. e.g. using a the wpf tree control without MVVM will have you tearing your hair out within a day.. MVVM just makes things simpler and testable. This could answer some of the questions: wintellect.com/CS/blogs/jlikness/archive/2010/04/14/….

What should a ViewModel contain?

ViewModel objects can contain LifecycleObservers , such as LiveData objects. However ViewModel objects must never observe changes to lifecycle-aware observables, such as LiveData objects.


1 Answers

In the original Presentation Model pattern described by Martin Fowler, the view "asks" the view-model how to display itself. This seems to favor putting color and size properties on your view-model rather than triggers in your view. The application of this pattern within WPF, however, is somewhat different. In WPF, you typically define how the view looks by using Styles and DataTemplates in the view. Returning specific colors directly from the view-model would be contrary to this approach. So the short answer is: no, don't put color properties on your view-model.

Also within the original Presentation Model pattern, the view-model is an abstraction of the view. So instead of it returning the exact color, it would be preferable to return a "key" that the view can then use to look up the actual color. For example, instead of PersonViewModel.FaceColor returning Red, you'd have PersonViewModel.Mood returning Angry. The view could then use a Style or DataTemplate trigger that translates this to the actual Red color.

So that's my answer and I'm sticking by it, but it's also interesting to consider arguments in the other direction. For one, putting color properties on your view-model is still unit-testable, which seems has become the primary critera for what's okay in the view-model.

Remaining "agnostic" to the view technology isn't a huge factor in either direction. The goal to maintain binary compatibility of view-models with other view technologies is realistic only within the XAML family. Moving all your view-models to their own project which lacks a direct dependency on WPF is a nice idea. But you would have to exclude anything that uses ICommand, or make an exception for a WindowsBase.dll reference. Practically speaking, though, it won't buy you much. We're pretty much glued to Micrsoft technologies! If you decide to port to another GUI framework, then my guess is you're looking at source code conversion. I'm waiting to see if Microsoft goes under before I try it ;) Porting could include changing your color types, if you decided to put them in your view-model. Although not a reason against color properties on your view-model, it's not necessary a reason for it either.

like image 98
HappyNomad Avatar answered Nov 15 '22 21:11

HappyNomad