如何使CM视图显示两个子视图中的一个,所有(包括父视图)绑定到同一视图模型?

时间:2014-01-09 02:48:43

标签: c# wpf mvvm caliburn.micro

我在 Caliburn Micro 项目中使用视图模型优先方法。

我有一个视图,比如,EmployeeSearchView,绑定到EmployeeSearchViewModel。它有一个内容区域,应该显示 网格或某些结果数据的列表视图。

可以公开子视图模型,例如EmployeeSearchResultsViewModel,并使用View.Context附加属性在EmployeeSearchResults.GridViewEmployeeSearchResults.ChildView之间进行选择。但是,我不想要额外的子视图模型;我需要显示的数据属性为EmployeeSearchViewModel

喜欢让我的子区域显示与其父视图绑定到同一视图模型的不同视图。可以这样做吗?我试过这个,插入EmployeeSearchView中的相关点:

<ContentControl cal:View.Model="{Binding}" cal:View.Context="{Binding Mode}" Grid.Row="1" />

我在“调试”窗格中看到错误:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Logical tree depth exceeded while traversing the tree. This could indicate a cycle in the tree.
   at System.Windows.FrameworkElement.FindResourceInTree(FrameworkElement feStart, FrameworkContentElement fceStart, DependencyProperty dp, Object resourceKey, Object unlinkedParent, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, DependencyObject boundaryElement, InheritanceBehavior& inheritanceBehavior, Object& source)
   at System.Windows.FrameworkElement.FindResourceInternal(FrameworkElement fe, FrameworkContentElement fce, DependencyProperty dp, Object resourceKey, Object unlinkedParent, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, DependencyObject boundaryElement, Boolean isImplicitStyleLookup, Object& source)
   at System.Windows.FrameworkElement.FindImplicitStyleResource(FrameworkElement fe, Object resourceKey, Object& source)

CM记录随后表明事情已正确连接,但视图不显示。

Info: Binding MyProject.Views.EmployeeSearchView and MyProject.ViewModels.EmployeeSearchViewModel.
Info: Attaching MyProject.Views.EmployeeSearchView to MyProject.ViewModels.EmployeeSearchViewModel.
Info: Binding MyProject.Views.EmployeeSearch.GridView and MyProject.ViewModels.EmployeeSearchViewModel.
Info: Setting DC of MyProject.Views.EmployeeSearch.GridView to MyProject.ViewModels.EmployeeSearchViewModel.
Info: Attaching message handler MyProject.ViewModels.EmployeeSearchViewModel to MyProject.Views.EmployeeSearch.GridView.

1 个答案:

答案 0 :(得分:1)

多么干净的想法,我之前没有考虑过像这样构图,而且听起来确实可能。我只是快速尝试使用测试项目,我能够得到你所追求的行为,基本上正是你所描述的。

快速浏览我使用的测试类/ XAML:

TestViewModel.cs

public class TestViewModel
{
    public string TestProperty { get; set; }
    public string AnotherTestProperty { get; set; }
    public string Mode { get; set; }

    public TestViewModel()
    {
        TestProperty = "A Testing String.";
        AnotherTestProperty = "Another Testing String";
        Mode = "Test"; // Hard Coded to my Test Context
    }
}

TestView.xaml

<UserControl x:Class="WpfApplication1.TestView"
         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:cal="http://www.caliburnproject.org"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <StackPanel>
        <TextBlock Text="This is the main TestViewModel I can bind to properties out here:"/>
        <TextBlock x:Name="TestProperty" />
        <TextBlock x:Name="AnotherTestProperty" />
        <ContentControl cal:View.Model="{Binding}" cal:View.Context="{Binding Mode}" Grid.Row="1" />
    </StackPanel>
</Grid>
</UserControl>

Test.xaml

<UserControl x:Class="WpfApplication1.Test.Test"
         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" 
         mc:Ignorable="d">
<Grid Background="#FF2BFB16">
    <StackPanel>
        <TextBlock Text="This is another View, It's also attached to the Test ViewModel."/>
        <TextBlock Text="I can bind to the same properties in here:" />
        <TextBlock x:Name="TestProperty" />
        <TextBlock x:Name="AnotherTestProperty" />
    </StackPanel>
</Grid>

产生这个(远非漂亮)结果:

enter image description here

我认为你走在正确的轨道上,我怀疑问题(基于错误消息)与ModeView的设计有关。如果我尝试指定不存在的Mode,我会遇到问题,因为快速测试会尝试对Mode的名称进行硬编码。

可能是你的Views之一试图将主EmployeeSearchView组成一个子节点,它本身包含另一个EmployeeSearchView视图,依此类推(View永远无法解析)本身)。