0
votes

I'm new in WPF and try learn VMMV. I try to create TabControl with template for content in xaml. I want tabitem with content of grid and in grid list of usercontrols. After adding a usercontrol the header of tabitem render right but nothing is in content. What is wrong?

This is my xaml:

<TabControl ItemsSource="{Binding Items}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Visibility="Hidden" Name="tcContent" Grid.Column="1" Grid.Row="0">
   <TabControl.ItemTemplate>
      <DataTemplate>
         <TextBlock Text="{Binding Header}" />
      </DataTemplate>
   </TabControl.ItemTemplate>
   <TabControl.ContentTemplate>
      <DataTemplate>
         <ContentControl Content="{Binding Content}" />
      </DataTemplate>
   </TabControl.ContentTemplate>
</TabControl>

Viewmodel:

public class Tab
{
    public string Header { get; set; }
    public ObservableCollection<UserControl> Content { get; set; }
}

public class MainWindowsViewModel
{        
    ObservableCollection<Tab> _items = new ObservableCollection<Tab>();

    public ObservableCollection<Tab> Items
    {
         get
         {
              return _items;
         }
    }       
}

Behind code for fill tabcontrol:

public MainWindow()
{ 
     this.DataContext = new MainWindowsViewModel();
}

public void AddToTab(string header, UserControl c)
{
     Tab tab = new Tab();
     tab.Header = header;
     tab.Content = new ObservableCollection<UserControl>();
     tab.Content.Add(c);

     ((MainWindowsViewModel)this.DataContext).Items.Add(tab);
}
2

2 Answers

3
votes

You are misunderstanding the MVVM principle.

In your view-model, you have a collection of the Tab objects, and each of them holds a collection of UserControls. In this way, your view-model contains some view elements (UserControls). In MVVM, you shouldn't do that.

Instead, you create the view-models for each tab item that describe a model of the representation (hence view-model); and in XAML, you describe how do these view-models should look like using DataTemplates.

But this is all required only if your views have to be dynamic. E.g. you don't know which data will be available because you're fetching them from a database.

If your TabItems display a set of UserControls that won't change, then just describe your view completely in XAML, without any DataTemplates.

2
votes

Firstly, remove Visibility="Hidden" form the TabControl. Then change the ControlControl to ItemsControl which can hold Tab.Content, which is a collection. However, you should pay attention to the problems mentioned in @dymanoid's answer.

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