繁体   English   中英

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

[英]Best Way to Pass Data to new ViewModel when it is initiated

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

现在我在InitializeComponent()之后使用View上的messenger传递这个。 然后由View Model捕获。 这目前确实有效,但它有一些挫折。

首先,在调用视图模型的构造函数之前,不会发送消息。 假设我在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);
        }
    }

现在当构造函数被调用时,我必须在View Model Constructor中初始化ThisCar,就像这样,否则我在创建ViewModel时会在ThisCar.Brand上得到null错误。

ThisCar = new CarObject();

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

ThisCar = webService.GetCar(carId);

但是,当我这样做时,品牌属性不会更新,因为没有任何东西为品牌调用OnPropertyChanged。

我有两个工作,但他们觉得更像是我的黑客。 首先,为任何需要更新的属性手动调用OnPropertyChanged。 其次是删除所有小属性,并将所有内容直接绑定到ThisCar属性(这意味着我必须在我的模型中实现INotifyPropertyChanged)。

如果我只是挑剔,或者有更好的方法,请告诉我。 我这样做的方式有效,但不能和我坐在一起。 谢谢。

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

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

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

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

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

    public void setDictionary(int carId)
    {
        CarId = carId;
    }
}

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

 r.SetCarId(13);

并且在新视图中接收模型我把它放在View Models Constructor中:

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

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

我遇到的主要问题是它感觉像是一个全局变量,但这是我能想到的最好的变量。 如果这是一个非常糟糕的主意,请告诉我。 谢谢。

我会投票让模型能够通知那些变化,即在模型中实现INotifyPropertyChanged。 两个原因:

  1. 您可能需要使用相同模型的多个位置/视图,并且您不希望在每个ViewModel中注意哪个属性更改应该引发哪个其他属性更改。 坦率地说那是凌乱和马车。

  2. 有时,在VM层中,我们可能需要监听模型中的更改,因此在这种情况下,自我通知模型也会有所帮助。

谢谢

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM