从另一个ViewModel设置Caliburn.Micro ControlContent

时间:2013-10-14 14:08:29

标签: c# wpf caliburn.micro

我是Caliburn.Micro (以及MVVM)的新手,我正在尝试使用位于ShellViewModel内的导体从子内的按钮激活一个屏幕-viewmodel(由指挥家召集的一个)。我见过的所有教程都在实际shell中有按钮切换,所以我有点迷失。

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

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

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

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

ShellView XAML

<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
    }
}

MainView XAML

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

1 个答案:

答案 0 :(得分:1)

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

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

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

在我给你解决方案之前,我应该提出几点建议:

  1. 如果您使用MainViewModel在不同的视图模型之间导航,那么将MainViewModel作为指挥本身是合适的。

  2. 如果你没有那样使用它,那么也许你应该将导航的按钮放在LoginPromptViewModel本身的ShellView

  3. 现在回到你的问题,因为你的MainViewModel扩展Screen然后它有一个Parent属性引用指挥,所以你可以这样做:

    public void ShowLoginPrompt()
    {
        LoginPromptViewModel lg = new LoginPromptViewModel();//This does happen
        var parentConductor = (Conductor)(lg.Parent);
        parentConductor.Activate(lg);
    }