2
votes

I'm writing a WPF desktop application. I'm trying to understand the MVVM flow of data. I'm using Entity Framework as a data access, and I'm using a code-first approach so I have my POCO entity classes that represent each SQL table.

With this configuration, it's my understanding that my model (M in MVVM) is my POCO entity class. My views (V in MVVM) are my WPF windows.

What populates my view models? Do I just make my EF queries inside my views, populating the view models? Do my view models perform their own querying (inside class constructor, perhaps)?

2

2 Answers

4
votes

Typically the view is a WPF window and it's corresponding code behind. The view model is a simple class that is created to handle the data layer requirements for the specific view and to do the processing. It is common to use Commands in the XAML view on the controls and each command is bound to a command instance that is in the view model. The view model can be created by dependency injection or it can be passed into the constructor in the views code behind and it is stored as member/property in the code behind. Make sure to set the views data context to the instance of the view model so to allow binding to the properties and commands in the view model.

this.DataContext = new TheViewModelType();

The Entity Framework Plain Old CLR Objects are data models and the view should not typically know about these. The view model may have properties of the model types that the view can bind to for say Items controls and such. So in the view:

<ItemsControl x:Name="CarItems" ItemsSource="{Binding Vm.CarsCollection}"></ItemsControl>

So, since the view's DataContext is a instance of the view model type, the view controls may bind directly to properties in the view model. The example is the view model having a collection of Cars and the view model may call a service when needed to populate the Cars collection. Obviously the a Car is the model.

    public MyViewModel( )
    {
        Cars = TheCarsDataLayerService.GetCars( );
    }

    private IObservable<Car> _cars;

    public IObservable<Car> Cars
    {
        get { return _cars; }
        set
        {
            if( _cars == value )
                return;
            _cars = value;
            RasisePropertyChanged("Cars");
        }
    }

For the Cars service int the example, This may be a data layer repository or it could be a instance of the Entity Framework DbContext. So the view model can have a field of the DbContext derived type or a service of such and this can be passed into the constructor of the view model class or injected with dependency injection or maybe the service is a static factory or singleton that the view model just calls into to populate the its members with the data that the view is going to display to the user.

MVVM is a pretty basic design pattern that can be implemented in many different ways. Some developers will take the pattern to new heights and strictly obey many rules in which the components of the pattern communicate. Ultimately,using the pattern is much better than not using any pattern at all regardless of how it is implemented, as it will allow the code to scale much better and other developers might much more easily understand the code and expect certain things. Also, the MVVM pattern allows for WPF devs to unit test. When done well enough, the view models can be tested and since there is no code in the views code behind and the view doesn't do anything but display data that it doesn't even know about, testing the view model is good enough.

1
votes

Strictly using your domain models as view models will eventually if not immediately cause you problems. Typically a domain model consists of raw data, it may or may not contain business operations, some may place that in a BusinessLayer manager class for example. But you VM ViewModel is strictly for the view, should exist only in the view project. Cluttering your domain with view related dropdowns etc... is not an appropriate place to put those "View" data sources.

So to put this in code terms, your view model can contain a property that references an instance of the domain model OR you could add every property that the view will expose. But by separating the ViewModel and Model (domain model) you are allowing the view to be able to expose/hide what it needs as well as convert some properties, for example an EntityFramework model may contain a string property but your view may want a strictly numeric representation of it on one screen while another may allow an edit as string property, point is your EF model (domain model) doesn't need to worry about those view issues.

Where do you create the VM?

The job of a controller is to interpret a request and determine the view and view model needed. So it would be in the controller that the VM is created using a EF domain model class (for an edit request as an example) as the source of the VM.