2010-06-09 51 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