简体   繁体   中英

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?

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());
}

正如@devdigital所说,可能只在构造函数中初始化新闻订阅源视图模型一次,为什么不使用Conductor.Collection.OneActive,因为在任何给定时间只有一个活动项,它用于这种情况,这可以解决你的问题问题。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM