question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Conductor<T>'s ActiveItem not Updating View

See original GitHub issue

Problem

I am using Caliburn Micro in WPF on Windows / desktop.

I have the following very simple ShellView.xaml:

<ContentControl Caliburn:View.Model="{Binding ActiveItem}"/>

I am using a Conductor<IViewModelBase> to display the ActiveItem.

My ShellViewModel.cs (Conductor) looks like this:

    internal sealed class ShellViewModel : Conductor<IViewModelBase>, IShellViewModel
    {
        private readonly IMainViewModel mainViewModel;

        public ShellViewModel(IWelcomeViewModel welcomeViewModel, IMainViewModel mainViewModel)
        {
            this.mainViewModel = mainViewModel;

            welcomeViewModel.Deactivated += WelcomeViewModel_Deactivated;
            ChangeActiveItem(welcomeViewModel, false); // <-- Initial ActiveItem
        }

        private void WelcomeViewModel_Deactivated(object sender, DeactivationEventArgs e)
        {
            ((IWelcomeViewModel)sender).Deactivated -= WelcomeViewModel_Deactivated;
            ChangeActiveItem(mainViewModel, true); // <-- Changes ActiveItem to MainViewModel
        }
    }

For the purposes of testing, WelcomeViewModel TryClose()-s after 10 seconds:

    internal class WelcomeViewModel : ViewModelBase, IWelcomeViewModel
    {
        public WelcomeViewModel()
        {
            Timer timer = new Timer(10_000) { Enabled = true };
            timer.Elapsed += (sender, e) => TryClose();
            timer.Start();
        }
    }

The expected result is that the view should update its UserControl to match whichever ViewModel has been bound to, which is the ActiveItem, which changes after 10 seconds. However, it doesn’t - the screen becomes blank (white).

Attempted Solutions

I’ve tried swapping the two ViewModels around - having the MainViewModel go first - and in that case, the MainViewModel is displayed, however the screen does not end up displaying WelcomeViewModel; it goes blank instead.

Subsequently, I tried manually notifying of change.

NotifyOfPropertyChange(() => ActiveItem);

This also did not work.

I have also tried using convention binding on the ShellView.xaml (x:Name="ActiveItem") which also did not work.

Finally, I remember once having to activate my conductor (Conductor<T>.Collection.OneActive) in order for it to properly activate/deactivate views, so I tried that as well (in ShellViewModel.cs):

ScreenExtensions.TryActivate(this);

also to no avail.

What worked, however, was having a custom IViewModelBase property (e.g. ActiveView), and binding to that instead, changing it whenever ChangeActiveItem is called.

Question

I can, of course, fix this issue by either rolling my own ActiveItem, or not using Conductor<T> at all, however I would like to do this properly.

Is there some kind of trick to using Conductor<T>, or is this just a bug? I have searched plenty on the internet and nothing seemed to work.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:11 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
Aleksbgbgcommented, Jan 29, 2018

Okay, thanks for all the help. You can close the issue if you wish.

1reaction
nigel-sampsoncommented, Jan 29, 2018

From what I can tell there’s a bit of a race condition happening here. Calling TryClose on WelcomeViewModel will deactivate that view model, and remove it from being the ActiveItem. However by listening for that event and jumping in the middle we’re trying to replace the ActiveItem before the previously one is finished being closed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Caliburn Micro Conductor.Collection.AllActive not working
Conductor.Collection.AllActive uses Items property. If you want to display multiple Screens at once, you have to add them to Items property.
Read more >
Screens, Conductors and Composition
If not, the action is cancelled. Checks to see if the closing item is the current ActiveItem. If so, determine which item to...
Read more >
Conductor<IScreen>.Collection.AllActive child view ...
I am working on a WPF app and I have a view model which inherits from Conductor.Collection.AllActive. I add child views to the...
Read more >
Caliburn.Micro Conductor; What Am I Missing?
In the view, I have a contentcontrol bound to the ActiveItem property of the Conductor. In a separate view/viewmodel pair, I have a...
Read more >
Update Conductor Firmware - Airwall help be invisible
How to update the firmware for an Airwall Conductor. ... Download, but do not install, the new firmware to the current active Conductor...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found