【问题标题】:cleanup all items in a ViewModel when closing window关闭窗口时清理 ViewModel 中的所有项目
【发布时间】:2013-05-27 13:56:08
【问题描述】:

我在使用窗口时将RichBox 绑定到List<String>ListName 我在这个列表中添加了一些项目,但是在我关闭这个窗口并打开它之后我仍然有旧的添加名称,我知道关闭窗口时不会释放视图模型,但我在关闭时使用它

public virtual void Cleanup()
{
    this.MessengerInstance.Unregister(this);
}

但这只会清理Messenger 并让我的所有其他项目具有值,我想在关闭窗口时清除此 ViewModel 中的所有资源

更新:

有了鲁迪的回答,我尝试关闭做

SimpleIoc.Default.Unregister<ScanViewModel>();
SimpleIoc.Default.Register<ScanViewModel>();

它可以工作,但我似乎不适合取消注册虚拟机并重新注册!

【问题讨论】:

    标签: c# wpf mvvm-light resource-cleanup


    【解决方案1】:

    如果需要,您可以只注销该类的一个实例,而不是删除整个类。

    来自SimpleIoc.cs的片段:

    //
    // Summary:
    //     Removes the instance corresponding to the given key from the cache. The class
    //     itself remains registered and can be used to create other instances.
    //
    // Parameters:
    //   key:
    //     The key corresponding to the instance that must be removed.
    //
    // Type parameters:
    //   TClass:
    //     The type of the instance to be removed.
    public void Unregister<TClass>(string key) where TClass : class;
    

    请记住,每次从 SimpleIoC 解析时都要获取该类的新实例,我们需要在 GetInstance() 中为其指定唯一键

    所以在ViewModelLocator.cs 中保留对currentKey 的引用并在下次尝试时取消注册,例如:

    private string _currentScanVMKey;
    public ScanViewModel Scan
    {
      get {
        if (!string.IsNullOrEmpty(_currentScanVMKey))
          SimpleIoc.Default.Unregister(_currentScanVMKey);
        _currentScanVMKey = Guid.NewGuid().ToString();
        return ServiceLocator.Current.GetInstance<ScanViewModel>(_currentScanVMKey);
      }
    }
    

    这样,每次在 VMLocator 中查询 Scan 时,在取消注册当前 VM 后都会返回一个新 VM。这种方法符合“Laurent Bugnion”Here 建议的指导方针,我认为他非常了解自己的库,这样做不会出错。

    我记得 MVVM Light 的作者状态 SimpleIoC 旨在让开发人员熟悉 IOC 原则并让他们自己探索。这对于简单的项目来说非常有用,如果您确实希望对 VM 注入进行越来越多的控制,那么我建议您查看 Unity 之类的东西,您目前的情况很容易解决,因为您可以去

    // _container is a UnityContainer
    _container.RegisterType<ScanViewModel>();  // Defaults to new instance each time when resolved
    _container.RegisterInstance<ScanViewModel>();  // Defaults to a singleton approach
    

    您还可以获得 LifeTimeManagers 和排序功能,可以提供更大的控制权。是的,与 SimpleIoC 相比,Unity 是一种开销,但这是该技术在需要时可以提供的,而不是自己编写代码。

    【讨论】:

      【解决方案2】:

      我想这会做到:

      SimpleIoc.Default.Unregister<ViewModelName>();
      

      编辑:这个怎么样

          public ViewModelName MyViewModel
          {
              get
              {
                  ViewModelName vm = ServiceLocator.Current.GetInstance<ViewModelName>();
                  SimpleIoc.Default.Unregister<ViewModelName>();
                  //or SimpleIoc.Default.Unregister<ViewModelName>(MyViewModel);
                  return vm;
              }
          }
      

      【讨论】:

      • 但在这种情况下,当我再次打开同一个窗口时,没有任何效果(视图没有虚拟机)
      • 您可以重新注册 ViewModel SimpleIoc.Default.Register&lt;ViewModelName&gt;(); ,但由于我不使用它,我不能说它是否真的有效,或者这是否是这样做的正确方法。
      • 我对其进行了测试并且它可以工作,但我认为这并不是对每个 VM 都进行的好习惯
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-03
      • 1970-01-01
      • 2021-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多