WPF – Passing Model into ViewModel via Constructor in MVVM

modelmvvmviewwpf

public class LDLTrackViewModel : RailwayViewModel {

    private LDLTrack _ldlTrack;



    public LDLTrack LDLTrack {
        get => _ldlTrack;
        set { _ldlTrack = value;
            OnPropertyChanged("LDLTrack");
        }
    }

    public LDLTrackViewModel(LDLTrack ldlTrack) {
        LDLTrack = ldlTrack;  
        LineCoords = new ObservableCollection<LineCoordinates>(ldlTrack.LineCoordList);

        ZIndex = -50;

    }

}

My system is set up that I've filled my models with data through reading a big file. I then pass these models to various view models via their constructor (I have the same amount of view models as I do models):

LDLTracks = new ObservableCollection<LDLTrackViewModel>(TrainSimAllData.AllLDLTracks.Select(ldl => new LDLTrackViewModel(ldl)));

Where LDLTracks is a collection of LDLTrackViewModels. I then bind to this list of view models in my view. I'm wondering if this is the normal way to go about things or whether there's a better approach?

Best Answer

Personally I would not have an issue with the view model constructor taking an LDLTrack and using it to populate itself. That's a fairly tidy, well-encapsulated way of doing things.

What I wouldn't be so keen on is then exposing that model to consumers via a property - instead, I'd populate fields explicitly defined for the properties that the view model represents:

public class LDLTrackViewModel : RailwayViewModel {

    private readonly string _theFoo;
    private readonly int _theBar;

    public string TheFoo => _theFoo;
    public int TheBar => _theBar;

    public LDLTrackViewModel(LDLTrack ldlTrack) {
        _theFoo = ldlTrack.Foo;
        _theBar = ldlTrack.Bar;
    }
}

This will help to reduce coupling - the view model's job is to communicate certain information and the constructor allows the LDLTrack model to be one source of that information, without further binding other consumers to that type.