Alexander
Alexander

Reputation: 1297

Caliburn.Micro rebind ContentControl on navigation GoBack

I'm using Caliburn.Micro within WinRT application

Here is my main VM:

public class MainViewModel : Conductor<Screen>
{
    protected override void OnActivate()
    {
        if (ActiveItem == null)
        {
           ActivateItem(
               ViewModelLocator.LocateForViewType(typeof(NewsFeedView)) as Screen);
        }

        base.OnActivate();
    }
}

here I use conductor because I want to load different controls in ContentControl, but now I have only this code. Here is my content control in main view:

<ContentControl x:Name="ActiveItem" Grid.Column="1" Grid.Row="1" />

When I running the application everything work fine, MainViewModel.Activate gets called and ActiveItem set to NewsFeedViewModel and ContentControl loads NewsFeedView.

The problem:

When I navigate in NewsFeedView control to another view using NavigationService.NavigateToViewModel method and then in that view use NavigationService.GoBack, i'm returning to MainView and in that moment when MainViewModel.Activate gets called ActiveItem is not null, but ContentControl.Content is null. I've tried use View.Model attached property for ContentControl but no luck, how to make it rebind?

EDIT: Finally i'm setup logger in Caliburn to see what happens and I found an error - when MainView loaded after navigationg back this events occuring:

Attaching ***.Views.MainView to ***.ViewModels.MainViewModel.
ViewModel bound on ActiveItem.
Using cached view for ***.ViewModels.NewsFeedViewModel.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Exception: Unspecified error
at Windows.UI.Xaml.Controls.ContentControl.put_Content(Object value)
... some winRT stack
at Caliburn.Micro.View.SetContentPropertyCore(...

Though it was not so informative I've used InteliTrace to get more info and got this message: "Element is already child of another element". I suppose NewsFeedView stored somewhere and when time comes to put it in ContentControl this exception thrown. How to solve this?

Upvotes: 9

Views: 1443

Answers (2)

Ibrahim Najjar
Ibrahim Najjar

Reputation: 19423

Initialize the news feed view model only once as @devdigital said, probably in the constructor, and why not use Conductor.Collection.OneActive since you only have one active item at any given time, it is used for this situations, this could solve your issue.

Upvotes: 1

devdigital
devdigital

Reputation: 34349

You should adopt the view model first approach. In other words, activate an instance of a view model, and Caliburn.Micro will do the view location and binding for you.

It also looks like you want to just instantiate the view model once in the constructor for example, or OnInitialise:

public MainViewModel()
{
    this.ActivateItem(new NewsFeedViewModel());
}

Upvotes: 3

Related Questions