Confusion about View lifetime.

Topics: Getting Started, UI Architecture
Apr 15, 2013 at 11:27 PM
I am working on a relatively large and complex WPF app and am using Caliburn Micro as an MVVM library to help make it easier to test and maintain. This is the first real project I've used CM on, and while I've read much of the documentation, I still have a couple questions that I cannot find answers to.

The layout of the app is essentially a Shell with two main Views that can be toggled between. These views on sub-views in them, which also have subviews and so on. My Shell VM has contains an instance of each view's VM and sets the currently displayed one to a "CurrentVM" variable to switch between them. I could probably switch to using a conductor, but I'm not using any of the extra functionality it enables so I don't know what benefit it would be.

My first Question is this: Is it possible to persist the state of the view? I just leared yesturday that when switching the CurrentVM to a new ViewModel, the old view gets Unloaded. The ViewModels' states all persist, since they are kept in instance variables, but View-only stuff (like the state of expanders, position of scrollviewers, etc) are reset when switching back to a View. I would like these things to persist between toggling views.

Is there a good/easy way to do this or a standard convention or feature in CM that I haven't found yet? The only methods I can think of are:
  • Bind all those view properties to variables VM, which seems like a lot of work and would clutter the VM a TON.
  • or Don't switch between Views, but just hide one and display the other and toggle their Visibility.
Is there a better way?

My second Question is about some odd behavior I'm seeing with some custom converters I'm binding to one of the sub-sub-views. Each time I toggle between views, they are unloaded and then re-created, but it seems like the old bindings are not released. Because of this, after a few toggles, the converters are being called multiple times instead of once. This seems like it will become a memory leak.

I created the simplest example of the issue and put it on github:

Pressing the 'First' button will bring up the view with the bound converters. When clicking one of the radiobuttons, convertback should be called for the button selected, and convert should be called 3 times, once for each button. Debug.WriteLine statements are used to show when they are called. This works fine the first time the view is brought up, but if you click first/second several times to toggle, the convert and convertback functions are called many times for each click on a radiobutton.

I'm not sure what to do about this behavior.

Sorry if any of this is confusing or simply wrong, I haven't been learning it for very long.

Apr 15, 2013 at 11:56 PM
So, after writing all that and posting it... I went and made the quick change to Conductor<IScreen>.Collection.OneActive and... the view's state persists just like I wanted. I assumed it would work the same as how I was doing it, but I guess not...
Apr 18, 2013 at 9:31 AM
Edited Apr 18, 2013 at 9:34 AM
Apr 22, 2013 at 10:33 PM
Yea, thanks for the links. It looks like the views are cached by default when using Conductor Collection, which is what I was trying for.