Note that there are some explanatory texts on larger screens.

plurals
  1. POStop ContentTemplate Selector invoke on TabControl selection change event
    primarykey
    data
    text
    <p>I have a TabControl. Each tab Item i.e newly added Tab is rendered using content template selector. But each time i switch between the tabs, content template selector is getting called. </p> <p>I wanted to stop this. This is because, In the in Tabcontrol, User have provided actions to change the layout, since in the selection change event of the tab Item content template is getting called, it is getting difficult for me to retain the layout what user has changed during Tab Item Selection change Event.</p> <p>Following is code i am using for the TabControl</p> <pre><code> &lt;TabControl Grid.Column="2" x:Name="MainTabControl" HorizontalAlignment="Stretch" Margin="0,12,0,7" SelectedItem="{Binding SelectedTabItem}" Visibility="{Binding TabsVisible}" ItemsSource="{Binding ToolsList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" ItemTemplate="{StaticResource ToolDisplayDataTemplate}" commands:FrameworkUICommandList.TabItemChangedCommand="{Binding Path=TabItemChangedCommand}" &gt; &lt;TabControl.ContentTemplate&gt; &lt;DataTemplate&gt; &lt;ContentControl Content="{Binding}" ContentTemplateSelector="{DynamicResource toolTabDataItemTemplateSelector}"/&gt; &lt;/DataTemplate&gt; &lt;/TabControl.ContentTemplate&gt; &lt;TabControl.ItemContainerStyle&gt; &lt;Style TargetType="TabItem" BasedOn="{StaticResource TabItemStyle}"&gt; &lt;Setter Property="AutomationProperties.AutomationId" Value="{Binding ToolID}" /&gt; &lt;Setter Property="ToolTip" Value="{Binding ToolID,Converter={StaticResource ResourceKey=tabItemTooltipConverter}}"/&gt; &lt;/Style&gt; &lt;/TabControl.ItemContainerStyle&gt; &lt;/TabControl&gt; </code></pre> <p>UPDATE : I have created a sample project to explain my problem. Could not share the project anywhere, so updating the code snippet in main question. sorry for that.</p> <p>In the sample project, user can add TabItem dynamically to TabControl. Eash Tabcontent can show two Grid panel and they are separated by Grid Splitter. Display of second grid is Based on some flag (in this example ShowSecondPanel). If user click on "Show / Hide Second Panel" button, then second panel content will be shown for the current selected tab. </p> <p>The Problem is, user can re-size the panels using Grid Splitter, but when user navigates to some other tab and comes back to previous one, the grid splitter position changes to original position.</p> <p>Hope I am clear on describing the problem.</p> <p>Code for MainWindow.xaml</p> <pre><code> &lt;Window x:Class="TabControlTestApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:TabControlTestApp" Title="MainWindow" Height="500" Width="700"&gt; &lt;Window.DataContext&gt; &lt;local:MainWindowViewModel /&gt; &lt;/Window.DataContext&gt; &lt;Window.Resources&gt; &lt;local:TabContentTemplateSelector x:Key="tabContentTemplateSelector" /&gt; &lt;DataTemplate x:Key="TabitemDataTemplate"&gt; &lt;StackPanel Width="50" Height="50"&gt; &lt;TextBlock Text="{Binding TabFirstPanel.Name}"&gt;&lt;/TextBlock&gt; &lt;/StackPanel&gt; &lt;/DataTemplate&gt; &lt;DataTemplate x:Key="TabContentWithFirstPanel"&gt; &lt;Grid&gt; &lt;Grid.RowDefinitions&gt; &lt;RowDefinition&gt;&lt;/RowDefinition&gt; &lt;RowDefinition&gt;&lt;/RowDefinition&gt; &lt;/Grid.RowDefinitions&gt; &lt;Grid.ColumnDefinitions&gt; &lt;ColumnDefinition&gt;&lt;/ColumnDefinition&gt; &lt;ColumnDefinition&gt;&lt;/ColumnDefinition&gt; &lt;/Grid.ColumnDefinitions&gt; &lt;TextBlock Grid.Row="0" Grid.Column="0"&gt;Name :&lt;/TextBlock&gt; &lt;TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding TabFirstPanel.Name}"&gt;&lt;/TextBlock&gt; &lt;/Grid&gt; &lt;/DataTemplate&gt; &lt;DataTemplate x:Key="TabContentWithBothPanel"&gt; &lt;Grid&gt; &lt;Grid.RowDefinitions&gt; &lt;RowDefinition&gt;&lt;/RowDefinition&gt; &lt;/Grid.RowDefinitions&gt; &lt;Grid.ColumnDefinitions&gt; &lt;ColumnDefinition Width="200"&gt;&lt;/ColumnDefinition&gt; &lt;ColumnDefinition Width="5"&gt;&lt;/ColumnDefinition&gt; &lt;ColumnDefinition Width="Auto"&gt;&lt;/ColumnDefinition&gt; &lt;/Grid.ColumnDefinitions&gt; &lt;Grid Grid.Row="0" Grid.Column="0"&gt; &lt;Grid.RowDefinitions&gt; &lt;RowDefinition&gt;&lt;/RowDefinition&gt; &lt;RowDefinition&gt;&lt;/RowDefinition&gt; &lt;/Grid.RowDefinitions&gt; &lt;Grid.ColumnDefinitions&gt; &lt;ColumnDefinition&gt;&lt;/ColumnDefinition&gt; &lt;ColumnDefinition&gt;&lt;/ColumnDefinition&gt; &lt;/Grid.ColumnDefinitions&gt; &lt;TextBlock Grid.Row="0" Grid.Column="0"&gt;Name :&lt;/TextBlock&gt; &lt;TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding TabFirstPanel.Name}"&gt;&lt;/TextBlock&gt; &lt;/Grid&gt; &lt;GridSplitter Grid.Row="0" Grid.Column="1" VerticalAlignment="Stretch" Width="5" Height="Auto" ResizeDirection="Columns" ResizeBehavior="PreviousAndNext" &gt;&lt;/GridSplitter&gt; &lt;Grid Grid.Row="0" Grid.Column="2"&gt; &lt;Grid.RowDefinitions&gt; &lt;RowDefinition&gt;&lt;/RowDefinition&gt; &lt;RowDefinition&gt;&lt;/RowDefinition&gt; &lt;/Grid.RowDefinitions&gt; &lt;Grid.ColumnDefinitions&gt; &lt;ColumnDefinition&gt;&lt;/ColumnDefinition&gt; &lt;ColumnDefinition&gt;&lt;/ColumnDefinition&gt; &lt;/Grid.ColumnDefinitions&gt; &lt;TextBlock Grid.Row="0" Grid.Column="0"&gt;Additional Detail :&lt;/TextBlock&gt; &lt;TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding TabSecondPanel.AdditionalDetails}"&gt;&lt;/TextBlock&gt; &lt;/Grid&gt; &lt;/Grid&gt; &lt;/DataTemplate&gt; &lt;/Window.Resources&gt; &lt;Grid&gt; &lt;Grid.RowDefinitions&gt; &lt;RowDefinition Height="50"&gt;&lt;/RowDefinition&gt; &lt;RowDefinition&gt;&lt;/RowDefinition&gt; &lt;/Grid.RowDefinitions&gt; &lt;Grid.ColumnDefinitions&gt; &lt;ColumnDefinition Width="150"&gt;&lt;/ColumnDefinition&gt; &lt;ColumnDefinition&gt;&lt;/ColumnDefinition&gt; &lt;/Grid.ColumnDefinitions&gt; &lt;StackPanel Grid.Row="1" Grid.Column="0"&gt; &lt;Button Content="Load Tab : 1" Name="LoadTab1" Width="100" Height="50" Command="{Binding LoadTabCommand}" CommandParameter="{Binding ElementName=LoadTab1}"&gt;&lt;/Button&gt; &lt;Button Content="Load Tab : 2" Name="LoadTab2" Width="100" Height="50" Command="{Binding LoadTabCommand}" CommandParameter="{Binding ElementName=LoadTab2}"&gt;&lt;/Button&gt; &lt;Button Content="Load Tab : 3" Name="LoadTab3" Width="100" Height="50" Command="{Binding LoadTabCommand}" CommandParameter="{Binding ElementName=LoadTab3}"&gt;&lt;/Button&gt; &lt;/StackPanel&gt; &lt;Button Content="Close All tab" Width="100" Height="40" x:Name="CloseAllTab"&gt;&lt;/Button&gt; &lt;Button Content="Show / Hide Second Panel" x:Name="ShowHideSecondPanelInTab" Grid.Row="0" Grid.Column="1" Width="150" Command="{Binding LoadTabCommand}" CommandParameter="{Binding ElementName=ShowHideSecondPanelInTab}"&gt;&lt;/Button&gt; &lt;TabControl Grid.Row="1" Grid.Column="1" ItemsSource="{Binding TabContentList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedTabItem}" ItemTemplate="{StaticResource ResourceKey=TabitemDataTemplate}" ContentTemplateSelector="{StaticResource ResourceKey=tabContentTemplateSelector}" &gt; &lt;/TabControl&gt; &lt;/Grid&gt; &lt;/Window&gt; </code></pre> <p>Code For MainWindowViewModel </p> <pre><code> using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Input; using System.ComponentModel; using System.Collections.ObjectModel; namespace TabControlTestApp { class MainWindowViewModel : INotifyPropertyChanged { public MainWindowViewModel() { this.loadTabCommand = new LoadTabCommand(this); tabContentList = new ObservableCollection&lt;TabContent&gt;(); } public ICommand LoadTabCommand { get { return this.loadTabCommand; } set { this.loadTabCommand = value; } } public ObservableCollection&lt;TabContent&gt; TabContentList { get { return tabContentList; } set { tabContentList = value; OnPropertyChanged("TabContentList"); } } public TabContent SelectedTabItem { get { return selectedTabItem; } set { selectedTabItem = value; OnPropertyChanged("SelectedTabItem"); } } public void LoadFirstTab() { TabFirstPanel firstPanel = new TabFirstPanel() { Name = "John-1", Age = "31" }; TabSecondPanel secondPanel = new TabSecondPanel() { AdditionalDetails="Some Details for First Tab" }; TabContent firstTabContent = new TabContent() { TabFirstPanel = firstPanel, TabSecondPanel = secondPanel, ShowSecondPanel = false }; tabContentList.Add(firstTabContent); SelectedTabItem = firstTabContent; } public void LoadSecondTab() { TabFirstPanel firstPanel = new TabFirstPanel() { Name = "John-2", Age = "31" }; TabSecondPanel secondPanel = new TabSecondPanel() { AdditionalDetails = "Some Details for second Tab" }; TabContent secondTabContent= new TabContent() { TabFirstPanel = firstPanel, TabSecondPanel = secondPanel, ShowSecondPanel=false }; tabContentList.Add(secondTabContent); SelectedTabItem = secondTabContent; } public void LoadThirdTab() { TabFirstPanel firstPanel = new TabFirstPanel() { Name = "John-3", Age = "31" }; TabSecondPanel secondPanel = new TabSecondPanel() { AdditionalDetails = "Some Details for Third Tab" }; TabContent ThirdTabContent = new TabContent() { TabFirstPanel = firstPanel, TabSecondPanel = secondPanel, ShowSecondPanel = false }; tabContentList.Add(ThirdTabContent); SelectedTabItem = ThirdTabContent; } public void ShowHideSecondPanelInTab() { TabContent currentTabContent = SelectedTabItem; int currentIndex = tabContentList.IndexOf(SelectedTabItem); if (currentTabContent.ShowSecondPanel) { currentTabContent.ShowSecondPanel = false; } else { currentTabContent.ShowSecondPanel = true; } TabContentList.RemoveAt(currentIndex); TabContentList.Insert(currentIndex, currentTabContent); OnPropertyChanged("TabContentList"); SelectedTabItem = currentTabContent; } private TabContent selectedTabItem = null; private ObservableCollection&lt;TabContent&gt; tabContentList = null; private ICommand loadTabCommand = null; public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } </code></pre> <p>}</p> <p>Code for TabContentTemplateSelector.cs</p> <pre><code> using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Controls; using System.Windows; namespace TabControlTestApp { class TabContentTemplateSelector : DataTemplateSelector { public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container) { FrameworkElement element = container as FrameworkElement; if (element != null &amp;&amp; item != null) { TabContent tabContent = (TabContent)item; if (tabContent.ShowSecondPanel) { return element.FindResource("TabContentWithBothPanel") as DataTemplate; } else { return element.FindResource("TabContentWithFirstPanel") as DataTemplate; } } else { return base.SelectTemplate(item, container); } } } </code></pre> <p>}</p> <p>Code for TabContent Data Object</p> <pre><code> using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TabControlTestApp { class TabFirstPanel { public string Name { get; set; } public string Age { get; set; } } class TabSecondPanel { public string AdditionalDetails { get; set; } } class TabContent { public TabFirstPanel TabFirstPanel { get; set; } public TabSecondPanel TabSecondPanel { get; set; } public bool ShowSecondPanel { get; set; } } </code></pre> <p>}</p> <p>Code for LoadTabCommand Class</p> <pre><code> using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Input; namespace TabControlTestApp { class LoadTabCommand : ICommand { MainWindowViewModel mainWindowViewModel = null; public LoadTabCommand(MainWindowViewModel mainWindowViewModel) { this.mainWindowViewModel = mainWindowViewModel; } public bool CanExecute(object parameter) { return true; } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { System.Windows.Controls.Button btn = (System.Windows.Controls.Button)parameter; switch (btn.Name) { case "LoadTab1": mainWindowViewModel.LoadFirstTab(); break; case "LoadTab2": mainWindowViewModel.LoadSecondTab(); break; case "LoadTab3": mainWindowViewModel.LoadThirdTab(); break; case "ShowHideSecondPanelInTab": mainWindowViewModel.ShowHideSecondPanelInTab(); break; } } } </code></pre> <p>}</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload