Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 267
Alexander Avatar asked May 21 '13 16:05

Alexander


1 Answers

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());
}
like image 108
devdigital Avatar answered Sep 29 '22 18:09

devdigital