【问题标题】:How to create non keyed, non cached viewmodel using ViewModelLocator如何使用 ViewModelLocator 创建非键控、非缓存视图模型
【发布时间】:2016-07-04 07:38:45
【问题描述】:

我在一个简单的 WPF 应用程序中使用 MVVM Light。我知道ViewModelLocator 类可用于创建缓存的视图模型对象,无论是带键还是不带键。但是,我希望能够创建一个没有缓存或键控的视图模型。让我详细说明。

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

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

这可行,但如果我打开新对话框一次,做出选择并单击“确定”,然后稍后再次打开,则用户之前的选择已被选中。这不是我想要的。我希望新对话框每次打开时都处于完全相同的初始状态。

我是否只需将调用ServiceLocator.Current.GetInstance&lt;NewObjectModel&gt;() 替换为调用new NewObjectModel()?或者我需要使用不同的ServcieLocator.Current 电话吗?

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

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

编辑:

我进行了更多搜索,发现SimpleIoc 类有一个GetInstanceWithoutCaching&lt;T&gt;() 方法,适用于我的新对话框。所以这是问题的一半。

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

【问题讨论】:

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


    【解决方案1】:

    我已经找到了一个有效且非常优雅的解决方案。

    首先,正如我在问题编辑中所说,我在 MVVM Light SimpleIoc 类中找到了 GetIntanceWithoutCaching&lt;T&gt;() 方法。该方法创建一个新的类实例,其类型在每次调用时传入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 会为其创建一个新的视图模型,子视图模型向模型对象发送显示请求。子视图模型不知道谁来处理消息,只是通过消息中的回调得到一个对象来显示。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-15
      • 2020-07-21
      • 2011-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多