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

本文关键字:视图 模型 数据 何避免 | 更新日期: 2023-09-27 18:21:24

我对代码的行为有点困惑。我还是MVVM方面的新手。

我有命令显示的NewMessageWindow

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

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

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

正在更改的对象是绑定到视图的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());

但我读到过旧实例是缓存的。如何摆脱它们?

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

MVVM Light的SimpleIoC不会在每次调用ServiceLocator.Current.GetInstance<...>(); 时创建新的VM

你可以从库的作者那里找到解释,每次都可以获得一个新的VM在这里

对于您的情况,

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

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发送消息以删除缓存
  • 您可以在ViewModelLocator中实现Cleanup()函数,以在出现密钥时删除缓存

选择一个你喜欢的实现并使用它,或者使用类似Unity或其他DI容器助手的东西来获得对VM对象生存期的更多控制。

这种行为是因为Servicelocator。它们返回对象的相同实例。在那里您可以获得所有共享实例的更改。如果您想要ViewModel的一个副本。您可以在服务定位器中实现GetNewInstance。