0

I have RichBox binded to a List<String>ListName in the using of the window I add some item in this list, but after I close this window and I open it i still have the old added name, I know that the View model don't be disposed when I close window, but I use this on closing

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

but this will clean only the Messenger and let all my other items with values, I want to clear all resource in this ViewModel when I close the window

Update :

with Rudi answer I try on closing to do

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

and it work, but it seems not right to me to Unregister the VM and register it again !

Akrem
  • 5,033
  • 8
  • 37
  • 64

2 Answers2

2

You can just unregister an instance of the class than remove the entire class if you want.

Snippet from 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;

Do keep in mind to get a new instance of the class on every resolve from SimpleIoC we need to specify a unique key to it in GetInstance()

so in ViewModelLocator.cs keep a reference to the currentKey used and un-register it on the next attempt, something like:

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);
  }
}

This way each time the VMLocator is queried for Scan a new VM is returned after unregistering the current VM. This approach would comply with the guidelines suggested by "Laurent Bugnion" Here and I'd take it he knows his own libraries pretty well and you're not going to go wrong doing it that way.

I remember MVVM Light's author state somewhere SimpleIoC was intended to get dev's familiar with IOC principles and let them explore it for themselves. It's great for simple project's, If you do want more and more control over your VM injections then I'd suggest looking at things like Unity in which your current situation would have been resolved pretty easily since you could just go

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

You also get LifeTimeManagers and sorts that give even greater control. Yes Unity is an overhead compared to SimpleIoC, but it's what the technology can provide when needed than having to write code yourself.

Community
  • 1
  • 1
Viv
  • 17,170
  • 4
  • 51
  • 71
0

I guess this would do it:

SimpleIoc.Default.Unregister<ViewModelName>();

edit: how about this

    public ViewModelName MyViewModel
    {
        get
        {
            ViewModelName vm = ServiceLocator.Current.GetInstance<ViewModelName>();
            SimpleIoc.Default.Unregister<ViewModelName>();
            //or SimpleIoc.Default.Unregister<ViewModelName>(MyViewModel);
            return vm;
        }
    }
Rudi
  • 926
  • 2
  • 19
  • 38
  • but in this case when I open the same window again nothing work(there's not a VM for the View) – Akrem May 27 '13 at 14:15
  • you could re-register the ViewModel `SimpleIoc.Default.Register();` , but since I don't use this I can't say if it would actually work or if this is the right method to do it like this. – Rudi May 27 '13 at 14:21
  • I test it and it work, but I don't see that a good practice to do it for every VM – Akrem May 27 '13 at 14:25