Best way to transfer data to the new ViewModel when it starts

I am working on a WPF database application using the MVVM-Light Framework. I use SimpleIOC to enter my data services, and my ViewModels connect to the view from the XAML file. However, when opening new view models, I usually also need to pass another object to the view model (let's say I pass an integer CarId so that I can capture the actual car from the database).

Now I pass this using Messenger in the view, after InitializeComponent (). Then it falls into the view model. This currently works, however it has a few deviations.

First, a message is not sent until the View model constructor is called. Suppose I had a property of the ThisCar object in the ViewModel, and I had secondary properties, such as a string called Brand, which returns ThisCar.Brand.

public const string ThisPersonPropertyName = "ThisCar"; private Model.Car _thisCar; public Model.Car ThisCar { get { return _thisCar; } set { if (_thisCar== value) { return; } RaisePropertyChanging(ThisCarPropertyName); _thisCar= value; RaisePropertyChanged(ThisCarPropertyName); } } public const string BrandPropertyName = "Brand"; public string Brand { get { return ThisCar.Brand; } set { if (ThisCar.Brand == value) { return; } RaisePropertyChanging(BrandPropertyName); ThisCar.Brand = value; RaisePropertyChanged(BrandPropertyName); } } 

Now that the constructor receives the call, I have to initialize ThisCar in the View Model Constructor. So otherwise, I get a null error on ThisCar.Brand when creating the ViewModel.

 ThisCar = new CarObject(); 

Then, after initializing the empty object, the message will be called, and I will pull the real car from the database based on the identifier of the car.

 ThisCar = webService.GetCar(carId); 

However, when I do this, the Brand property is not updated because nothing calls OnPropertyChanged for the brand.

I have two works, but I like them more. First on manually calls OnPropertyChanged for any properties that need to be updated. Secondly, I remove all the small properties and bind everything directly to the ThisCar property (this means that I have to implement INotifyPropertyChanged in my model).

Please let me know if I'm just picky, or if there is a better way to do this. The way I do this works, but just doesn't sit right with me. Thanks.

+4
c # wpf mvvm mvvm-light
source share
2 answers

So this is what I came up with, please let me know if this is a terrible idea.

I created an interface called IRepository, since I am using Injections Dependency to create View Models. Here is the implementation:

 public interface IRepository { void GetCarId(Action<int> callback); void SetCarId(int value); } 

Next, I create a class that inherits from IRepository

 public class Repository : IRepository { private int CarId; public void GetCarId(Action<int> callback) { callback(CarId); } public void setDictionary(int carId) { CarId = carId; } } 

Now, to pass the value to the repository, I put it in the parent view model

  r.SetCarId(13); 

And to get in the new View, I put this in the View Model Constructor:

  public View2ViewModel(IChildView i, IRepository r) { int CarId; r.GetCarId((id) => CarId = id); thisCar = GetCarFromDatabase(CarId); } 

It seems to me that I solved the problem without violating the MVVM pattern, and since the IOC container I use creates all the interface members as static, I will have this data in all other views.

The main problem I am facing is that it looks like a global variable, but this is the best I could come up with. Please let me know if this is a really bad idea. Thanks.

+2
source share

I will vote for the models being able to notify of the changes by introducing INotifyPropertyChanged in the models. Two reasons:

  • There may be several places / views that you may need to use the same model, and you would not want to take care of each ViewModel model, since changing a property should raise another property. Honestly, it's dirty and buggy.

  • Sometimes at the VM level we may need to listen to changes in models, so in this case a self-declaring model can also be used.

thanks

+1
source share

All Articles