重用多个视图模型的视图

时间:2015-10-22 10:18:21

标签: c# .net wpf mvvm caliburn.micro

我希望在我的示例MyEntityEditViewModelMyEntityCreateViewModel中重复使用2个不同视图模型的视图。该视图基本上只是一个带有Save按钮的表单,因此非常常见的布局。

我创建了两个视图模型以及父视图/视图模型(MyEntitySummaryViewModel),现在我想使用ContentControl定义表单视图

摘要视图

<ContentControl x:Name="ActiveItem" cal:View.Model="{Binding ActiveItem}" cal:View.Context="MyEntityDetailView" />

MyEntitySummaryViewModel

public MyEntity SelectedEntity {
    get { return _selectedEntity; }
    set {
        _selectedEntity = value;
        NotifyOfPropertyChange();

        ActivateItem(new MyEntityEditViewModel(_selectedEntitity));
    }
}

public void Create() {
    ActivateItem(new MyEntityCreateViewModel(new MyEntity()));
}

我现在的问题是,Caliburn试图找到一个&#39; MyEntityEditView&#39;由于它的视图定位约定,即使我严格将ContentControl的上下文定义为自定义视图。有没有解决的办法?或者我在这里做错了什么?

2 个答案:

答案 0 :(得分:0)

如果我的理解是正确的,您希望2种类型的ViewModel指向同一视图。如果是这样,juste为您的Entity(EntityBaseViewModel)创建一个base classe并创建一个View(EntityBaseView)。

绑定ContentControl设置其x:Name,使其名称与您的ViewModel的属性相匹配。

示例:

查看(ShellView):

<ContentControl x:Name="SelectedEntity"/>

ViewModel(ShellViewModel):

public EntityBaseViewModel  SelectedEntity 
{
    get 
    { 
        return this._selectedEntity; 
    }
    set 
    {
        this._selectedEntity = value;
        this.NotifyOfPropertyChange(() => SelectedEntity);
    }
}

如果你按照你所说的命名惯例创建了ViewModel / View,Caliburn会找到ViewModel的View并绑定DataContext。

答案 1 :(得分:0)

参加聚会有点晚,但这也许会对某人有所帮助。这部影片对我很有帮助-(Tim Corey, WPF and Caliburn with MVVM)

使用您提到的指向ActiveItem的控件设置ShellView,可以使该控件显示您从ShellViewModel代码告诉它的任何视图。我还在该项目中使用了Fody,因此可以处理更改通知,因此您不会在代码中看到这些通知。

ShellView-

<Button x:Name="LoadMainPage" />    
<Button x:Name="LoadSecondPage" />
<ContentControl x:Name="ActiveItem"/>

ShellViewModel-

public class ShellViewModel : Conductor<object>.Collection.OneActive
{       
        public MainPageViewModel MainPageVM = new MainPageViewModel();
        public SecondPageViewModel SecondPageVM = new SecondPageViewModel();

        public ShellViewModel()
        {           
            LoadMainPage(); // auto load main page on startup
        }

        public void LoadMainPage()
        {
            ActivateItem(MainPageVM);
        }

        public void LoadSecondPage()
        {
            ActivateItem(SecondPageVM);
        }
}

使用ActivateItem时,无需创建ViewModel的新实例,而只是重新使用创建的初始实例。或者,如果您确实希望每次启动该特定视图时都创建另一个实例,则只需使用已有的ActivateItem。

在您的SecondPageViewModel中查看该视图,它将占用ActiveControl的ContentControl中的空间-

public class SecondPageViewModel : Screen

SecondPageView.xaml添加为用户控件(以及您要创建的任何其他子视图/子视图)-

<UserControl x:Class="MyNamespace.Views.SecondPageView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyNamespace.Views"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>

    </Grid>
</UserControl>

这将允许您在基本视图/视图模型中所需的任何视图之间来回切换,并显示在ContentControl框中选择的子视图(无论需要多少个)的内容。