Creating closeable tabitems for use in CompositeWPF

Using a tabcontrol as a region for views in a CompositeWPF application is one thing, making them closeable can be a bit trickier. The sample in this article will show how you can modify a tabcontrol to allow closeable items.

Step 1: Make the custom header template and tabitem style

The first step is to modify the look of a tabitem header so it contains a close button while leaving room for the header content defined on the tab item. The XAML content required for this looks like the following:

<TabControl>
<TabControl.Resources>
<DataTemplate x:Key=&quot;CustomTabHeader&quot;>
<StackPanel Orientation=&quot;Horizontal&quot;>
<ContentPresenter>
<ContentPresenter.Content>
<Binding Path=&quot;Header&quot;>
<Binding.RelativeSource>
<RelativeSource Mode=&quot;FindAncestor&quot;
AncestorType=&quot;{x:Type TabItem}&quot;/>
</Binding.RelativeSource>
</Binding>
</ContentPresenter.Content>
</ContentPresenter>
<Button Margin=&quot;8,0,0,0&quot; Command=&quot;local:Commands.CloseTabItem&quot; CommandParameter=&quot;{Binding
RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type TabItem}}}&quot;

HorizontalContentAlignment=&quot;Center&quot;
VerticalContentAlignment=&quot;Center&quot;>
<Grid>
<Canvas Width=&quot;8&quot; Height=&quot;8&quot;>
<Line X1=&quot;2&quot; X2=&quot;6&quot; Y1=&quot;2&quot; Y2=&quot;6&quot;
Stroke=&quot;Black&quot; StrokeThickness=&quot;1&quot;/>
<Line X1=&quot;6&quot; X2=&quot;2&quot; Y1=&quot;2&quot; Y2=&quot;6&quot;
Stroke=&quot;Black&quot; StrokeThickness=&quot;1&quot;/>
</Canvas>
</Grid>
</Button>
</StackPanel>
</DataTemplate>
<Style TargetType=&quot;TabItem&quot;>
<Style.Setters>
<Setter Property=&quot;HeaderTemplate&quot;
Value=&quot;{StaticResource CustomTabHeader}&quot;/>
</Style.Setters>
</Style>
</TabControl.Resources>
</
TabControl>

Step 2: Closing tabitems

The second step is writing a little bit of code to close tabitems when the command is fired.

private void OnCloseTabItemExecute(object sender, ExecutedRoutedEventArgs e)
{
TabItem parent = e.Parameter as TabItem;

if (parent != null)
{
FrameworkElement view = (parent as TabItem).Content as FrameworkElement;
string regionName = RegionManager.GetRegionName(view);

_regionManager.Regions[regionName].Remove(view);
}
}

The first thing to do is find the tabitem that is quietly wrapped around the view that was added to the tabcontrol. This is done through a recursive search for parent framework elements until the tabitem is found. After that its a matter of retrieving the value of the RegionName attached property and removing the tabitem content from the region.

Conclusion

While a custom may look prettier over time it&rsquo;s really not a requirement to make closable views in a compositeWPF application. Thanks to the powerful styling and templating features in WPF you can make the tabcontrol as fancy as you like without making it overly complex to work with.

&nbsp;

— Update : The sample didn&#039;t work as expected. I have updated the sample code and made sure it works now. Please notify me if any more issues arise.