Click here to Skip to main content
15,895,084 members
Articles / Desktop Programming / WPF

Persist the Visual Tree when switching tabs in the WPF TabControl

Rate me:
Please Sign up or sign in to vote.
4.76/5 (14 votes)
16 Jun 2011CPOL5 min read 85.4K   3.1K   32  
Using attached behavior pattern to create a tab persist TabControl in WPF when ViewModel is used.
<Window x:Class="PersistTabDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:PersistTabDemo.ViewModel"
        xmlns:c="clr-namespace:PersistTabDemo"
        xmlns:b="clr-namespace:PersistTabDemo.Behavior"
        WindowState="Maximized"
        Title="MainWindow">
    
    <Window.Resources>

        <!-- Ref: http://msdn.microsoft.com/en-us/library/ms752032(v=VS.90).aspx -->
        <LinearGradientBrush x:Key="LightBrush" StartPoint="0,0" EndPoint="0,1">
            <GradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Color="#FFF" Offset="0.0"/>
                    <GradientStop Color="#EEE" Offset="1.0"/>
                </GradientStopCollection>
            </GradientBrush.GradientStops>
        </LinearGradientBrush>

        <SolidColorBrush x:Key="SolidBorderBrush" Color="#888" />
        <SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />
        <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />
        <SolidColorBrush x:Key="DisabledBorderBrush" Color="#AAA" />
        <SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />

        <Style x:Key="PersistTabItemStyle" TargetType="{x:Type TabItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Grid>
                            <Border 
            Name="Border"
            Margin="0,0,-4,0" 
            Background="{StaticResource LightBrush}"
            BorderBrush="{StaticResource SolidBorderBrush}" 
            BorderThickness="1,1,1,1" 
            CornerRadius="2,12,0,0" >
                                <ContentPresenter x:Name="ContentSite"
              VerticalAlignment="Center"
              HorizontalAlignment="Center"
              Content="{Binding Header}"
              Margin="12,2,12,2"
              RecognizesAccessKey="True"/>
                            </Border>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="Panel.ZIndex" Value="100" />
                                <Setter TargetName="Border" Property="Background" Value="{StaticResource WindowBackgroundBrush}" />
                                <Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0" />
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />
                                <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" />
                                <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>


        <DataTemplate DataType="{x:Type vm:TabPageViewModel}">
            <c:DataGridControl />
        </DataTemplate>
        
        <DataTemplate x:Key="templateForTheHeader" DataType="{x:Type vm:TabPageViewModel}">
            <TextBlock Text="{Binding Header}" />
        </DataTemplate>
        
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="25" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal">

            <TextBlock VerticalAlignment="Center">Selected Page:</TextBlock>
            
            <TextBlock 
                VerticalAlignment="Center"
                Margin="5,0,0,0" 
                DataContext="{Binding Tab2}" 
                FontWeight="Bold" 
                Text="{Binding SelectedPage.Header}" />
            
            <Button 
                Margin="20,0,0,0"
                Content="Add Page"
                Width="80"
                DataContext="{Binding Tab2}"
                Command="{Binding AddPageCommand}" />

            <Button
                Margin="20, 0, 0, 0"
                Content="Remove Page"
                Width="80"
                DataContext="{Binding Tab2}"
                Command="{Binding RemovePageCommand}" />
            
        </StackPanel>
        
        <TabControl 
            Grid.Row="1"
            DataContext="{Binding Tab2}"
            b:PersistTabBehavior.ItemsSource="{Binding Pages}"
            b:PersistTabBehavior.SelectedItem="{Binding SelectedPage}"
            ItemContainerStyle="{StaticResource PersistTabItemStyle}"
            />

        <TabControl 
            Grid.Row="2"
            DataContext="{Binding Tab1}"
            ItemsSource="{Binding Pages}"
            SelectedItem="{Binding SelectedPage}"
            ItemTemplate="{StaticResource templateForTheHeader}"
            />
    </Grid>
</Window>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Fidelity
Hong Kong Hong Kong
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions