1

我是 Caliburn.Micro 的新手(以及 MVVM),我正在尝试通过ShellViewModel子视图模型中的按钮(由指挥者调用的按钮)激活一个屏幕,其中指挥者位于其中。我见过的所有教程都有在实际外壳中切换的按钮,所以我有点迷茫。

所有 ViewModel 共享命名空间SafetyTraining.ViewModels

(第ShellViewModel 一次使用外壳,所以我可能以错误的方式使用它)

public class ShellViewModel : Conductor<object>.Collection.OneActive, IHaveDisplayName
{        
    public ShellViewModel()
    {
        ShowMainView();
    }

    public void ShowMainView()
    {
        ActivateItem(new MainViewModel());
    }
}

ShellViewXAML

<UserControl x:Class="SafetyTraining.Views.ShellView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DockPanel>
    <ContentControl x:Name="ActiveItem" />
</DockPanel>

MainViewModel- 主屏幕(正确显示)。

public class MainViewModel : Screen
{
    public void ShowLoginPrompt()
    {
        LoginPromptViewModel lg = new LoginPromptViewModel();//This does happen
    }
}

MainViewXAML

<Button cal:Message.Attach="[Event Click] = [ShowLoginPrompt]">Login</Button> 

LoginPromptViewModel

public class LoginPromptViewModel : Screen
{
    protected override void OnActivate()
    {
        base.OnActivate();
        MessageBox.Show("Hi");//This is for testing - currently doesn't display
    }
}

编辑工作代码:

稍微修改了 Sniffer 的代码以适合我的结构。谢谢 :)

var parentConductor = (Conductor<object>.Collection.OneActive)(this.Parent);
        parentConductor.ActivateItem(new LoginPromptViewModel());
4

1 回答 1

2

你做的一切都是正确的,但你错过了一件事:

public void ShowLoginPrompt()
{
    LoginPromptViewModel lg = new LoginPromptViewModel();//This does happen
}

您正在创建 的实例LoginPromptViewModel,但您没有告诉指挥员激活此实例,因此OnActivate()永远不会调用它的方法。

现在,在我给你一个解决方案之前,我应该建议几件事:

  1. 如果您使用MainViewModel来在不同的视图模型之间导航,那么自己制作MainViewModel一个导体是合适的。

  2. 如果您不那样使用它,那么也许您应该将导航到的按钮放在LoginPromptViewModel本身中ShellView

现在回到你的问题,因为你的MainViewModel扩展Screen那么它有一个Parent引用导体的属性,所以你可以这样做:

public void ShowLoginPrompt()
{
    LoginPromptViewModel lg = new LoginPromptViewModel();//This does happen
    var parentConductor = (Conductor)(lg.Parent);
    parentConductor.Activate(lg);
}
于 2013-10-14T16:28:44.533 回答