我在一个简单的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
为视图模型类创建新视图模型的情况,其构造函数将模型对象作为参数?
答案 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
时创建它的新视图模型创建窗口后,子视图模型发送要显示的模型对象的请求。子视图模型不知道谁将处理消息,只是它通过消息中的回调获得要显示的对象。