Wednesday, November 25, 2015

Create dynamic Tab Item with different User control using WPF MVVM in 5 steps

To create tab item dynamically with different user control using WPF MVVM, we need to follow below steps :
1. Create ITabViewModel Interface :

    public interface ITabViewModel
    {
        String Header { get; set; }
    }
2. Create three View model as follows :
 
   // ViewModelA

   public  class ViewModelA:ITabViewModel
    {
      public string Header { get; set; }
      public ViewModelA()
       {  
       }
    }

  // ViewModelB

   public  class ViewModelB:ITabViewModel
    {
      public string Header { get; set; }
      public ViewModelB()
       {  
       }
    }

  // ViewModelC

   public  class ViewModelC:ITabViewModel
    {
      public string Header { get; set; }
      public ViewModelC()
       {  
       }
    }
3. Create three user control like :

// First user control ViewAUserControl.xaml

          <UserControl x:Class="WPFTestApp.View.ViewAUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Button Content="A" Height="30" Width="100"></Button>
    </Grid>
</UserControl>

// Second user control ViewBUserControl.xaml

         <UserControl x:Class="WPFTestApp.View.ViewBUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Button Content="B" Height="30" Width="100"></Button>
    </Grid>
</UserControl>


// Third user control ViewCUserControl.xaml

        <UserControl x:Class="WPFTestApp.View.ViewCUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Button Content="C" Height="30" Width="100"></Button>
    </Grid>
</UserControl>

4. Create TabViewModel to use with Tab Window as follows :

    public class TabViewModel
    {
        public ObservableCollection TabViewModels { get; set; }

        public TabViewModel()
        {
            TabViewModels = new ObservableCollection();
            TabViewModels.Add(new ViewModelA { Header = "Tab A" });
            TabViewModels.Add(new ViewModelB { Header = "Tab B" });
            TabViewModels.Add(new ViewModelC { Header = "Tab C" });

        }
    }
5. Create one Tab Window to use user control code look like :

        <Window x:Class="WPFTestApp.View.TabWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:WPFTestApp.View"
        xmlns:vm="clr-namespace:WPFTestApp.ViewModel"
        Title="TabWindow" Height="300" Width="300">
    <Grid>
        <Grid.Resources>
            <vm:TabViewModel x:Key="TabVM"></vm:TabViewModel>
        </Grid.Resources>
       <TabControl x:Name="MyTabControl"
            ItemsSource="{Binding TabViewModels}" DataContext="{StaticResource TabVM}"
           SelectedItem="{Binding SelectedTabViewModel}" >

            <TabControl.Resources>
                <DataTemplate DataType="{x:Type vm:ViewModelA}">
                    <my:ViewAUserControl />
                </DataTemplate>
                <DataTemplate DataType="{x:Type vm:ViewModelB}">
                    <my:ViewBUserControl />
                </DataTemplate>
                <DataTemplate DataType="{x:Type vm:ViewModelC}">
                    <my:ViewCUserControl />
                </DataTemplate>
            </TabControl.Resources>

            <TabControl.ItemContainerStyle>
                <Style TargetType="TabItem">
                    <Setter Property="Header" Value="{Binding Header}" />
                </Style>
            </TabControl.ItemContainerStyle>

        </TabControl>
    </Grid>
</Window>
     

Here we are using data template to add different view model.

Output will look like :