如何解析内容展示者不显示View?

时间:2015-12-01 14:02:04

标签: wpf mvvm datatemplate tabcontrol contentpresenter

我在TabControl的数据模板中添加了一个内容展示器,以便显示正确的视图。

但是当我加载应用程序时,标签会显示,但它们没有用户控件内容。

我用Google搜索了错误并遇到了这个solution,这表明数据上下文出错,但我的AppVM和AppView中的设置似乎没问题。

我在AppView中引用的VM和视图的名称也是正确的。

有没有人知道这里的设置出错了?

这是包含两个视图的ApplicationView:

<Window x:Class="MongoDBApp.Views.ApplicationView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:views="clr-namespace:MongoDBApp.Views"
        xmlns:vm="clr-namespace:MongoDBApp.ViewModels"
        Title="ApplicationView"
        Width="800"
        Height="500">

    <Window.Resources>
        <DataTemplate DataType="{x:Type vm:CustomerDetailsViewModel}">
            <views:CustomerDetailsView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type vm:CustomerOrdersViewModel}">
            <views:CustomerOrdersView />
        </DataTemplate>
    </Window.Resources>

    <Window.DataContext>
        <vm:ApplicationViewModel />
    </Window.DataContext>


    <TabControl ItemsSource="{Binding PageViewModels}" TabStripPlacement="Top">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" />
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate>
                <ContentPresenter Content="{Binding CurrentPageViewModel}" />
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
</Window>

ApplicationViewModel构造函数和相关字段:

private ICommand _changePageCommand;
private IPageViewModel _currentPageViewModel;
private List<IPageViewModel> _pageViewModels;
private static ICustomerDataService customerDataService = new CustomerDataService(CustomerRepository.Instance);




#endregion

/// <summary>
/// Initializes a new instance of the <see cref="ApplicationViewModel"/> class.
/// </summary>
public ApplicationViewModel()
{
    // Add available pages
    PageViewModels.Add(new CustomerDetailsViewModel(customerDataService));
    PageViewModels.Add(new CustomerOrdersViewModel());

    // Set starting page
    CurrentPageViewModel = PageViewModels[0];
}

2 个答案:

答案 0 :(得分:3)

ContentTemplate属性包装Content对象。

例如,使用您的代码,您将.Content属性设置为CustomerDetailsViewModel对象,并尝试绑定到该对象的CurrentPageViewModel,该对象不存在

渲染的内容是:

<TabControl>
    <TabItem>
        <ContentPresenter Content=CustomerDetailsViewModel>
            <ContentPresenter Content="{Binding CurrentPageViewModel}" />
        </ContentPresenter>
    </TabItem>
    <TabItem>
        <ContentPresenter Content=CustomerOrdersViewModel>
            <ContentPresenter Content="{Binding CurrentPageViewModel}" />
        </ContentPresenter>
    </TabItem>
</TabControl>

因为TabControl会自动生成ContentPresenter以包裹每个.Content的{​​{1}},所以您根本不需要此模板。

但听起来你真正想要的是绑定TabControl的TabItem属性

SelectedItem

答案 1 :(得分:0)

我们通常不会在ContentPresenter之外使用ControlTemplate,而且肯定不会像您在DataTemplate中那样......使用ContentPresenter将使WPF框架搜索与DataTemplate的类型匹配的Content,因此在您的情况下,您将最终获得无限循环。相反,您应该将关联的视图放在DataTemplate

<DataTemplate DataType="{x:Type YourDataXamlPrefix:CurrentPageViewModel}">
    <YourUiXamlPrefix:YourView DataContext="{Binding CurrentPageViewModel}" />
</DataTemplate>

通过这种方式,当框架遇到集合中的视图模型类时,它将找到此DataTemplate并呈现相关视图。