View集合中的TabItems

时间:2010-06-09 11:41:44

标签: wpf mvvm tabcontrol

我正在使用MVVM。我有一个标签控件。我将收集一些物品。我想在集合中显示每个项目作为选项卡项。每个选项卡项中的视图都不同,可能有自己的视图模型。我该如何实现这一目标? 例如。我有3件物品。选项卡项模板包含ItemControl。我想现在创建了3个Tabs,每个tabitem中的ItemControls可能会显示不同的视图。

我能做的一种方法是为每个项目提供单一视图和视图模型。现在,基于某些条件,View将显示不同的UI元素,并且行为方式不同。但我担心这会使观点在一段时间内变得相当复杂。

编辑:下面的Goblin解决方案运行正常,但是当应用于TabControl的自定义样式时我遇到了问题。

<Style x:Key="TabControlStyle" TargetType="{x:Type TabControl}">
<Setter Property="Template">
  <Setter.Value>
     <ControlTemplate TargetType="TabControl">
      <Grid>
         <Grid.ColumnDefinitions>
            <ColumnDefinition/> <ColumnDefinition />
         </Grid.ColumnDefinitions>
         <Grid.RowDefinitions>
            <RowDefinition Height="Auto" Name="RowDefinition0" />
            <RowDefinition Height="*" Name="RowDefinition1" />
         </Grid.RowDefinitions>
         <TabPanel Grid.Column="0" Grid.Row="0" />
         <Border Grid.Column="0" Grid.Row="1">
             <ContentPresenter Content="{TemplateBinding TabControl.SelectedContent}" ContentTemplate="{TemplateBinding TabControl.SelectedContentTemplate}" ContentStringFormat="{TemplateBinding TabControl.SelectedContentStringFormat}" ContentSource="SelectedContent" Name="PART_SelectedContentHost" Margin="{TemplateBinding Control.Padding}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
          </Border>
          </Grid>
          <ControlTemplate.Triggers>

编辑:这已通过在上面的TabControl样式中将ContentTemplateSelector添加到ContentPresenter来解决

2 个答案:

答案 0 :(得分:8)

为每个视图创建一个datatemplate。实现一个DataTemplateSelector类,它给出一个项返回正确的datatemplate。如果项目集合被称为项目,您的xaml将看起来像这样

<TabControl 
    ItemsSource="{Binding Path=Items}"
    ContentTemplateSelector="{StaticResource MyTemplateSelector}" />

答案 1 :(得分:6)

您是否尝试过使用DataTemplateSelectors?

基本上,您在主ViewModel中发布了一组较小的ViewModel - 然后在DataTemplateSelector中根据ViewModel的类型选择模板?

<UserControl.Resources>
    <DataTemplate x:Key="HeaderTemplate">
        <TextBlock Text="CMR"/>
    </DataTemplate>
    <DataTemplate x:Key="FirstTemplate">
        <local:FirstView/>
    </DataTemplate>
    <DataTemplate x:Key="SecondTemplate">
        <lcoal:SecondView/>
    </DataTemplate>
    <local:TemplateSelector x:Key="TemplateSelector" FirstTypeTemplate="{StaticResource FirstTemplate}" SecondTypeTemplate={StaticResource SecondTemplate}/>
</UserControl.Resources>
<TabControl ItemsSource="{Binding SmallerViewModels}" ContentTemplateSelector="{StaticResource TemplateSelector}" ItemTemplate="{StaticResource HeaderTemplate}">

在代码隐藏中:

public class TemplateSelector:DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if(item.GetType() == typeof(FirstViewModel)
            return FirstTypeTemplate
        return SecondTypeTemplate;
    }
    public DataTemplate FirstTypeTemplate { get; set; }
    public DataTemplate SecondTypeTemplate { get; set; }
}

编辑: 的的ViewModels:

public class SharedViewModel
{
    public SharedViewModel()
    {
        SmallerViewModels = new List<ISmallViewModel>();
        SmallerViewModels.Add(new FirstViewModel());
        SmallerViewModels.Add(new SecondViewModel());
    }
    public IList<ISmallViewModel> SmallerViewModels{get;private set;}
}
public interface ISmallViewModel{}
public class FirstViewModel:ISmallViewModel
{
    public string FirstDescription
    {
        get{return "My first ViewModel";}
    }
}
public class SecondViewModel:ISmallViewModel
{
    public string SecondDescription
    {
        get{return "My second ViewModel";}
    }
}

<强>视图

<UserControl  .... x:Class="...FirstView">
    <TextBlock Text="{Binding FirstDescription}"
</UserControl>
<UserControl  .... x:Class="...SecondView">
    <TextBlock Text="{Binding SecondDescription}"
</UserControl>