WPF Caliburn Micro:使用ContentControl

时间:2015-05-15 10:17:31

标签: wpf user-controls caliburn.micro contentcontrol

此问题与Add a usercontrol to caliburm micro dynamically有关。 在打开这个新主题之前,我已经阅读过任何其他相关主题,但我仍然不理解并找不到解决方案。如果你们中的一些人认为这是重复的话,请接受我的道歉。

我有一个窗口(MainView)包含" main"网格(又名LayoutRoot)有2列。

在左栏上有2个按钮:"显示视图1"和"显示视图2"。

  • 如果用户点击"显示视图1"," Display1View" (是一个UserControl包含TextBlock with Text" View 1")应显示在右栏中,替换当前列。
  • 如果用户点击"显示视图2"," Display2View" (是一个UserControl包含TextBlock with Text" View 2")应显示在右栏上,替换当前列。

我的示例代码包含以下视图和视图模型:

  • MainView.xaml和MainViewModel.cs
  • Display1View.xaml和Display1ViewModel.cs
  • Display2View.xaml和Display2ViewModel.cs

在我的示例代码中,ContentControl无法识别UserControl。我究竟做错了什么?如何正确绑定ContentControl?请随意修改我的示例代码。提前谢谢

MainView.xaml

<Window x:Class="TestCaliMiContentControl.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Main View"
    Width="525"
    Height="350">
    <Grid x:Name="LayoutRoot" ShowGridLines="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="30*" />
            <ColumnDefinition Width="100*" />
        </Grid.ColumnDefinitions>
        <StackPanel x:Name="LeftNavPanel" Grid.Column="0">
            <Button x:Name="Display1" Content="Display View 1" />
            <Button x:Name="Display2" Content="Display View 2" />
        </StackPanel>
        <ContentControl x:Name="MainGridContent" Grid.Column="1" />
    </Grid>
</Window>

MainViewModel.cs

public class MainViewModel : PropertyChangedBase
{
    private ContentControl _mainGridContent;
    public ContentControl MainGridContent
    {
        get { return _mainGridContent; }
        set
        {
            _mainGridContent = value;
            NotifyOfPropertyChange(() => MainGridContent);
        }
    }

    public void Display1()
    {
        //MainGridContent = new Display1ViewModel(); // cannot convert source type error
    }

    public void Display2()
    {
        // MainGridContent = new Display2ViewModel(); // cannot convert source type error          
    }
}

Display1View.xaml

<UserControl x:Class="TestCaliMiContentControl.Display1View"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         d:DesignHeight="300"
         d:DesignWidth="300"
         mc:Ignorable="d">
    <Grid>
        <TextBlock HorizontalAlignment="Center" FontSize="72" 
                   Text="View 1"/>
     </Grid>
</UserControl>

Display1ViewModel.cs

using System;
using System.Windows.Controls;
using Caliburn.Micro;

namespace TestCaliMiContentControl
{
    public class Display1ViewModel : PropertyChangedBase {}
}

1 个答案:

答案 0 :(得分:5)

首先,我首先建议您阅读Caliburn.Micro文档,特别是有关屏幕,指挥和构图的部分:http://caliburnmicro.com/documentation/composition

话虽这么说,我们可以修改您的代码以使其正常工作。

1)由于你的MainViewModel应该开展其他项目,因此它应该来自Conductor<T>。在这种情况下,我们会让它进行Caliburn Screen课程。

public class MainViewModel : Conductor<Screen>

2)在MVVM中,您查看模型应该不了解您的视图。您不应该看到ContentControl等UI类。我们可以将您的属性更改为Screen类型,但实际上我们根本不需要该属性,因为我们使用的是指挥。因此,请删除MainGridContent属性和支持字段。

3)在Display1Display2方法中,调用Caliburn的指挥方法ActivateItem以显示相应的项目。

public void Display1()
{
    ActivateItem(new Display1ViewModel());
}

4)在您的MainView.xaml中,您需要将ContentControl绑定到指挥的有效商品属性,按惯例,ActiveItem

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

5)最后,由于你的指挥正在进行Screen,你需要制作它们。屏幕很有用,因为它们具有生命周期并允许您知道它们何时被激活/停用。对Display1和Display2执行此操作。

public class Display1ViewModel : Screen {}

这应该让你起步并运行。