title: caliburn.micro Condutor not working
body: <p>We are using caliburn.micro for one of our projects and I'm currently having a puzzling problem:</p>
  
  <p>we have the following classes:</p>
  
  <pre><code>ToolViewerViewModel : Conductor&lt;Screen&gt;.Collection.OneActive
  DocViewerViewModel : Conductor&lt;DocumentViewModel&gt;
  </code></pre>
  
  <p>and various document-views, all with this base class:</p>
  
  <pre><code>DocumentViewModel : Screen
  </code></pre>
  
  <p>The <code>ToolViewerViewModel</code> is to manage multiple dock-able tool views which allow the user to control different aspects of the program.</p>
  
  <p>The <code>DocViewerViewModel</code> is to show the user the data he's working on/with. It is here to present one of the many <code>DocumentViewModel</code> to the user. and is implemented as a special dock-able view which can not be closed or detached from the <code>ToolViewerView</code>. For every aspect of the data a specific <code>DocumentViewModel</code> is generated by the <code>DocViewerViewModel</code> and presented to the user.</p>
  
  <p>The <code>DocumentViewModel</code> is the base class for all presentation aspects of the data. One may present the data as a table an other may present it as a chart, and so on...</p>
  
  <p>We now encounter problems in terms of <code>OnActivate()</code> and <code>OnDeactivate()</code> which are not called when we expect them to be called.</p>
  
  <p>First Problem:
  The system is up and running; The <code>DocumentViewModel</code> is displayed in the <code>DocViewerViewModel</code> which is embedded in the <code>ToolViewerViewModel</code> along with one or two other dock-able views. The currently selected dock-able view is the <code>DocViewerViewModel</code>. When the user now selects one of the other dock-able views the <code>OnDeactivate()</code> method from the <code>DocumentViewModel</code> is being called. Which makes absolutely no sense to me. I'd expect the <code>DocViewerViewModel.OnDeactivate()</code> to be called.</p>
  
  <p>Second Problem:
  The system is up and running; The <code>DocumentViewModel</code> is displayed in the <code>DocViewerViewModel</code> which is embedded in the <code>ToolViewerViewModel</code> along with one or two other dock-able views. The currently selected dock-able view is the view that enables the user to change the <code>DocumentViewModel</code> presented by the <code>DocViewerViewModel</code>. When the user now selects an other <code>DocumentViewModel</code> the following code is being executed within the <code>DocViewerViewModel</code>:</p>
  
  <pre><code>DocViewerViewModel.DeactivateItem(oldDocumentViewModel, true);
  DocViewerViewModel.ActivateItem(new DocumentViewModel());
  </code></pre>
  
  <p>I'd expect the <code>DocumentViewModel.OnDeactivate()</code> to be called upon the <code>DocViewerViewModel.DeactivateItem(oldDocumentViewModel, true)</code> call. but that never happens.</p>
  
  <p>Conclusion:
  The only proper working Conductor is the <code>ToolViewerViewModel</code> which is managing everything. But this behavior is not what we want or expect to happen: We'd like to have the <code>ToolViewerViewModel</code> only Conduct the dock-able views and the <code>DocViewerViewModel</code> to conduct the <code>DocumentViewModel</code>. This is important because there are two different use cases in place: One to manage multiple instances at the same time and the other where only one instance is active and used, the old instance shall be thrown away.</p>
  
  <p>Hopefully anyone here can help me to get the behavior I'm looking for.</p>
  
  <p>I Now have an example code for you:</p>
  
  <pre><code>public class ToolViewerViewModel : Conductor&lt;Screen&gt;.Collection.OneActive
  {
      private readonly IDockManager _dockManager;
      private readonly DocViewerViewModel _docViewerViewModel;
      private readonly IList&lt;DockableViewModel&gt; _toolViews = new List&lt;DockableViewModel&gt;();
  
      public ToolViewerViewModel(IViewModelFactory viewModelFactory, DocViewerViewModel docViewerViewModel, IDockManager dockManager)
      {
          _dockManager = dockManager;
          _viewModelFactory = viewModelFactory;
          _docViewerViewModel = docViewerViewModel;
      }
  
      protected override void OnViewLoaded(object view)
      {
          _dockManager.Link(this);
          _dockManager.CreateSpecialPaneFor(_docViewerViewModel);
          ActivateItem(_docViewerViewModel);
  
          ShowToolView&lt;ProjectExplorerViewModel&gt;();
          base.OnViewLoaded(view);
      }
  
      public void ShowToolView&lt;T&gt;() where T : DockableViewModel
      {
          if (!IsToolViewOpen&lt;T&gt;())
          {
              var viewModel = _viewModelFactory.Create&lt;T&gt;();
              ActivateItem(viewModel);
              RefreshMenu(typeof(T));
          }
      }
  }
  </code></pre>
  
  <p>Next class:</p>
  
  <pre><code>public class DocViewerViewModel : Conductor&lt;DocumentViewModel&gt;
  {
      private readonly IViewModelFactory _viewModelFactory;
  
      public DocViewerViewModel(IViewModelFactory viewModelFactory)
      {
          _viewModelFactory = viewModelFactory;
      }
  
      public bool ShowInMainView&lt;T&gt;() where T : DocumentViewModel
      {
          return ShowInMainView(typeof(T));
      }
  
      private bool ShowInMainView(Type viewModelType)
      {
          var ret = false;
  
          // close the current view
          if (ActiveItem != null)
          {
              DeactivateItem(ActiveItem, true); //The close flag is on true since we want to remove the current instance from the memory
          }
  
          // check whether the current viewModel has been closed successfully
          if (ActiveItem == null)
          {
              try
              {
                  var viewModel = _viewModelFactory.Create(viewModelType) as DocumentViewModel;
                  if (viewModel != null)
                  {
                      ActivateItem(viewModel);
                      ret = true;
                  }
                  else
                  {
                      ActivateItem(_viewModelFactory.Create&lt;NoDataViewModel&gt;());
                  }
              }
              catch (Exception ex)
              {
                  ActivateItem(_viewModelFactory.Create&lt;NoDataViewModel&gt;());
              }
          }
  
          return ret;
      }
  }
  </code></pre>
  
  <p>and the last one:</p>
  
  <pre><code>public abstract class DocumentViewModel : Screen
  {
      private bool _isDirty;
  
      protected IViewModelFactory ViewModelFactory { get; private set; }
      protected IEventAggregator EventAggregator { get; private set; }
  
      public bool IsDirty
      {
          get
          {
              return _isDirty;
          }
          protected set
          {
              if (value.Equals(_isDirty))
              {
                  return;
              }
              _isDirty = value;
              NotifyOfPropertyChange(() =&gt; IsDirty);
          }
      }
  
      protected DocumentViewModel(IViewModelFactory viewModelFactory, IEventAggregator eventAggregator)
      {
          ViewModelFactory = viewModelFactory;
          EventAggregator = eventAggregator;
      }
  
      protected override void OnDeactivate(bool close)
      {
          if (close)
          {
              if (EventAggregator != null)
              {
                  EventAggregator.Unsubscribe(this);
              }
          }
          base.OnDeactivate(close);
      }
  
      protected override void OnActivate()
      {
          if (EventAggregator != null)
          {
              EventAggregator.Subscribe(this);
          }
          base.OnActivate();
      }
  
      public override void CanClose(Action&lt;bool&gt; callback)
      {
          var ret = true;
          if (IsDirty &amp;&amp; (ViewModelFactory != null))
          {
              var saveDialog = ViewModelFactory.Create&lt;SaveDialogViewModel&gt;();
              saveDialog.Show();
              if (saveDialog.DialogResult == DialogResult.Cancel)
              {
                  ret = false;
              }
              else
              {
                  if (saveDialog.DialogResult == DialogResult.Yes)
                  {
                      Save();
                  }
                  else
                  {
                      Discard();
                  }
                  IsDirty = false;
              }
          }
          callback(ret);
      }
  
      public abstract void Save();
  
      public virtual void Discard()
      {
      }
  }
  </code></pre>
  
  <p>With this code the only time the <code>DocumentViewModel.OnDeactivate()</code> is being called when the user brings an other dock-able view into focus while the <code>DocViewerViewModel</code> was having the focus. This should not happen!</p>
  
  <p>When the user is changing the focus between the dock-able views the  <code>DocumentViewModel.OnDeactivate()</code> should not get call. But it must get called when ever the Method <code>DocViewerViewModel.ShowInMainView&lt;SomeDocumentViewModel&gt;()</code> is being called. Which isn't the case currently.</p>