如何避免多个视图从同一视图模型接收数据

时间:2013-07-08 12:44:21

标签: c# .net wpf mvvm mvvm-light

我对代码的行为感到困惑。我还是MVVM灯的新人。

我有NewMessageWindow,它由命令

显示
    private ICommand newMessageCommand;
    public ICommand NewMessageCommand
    {
        get
        {
            if (newMessageCommand == null)
                newMessageCommand = new RelayCommand(() =>
                {
                    new NewMessageWindow().Show();
                });
            return newMessageCommand;
        }
    }

可以有多个NewMessageWindows,每个都应该有单独的ViewModel。但是我注意到当我打开多个窗口时,如果我在其中更改某些内容,则会影响所有窗口。例如,当我更改组合框时,所有窗口中的combox值都会发生变化。

如何避免它?如何使用不会相互影响的分隔视图模型打开多个窗口?

正在更改的对象是绑定到视图的 ObservableCollections

编辑:

这就是ViewLocator的样子

    public NewMessageWindowModel NewMessage
    {
        get
        {
            return ServiceLocator.Current.GetInstance<NewMessageWindowModel>();
        }
    }

并在构造函数

    SimpleIoc.Default.Register<NewMessageWindowModel>();

这就是绑定的样子:

 DataContext="{Binding NewMessage,
                          Source={StaticResource Locator}}"

我修复了

的问题
 ServiceLocator.Current.GetInstance<NewMessageWindowModel(System.Guid.NewGuid().ToString());

但我已经读过旧的实例被缓存了。如何摆脱它们?

2 个答案:

答案 0 :(得分:1)

来自MVVM Light的

SimpleIoC不会使用ServiceLocator.Current.GetInstance<...>();每次调用创建新VM

您可以从图书馆的作者那里找到解释,以便每次Here

获取新的VM

对于您的情况,

我可能只是在DataContext的代码隐藏构造函数中设置NewMessageWindow,而不是直接在xaml中设置:{/ p>

public NewMessageWindow() {
  InitializeComponent();
  var uniqueKey = System.Guid.NewGuid().ToString();
  DataContext = SimpleIoc.Default.GetInstance<NewMessageWindowModel>(uniqueKey);
  Closed += (sender, args) => SimpleIoc.Default.Unregister(uniqueKey);
}

这样,当Window关闭时,VM将从缓存中删除。

请注意,这不是唯一的方法,您还有其他一些选择,

  • 您可以将绑定保留在DataContext的xaml中,当Window关闭时,使用MVVM Light中的Messenger类向ViewModelLocator发送消息删除缓存。
  • 您可以在Cleanup()中实施ViewModelLocator功能,以便在显示密钥时删除缓存。

选择您喜欢的实现并使用它或使用类似Unity或其他DI容器帮助程序的内容来更好地控制VM对象的生命周期。

答案 1 :(得分:0)

这种行为是因为Servicelocator。它返回对象的同一个实例。您可以在整个共享实例中获得更改。如果你想拥有ViewModel的单独副本。您可以将GetNewInstance实现到Service定位器中。