Let's suppose you have a TabControl with several TabItems. The definition might look like this.
<Window x:Class="DeferredTabItemContentCreation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DeferredTabItemContentCreation"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:Search x:Key="Search"/>
<local:Add x:Key="Add"/>
<local:Edit x:Key="Edit"/>
</Window.Resources>
<Grid>
<TabControl SelectionChanged="TabControl_SelectionChanged">
<TabItem Header="Search" Content="{StaticResource Search}"/>
<TabItem Header="Add" Content="{StaticResource Add}"/>
<TabItem Header="Edit" Content="{StaticResource Edit}"/>
</TabControl>
</Grid>
</Window>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DeferredTabItemContentCreation"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:Search x:Key="Search"/>
<local:Add x:Key="Add"/>
<local:Edit x:Key="Edit"/>
</Window.Resources>
<Grid>
<TabControl SelectionChanged="TabControl_SelectionChanged">
<TabItem Header="Search" Content="{StaticResource Search}"/>
<TabItem Header="Add" Content="{StaticResource Add}"/>
<TabItem Header="Edit" Content="{StaticResource Edit}"/>
</TabControl>
</Grid>
</Window>
It's fairly easy to achieve this by not specifying Content for the Add and Edit tabs and adding a SelectionChanged event handler.
<Window x:Class="DeferredTabItemContentCreation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DeferredTabItemContentCreation"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:Search x:Key="Search"/>
</Window.Resources>
<Grid>
<TabControl SelectionChanged="TabControl_SelectionChanged">
<TabItem Header="Search" Content="{StaticResource Search}"/>
<TabItem Header="Add"/>
<TabItem Header="Edit"/>
</TabControl>
</Grid>
</Window>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DeferredTabItemContentCreation"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:Search x:Key="Search"/>
</Window.Resources>
<Grid>
<TabControl SelectionChanged="TabControl_SelectionChanged">
<TabItem Header="Search" Content="{StaticResource Search}"/>
<TabItem Header="Add"/>
<TabItem Header="Edit"/>
</TabControl>
</Grid>
</Window>
The SelectionChanged event handler detects that the TabItem we are changing to has no Content and creates it on the fly. If we have visited this tab before, we just reuse the Content we created on the first visit.
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
TabControl? tc = (sender as TabControl);
if (tc != null && e.AddedItems != null && e.AddedItems.Count > 0)
{
TabItem? ti = e.AddedItems[0] as TabItem;
if (ti != null)
{
if (ti.Content == null)
{
switch (ti.Header?.ToString()?.ToLower())
{
case "add": ti.Content = new Add();break;
case "edit":ti.Content = new Edit();break;
}
}
}
}
}
TabControl? tc = (sender as TabControl);
TabItem? ti = e.AddedItems[0] as TabItem;
if (ti.Content == null)
switch (ti.Header?.ToString()?.ToLower())
case "add": ti.Content = new Add();break;
}
}
}
}
For more complex scenarios we could subclass the TabItem and add a class property. Then we could use Reflection CreateInstance to dynamically create the Content from the class property.
No comments:
Post a Comment