2010-06-09 47 views
4

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

我可以做的一个方法是为每个项目提供单个视图和视图模型。现在基于某些条件,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风格

+0

这是我的帖子“[使用MVVM - - contenttemplateselector式标签控制视图(HTTP://jacobaloysious.wordpress。 com/2013/08/19/mvvm-using-contenttemplateselector-in-tab-control-view /)“,在一个类似的情况下,使用一个工作示例项目。可能对某人有帮助,因为我很难加入结尾:)。 – 2013-08-19 14:26:37

回答

6

添加ContentTemplateSelector到ContentPresenter您是否尝试过使用DataTemplateSelectors解决?

基本上,您在主视图模型中发布了一个较小的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> 
+0

谢谢哥布林。当我有两个差异视图但是视图模型相同,即共享视图模型场景时,我该如何实现这一点? – byte 2010-06-09 14:37:36

+0

只需将视图插入到配件DataTemplate(FirstTemplate vs SecondTemplate。 – Goblin 2010-06-09 19:46:56

+0

Goblin,我明白你在说什么,但对Wpf和模板是新手,如果你可以给出一个小代码示例或参考某篇文章,这将会有所帮助 – byte 2010-06-10 08:52:56

8

为每个视图创建一个数据模板。实现一个DataTemplateSelector类,它给出一个项目返回正确的数据模板。如果项目的集合称为项目的XAML会是这个样子

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

对不起,我没有评论你的帖子。我很感激你的回复,并且已经投了你的回复。 – byte 2010-06-10 09:55:48