启动数据时将数据传递给新ViewModel的最佳方法

Dar*_*ens 5 c# wpf mvvm mvvm-light

我正在使用MVVM-Light Framework开发WPF数据库应用程序。我正在使用SimpleIOC注入我的数据服务,并且我的ViewModels已从XAML文件连接到视图。但是,在打开新的视图模型时,我通常还需要将另一个对象传递给视图模型(可以说我传递的是CarId的整数,以便可以从数据库中获取实际的Car)。

现在,在InitializeComponent()之后,我通过在View上使用Messenger来传递它。然后,这被视图模型捕获。这目前确实有效,但是有一些挫折。

首先,直到调用视图模型的构造函数之后,才会发送消息。可以说我在ViewModel中有一个ThisCar对象属性,而我有一些辅助属性,例如一个名为Brand的字符串,它返回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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在,当构造函数被调用时,我必须像这样在视图模型构造函数中初始化ThisCar,否则在创建ViewModel时,在ThisCar.Brand上会出现null错误。

ThisCar = new CarObject();
Run Code Online (Sandbox Code Playgroud)

然后,在将其初始化为空对象之后,将调用Message,然后我将基于Car ID从数据库中提取真正的Car。

ThisCar = webService.GetCar(carId);
Run Code Online (Sandbox Code Playgroud)

但是,当我这样做时,品牌属性不会得到更新,因为没有什么调用该品牌的OnPropertyChanged。

我有两种解决方法,但对我来说,它们更像是骇客。首先是手动为需要更新的任何属性调用OnPropertyChanged。其次是我删除所有小的属性,并将所有内容直接绑定到ThisCar属性(这意味着我必须在模型中实现INotifyPropertyChanged)。

请让我知道我是否只是很挑剔,或者是否有更好的方法可以做到这一点。我的工作方式可行,但只是不适合我。谢谢。

Dar*_*ens 2

好的,这就是我的想法,如果这是一个可怕的想法,请告诉我。

我创建了一个名为 IRepository 的接口,因为我使用依赖注入来创建视图模型。这是实现:

public interface IRepository
{
    void GetCarId(Action<int> callback);
    void SetCarId(int value);
}
Run Code Online (Sandbox Code Playgroud)

接下来我创建一个继承自 IRepository 的类

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

    public void setDictionary(int carId)
    {
        CarId = carId;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,为了将值传递到存储库中,我将其放入父视图模型中

 r.SetCarId(13);
Run Code Online (Sandbox Code Playgroud)

为了接收新的视图模型,我将其放入视图模型构造函数中:

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

在我看来,这可以解决问题,而不会破坏 MVVM 模式,并且由于我使用的 IOC 容器将所有接口成员创建为静态,因此我将在其余视图中拥有这些数据。

我遇到的主要问题是它感觉像是一个全局变量,但这是我能想到的最好的办法。请告诉我这是否是一个坏主意。谢谢。