TabItems из коллекции View - PullRequest
       3

TabItems из коллекции View

4 голосов
/ 09 июня 2010

Я использую MVVM.У меня есть вкладка управления.У меня будет коллекция предметов.Я хочу отобразить каждый из этого элемента в коллекции как элемент вкладки.Представление в каждом элементе вкладки отличается и может иметь свою собственную модель представления.Как мне этого добиться?Например, у меня есть 3 предмета в коллекции.Шаблон элемента Tab содержит ItemControl.Теперь я хотел бы создать 3 вкладки, и элементы управления ItemControls внутри каждой вкладки могут отображать различные представления.

Один из способов, который я мог бы сделать, - это создать по одному представлению и модели представления для каждого элемента.Теперь в зависимости от некоторых условий представление будет отображать различные элементы интерфейса и вести себя по-разному.Но я боюсь, что это сделает представление довольно сложным в течение определенного периода времени.

Редактировать: приведенное ниже решение Гоблина работает нормально, но у меня есть проблема, когда пользовательский стиль применяется к 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>

РЕДАКТИРОВАТЬ: Это было решено путем добавления ContentTemplateSelector к ContentPresenter в вышеуказанном стиле TabControl

Ответы [ 2 ]

8 голосов
/ 09 июня 2010

Создание таблицы данных для каждого вида.Реализуйте класс DataTemplateSelector, который для данного элемента возвращает правильный шаблон данных.Если коллекция предметов называется Items, ваш xaml будет выглядеть примерно так:

<TabControl 
    ItemsSource="{Binding Path=Items}"
    ContentTemplateSelector="{StaticResource MyTemplateSelector}" />
6 голосов
/ 09 июня 2010

Вы пытались использовать 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; }
}

EDIT: 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>
...