如何使用ViewModelLocator

时间:2016-03-17 18:53:32

标签: wpf mvvm inversion-of-control mvvm-light ioc-container

我在一个简单的WPF应用程序中使用MVVM Light。我知道ViewModelLocator类可用于创建缓存的视图模型对象,两者都带有&没有钥匙。但是,我希望能够创建一个未缓存或键入的视图模型。让我详细说明一下。

我的应用程序中有一个新对话框。该对话框包含一个ComboBox,其中包含一个选项列表,一个OK按钮&一个取消按钮。我尝试为新对话框的视图模型对象添加属性ViewModelLocator,如下所示:

public NewObjectViewModel NewObject {
    get { return ServiceLocator.Current.GetInstance<NewObjectModel>(); }
}

这很有效,但如果我打开新对话框一次,做出选择并单击确定,然后再次打开它,则用户的上一个选择已被选中。这不是我想要的。我希望新对话框在每次打开时都处于完全相同的初始状态。

我是否只是通过拨打ServiceLocator.Current.GetInstance<NewObjectModel>()来取代对new NewObjectModel()的通话?或者我需要使用ServcieLocator.Current的不同呼叫?

这是一个简单的例子,因为这个视图模型类的构造函数没有参数。我有另一个对话框,它以IDataService引用作为参数。它有第二个参数,它是一个MyModel对象。看起来整个模式在这种情况下不起作用,因为你不能将模型对象传递给属性,而模型对象是MainViewModel类的属性。

如何在这两种情况下正确使用ViewModelLocator

修改

我已经做了更多的搜索&amp;我发现SimpleIoc类有一个GetInstanceWithoutCaching<T>()方法,适用于我的新对话框。这就是问题的一半。

但是,我如何处理使用ViewModelLocator为视图模型类创建新视图模型的情况,其构造函数将模型对象作为参数?

1 个答案:

答案 0 :(得分:1)

我已经能够找到解决我的问题的方法,并且非常优雅。

首先,正如我在编辑问题中所说,我在MVVM Light GetIntanceWithoutCaching<T>()类中找到了SimpleIoc方法。此方法创建一个类的新实例,其类型在每次调用时都在T中传递。

其次,我发现this blog post描述了子对话框的视图模型的过程,该过程将消息发送回主视图模型,该模型请求接收者向其发送所需的模型对象。以下是我必须对代码进行的所有更改才能使其生效。

首先,我创建了一个新的消息类:

public class GetMyModelMessage : MessageBase {

    public Action<MyModel> Callback { get; private set; }

    public GetMyModelMessage( Action<MyModel> callback ) {
        Callback = callback;
    }
}

然后,在MainViewModel中:

public MainViewModel() {
    // Existing initialization code

    Messenger.Default.Register<GetMyModelMessage>( this, SendMyModel );
}

private void SendMyModel( GetMyModelMessage message ) {
    message.Callback( MyModelProperty );
}

在子窗口的视图模型的构造函数中:

public ChildViewModel() {
    // Existing initialization

    Messenger.Default.Send( new GetMyModelMessage( m => MyModelProperty = m );
}

最后,在ViewModelLocator

public ChildViewModel Child {
    get { return SimpleIoc.Default.GetInstanceWithoutCaching<ChildViewModel>(); }
}

通过所有这些更改,子窗口的XAML现在可以像主窗口一样设置DataContext,当孩子在ViewModelLocator时创建它的新视图模型创建窗口后,子视图模型发送要显示的模型对象的请求。子视图模型不知道谁将处理消息,只是它通过消息中的回调获得要显示的对象。