1

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

我有命令显示的 NewMessageWindow

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

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

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

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

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

4

2 回答 2

1

SimpleIoC来自 MVVM Light 不会在每次调用时创建一个新的 VMServiceLocator.Current.GetInstance<...>();

您可以从库的作者那里找到每次获取新 VM 的说明Here

对于你的情况,

我可能只是DataContext在代码隐藏构造函数中NewMessageWindow直接在 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 中的绑定,使用 MVVM Light 中的类向 MVVM Light 发送消息以删除缓存。WindowMessengerViewModelLocator
  • 您可以在 中实现该Cleanup()功能以在ViewModelLocator出现键时删除缓存。

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

于 2013-07-08T13:16:21.320 回答
0

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

于 2013-07-08T13:12:44.007 回答