为什么Caliburn.Micro(与modern-ui一起使用)OnActivate在ActivateItem之后没有被调用?

时间:2014-10-07 16:53:48

标签: wpf caliburn.micro modern-ui

我在Caliburn.Micro应用中使用Modern-UIWPF。在modern-ui框架(一个UserControl)内的“页面”上,我试图使用Conductor来切换当前视图。这是我到目前为止所得到的:

注意:为简洁起见,从源代码中删除了命名空间

现代ui窗口内“页面”的XAML

<UserControl x:Class="ShellView">
    <ContentControl x:Name="ActiveItem" />
</UserControl>

ShellViewModel(指挥)的来源

[Export]
public class ShellViewModel : Conductor<IScreen>.Collection.OneActive
{
    private readonly Test1ViewModel m_TestView1;
    private readonly Test2ViewModel m_TestView2;

    public ShellViewModel()
    {
        this.m_TestView1 = new Test1ViewModel();
        this.m_TestView2 = new Test2ViewModel();

        this.ActivateItem(this.m_TestView1);
    }
}

Test1View的XAML目前没有任何内容,只是普通的UserControl内容。

Test1ViewModel的来源

public class Test1ViewModel : Screen
{
    protected override void OnActivate()
    {
        //This DOES NOT show or fire, I even put a breakpoint to double check
        Debug.Print("This should show in output");
    }
}

调用ActivateItem时,OnActivate根本不会触发。我甚至尝试在指挥中的视图模型ConductWith(this)上调用Test1ViewModel,但这不起作用。我使用的Modern-UI可能很重要,因为同样的事情适用于不使用Modern-UI的不同项目。哦,当调用ActivateItem时,屏幕上会显示相应的视图(我添加了一些按钮以验证视图确实发生了变化)。

关于调用UserControlContentControl之后ActivateItemOnActivate中显示的原因的任何想法根本不会触发?

还有一件事......这也可能与它有关,但如果确实如此,我不知道为什么或如何解决它。我正在使用这个类来使视图Modern-UICaliburn.Micro的模型第一种方法一起使用。

internal class ModernContentLoader : DefaultContentLoader
{
    protected override object LoadContent(Uri uri)
    {
        object content = base.LoadContent(uri);
        if (content == null)
            return null;

        // Locate the right viewmodel for this view
        object vm = ViewModelLocator.LocateForView(content);
        if (vm == null)
            return content;

        // Bind it up with CM magic
        if (content is DependencyObject)
            ViewModelBinder.Bind(vm, content as DependencyObject, null);

        return content;
    }
}

1 个答案:

答案 0 :(得分:9)

我去了Caliburn.Micro的源代码并调试了整个事情,就像我应该从一开始就做的那样。

事实证明,由于Modern-UI处理导航的方式,Conductor(除非它是附加到主窗口的主shell视图)不会被激活。换句话说,它永远不会知道它被显示并且Caliburn的来源检查以确保Conductor在允许激活新视图之前处于活动状态。由于某种原因,视图显示得很好,但View ModelScreen)永远不会被激活或实例化。在我的情况下,它是实例化的,因为Modern-UI + Caliburn.Micro视图绑定黑客。

我确实让它最终发挥作用,所以如果有人感兴趣,这就是ActivateItemConductorModern-UI内工作的方法。

将以下代码行添加到Conductor的构造函数或Modern-UI方法OnNavigatedTo

ScreenExtensions.TryActivate(this);

这是Caliburn-Micro的一部分,可让您的Conductor正确激活项目。如果您在OnNavigatedTo中使用它,则可能需要将此行添加到OnNavigatedFrom方法中:

ScreenExtensions.TryDeactivate(this, true);