【问题标题】:Caliburn.Micro rebind ContentControl on navigation GoBackCaliburn.Micro 在导航 GoBack 上重新绑定 ContentControl
【发布时间】:2013-05-16 12:33:42
【问题描述】:

我在 WinRT 应用程序中使用 Caliburn.Micro

这是我的主虚拟机:

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

        base.OnActivate();
    }
}

这里我使用了导体,因为我想在 ContentControl 中加载不同的控件,但现在我只有这段代码。这是我在主视图中的内容控件:

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

当我运行应用程序时,一切正常,MainViewModel.Activate 被调用,ActiveItem 设置为 NewsFeedViewModelContentControl 加载 NewsFeedView

问题:

当我使用NavigationService.NavigateToViewModel 方法在NewsFeedView 控件中导航到另一个视图然后在该视图中使用NavigationService.GoBack 时,我将返回到MainView 并且在那一刻MainViewModel.Activate 被调用ActiveItem不是null,而是ContentControl.Contentnull。我尝试使用View.Model 附加属性为ContentControl 但没有运气,如何让它重新绑定?

编辑: 最后,我在 Caliburn 中设置记录器以查看发生了什么,我发现了一个错误 - 当 MainView 在导航后加载时发生此事件:

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(...

虽然信息量不大,但我使用 InteliTrace 获取更多信息并收到以下消息:“元素已经是另一个元素的子元素”。我想 NewsFeedView 存储在某个地方,当需要将它放入 ContentControl 时,就会抛出这个异常。 如何解决?

【问题讨论】:

  • 你检查过MainViewModel对象是否还是和以前一样的实例吗? “元素已经是另一个元素的子元素”听起来就像您正在导航到一个新的 MainViewModel 实例,但旧的实例仍然挂在 NewsFeedViewModel 上。你能分享你的引导程序配置吗?
  • 请分享您的引导程序。这将告诉您有哪些可能性。已经在 .net 4.0 / wpf 场景中解决了这样的问题。
  • @MareInfinitus WinRT 应用中没有引导程序,MainViewModel 在 Caliburn IoC 容器中注册为 Singleton

标签: c# .net winrt-xaml caliburn.micro caliburn


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您应该采用视图模型优先的方法。换句话说,激活视图模型的一个实例,Caliburn.Micro 将为您进行视图定位和绑定。

    例如,您似乎也只想在构造函数中实例化一次视图模型,或者OnInitialise

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

    【讨论】:

    • 感谢您的回答,但我真的不明白您所说的“采用视图模型优先方法”是什么意思,我在调用 ActivateItem 和调用 NavigateToViewModel 时使用视图模型在视图之间导航,所以我在这里不使用视图优先方法
    • 是的,但是从上面包含的 MainViewModel 代码中,您会以一种非常迂回的方式进行处理。您通过使用 ViewModelLocator 和视图类型来获取视图模型。只需首先使用视图模型实例。
    • 好的,明白了,但最终这对数据绑定没有影响,仍然从视图导航回来时,尽管ActiveItem 不为空,但 ContentControl 为空,我尝试调用 NotifyOfPropertyChange(()=&gt;ActiveItem)但结果还是一样
    • 对不起,我很困惑,你是在做 Windows Phone 开发还是 WinRT?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    相关资源
    最近更新 更多