6

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

现在,在 InitializeComponent() 之后,我通过在视图上使用信使来传递它。然后由 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 构造函数中初始化 ThisCar,否则在创建 ViewModel 时我会在 ThisCar.Brand 上收到 null 错误。

ThisCar = new CarObject();

然后,在它被初始化为一个空对象之后,Message 会被调用,我会根据 Car ID 从数据库中拉出真正的 Car。

ThisCar = webService.GetCar(carId);

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

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

请让我知道我是否只是挑剔,或者是否有更好的方法来做到这一点。我这样做的方式很有效,但就是不适合我。谢谢你。

4

2 回答 2

2

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

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

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);

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

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

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

我遇到的主要问题是它感觉像是一个全局变量,但这是我能想到的最好的。请让我知道这是否是一个非常糟糕的主意。谢谢你。

于 2013-08-29T21:23:38.997 回答
1

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

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

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

谢谢

于 2013-08-29T03:02:00.627 回答