WPF TabControl with ContentControl

2019-04-11 20:59发布

I have searched a lot on SO and didn't find answer to my problems. I want to use TabControl with MVVM. Here is how I add TabControl to MainWindow.xaml

<Window.Resources>
        <DataTemplate DataType="{x:Type models:PartnersViewModel}">
            <views:PartnersView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type models:ProjectsViewModel}">
            <views:ProjectsView />
        </DataTemplate>
    </Window.Resources>

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

    <TabControl ItemsSource="{Binding PageViewModels}"  TabStripPlacement="Left">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" />
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate>
                <ContentControl Content="{Binding}" />
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>

PageViewModels is ObservableCollection<IPageViewModel>. IPageViewModel is simple interface with one property Name. There are 2 implementation of this interface PartnersViewModel and ProjectsViewModel.

public class ProjectsViewModel : IPageViewModel
{
    public String Name
    {
        get { return "Projects"; }
    }
}

public class PartnersViewModel : IPageViewModel
{
    public String Name
    {
        get { return "Partners"; }
    }
}

I want each tab to be displayed as ContentControl. Header text is taken from Name property. My ProjectsView and PartnersView looks like this:

<UserControl x:Class="WANIRPartners.Views.ProjectsView"
         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" >
  <Grid>
    <Label Content="Projects Content" />
  </Grid>
</UserControl>

Using this code, header and content in TabControl is exactly the same. 'Projects Content'/'Partners Content' are shown in tab headers and also(this is ok) in tab content. When I change <Label/> to <DataGrid/> tab headers contains datagrid (sic!). How can I get this working properly. I mean how can I display headers as value of property Name and tab content as properly rendered <views:PartnersView /> or <views:ProjectsView /> depending on what is in PageViewModels.

2条回答
Anthone
2楼-- · 2019-04-11 21:20

I have discovered solution for Elysium. Adding fter adding code belowe everything work fine.

 <TabControl.Resources>
     <Style TargetType="{x:Type TabItem}" BasedOn="{StaticResource {x:Type TabItem}}">
         <Setter Property="Header" Value="{Binding Name}"/>
     </Style>
 </TabControl.Resources>
查看更多
该账号已被封号
3楼-- · 2019-04-11 21:25

your code should work, dont have a IDE atm. you can also use Snoop to check your bindings at runtime. i changed the ContentTemplate to:

    <TabControl.ContentTemplate>
        <DataTemplate>
            <ContentPresenter Content="{Binding .}" />
        </DataTemplate>
    </TabControl.ContentTemplate>

and it works. but even your code works in my testapp.

查看更多
登录 后发表回答