I believe that I came up with a complete solution, I started with an NVM solution to create my template. And then referenced the DataGrid source code to come up with an advanced TabControl that can add and remove elements.
ExtendedTabControl.cs
public class ExtendedTabControl : TabControl { public static readonly DependencyProperty CanUserAddTabsProperty = DependencyProperty.Register("CanUserAddTabs", typeof(bool), typeof(ExtendedTabControl), new PropertyMetadata(false, OnCanUserAddTabsChanged, OnCoerceCanUserAddTabs)); public bool CanUserAddTabs { get { return (bool)GetValue(CanUserAddTabsProperty); } set { SetValue(CanUserAddTabsProperty, value); } } public static readonly DependencyProperty CanUserDeleteTabsProperty = DependencyProperty.Register("CanUserDeleteTabs", typeof(bool), typeof(ExtendedTabControl), new PropertyMetadata(true, OnCanUserDeleteTabsChanged, OnCoerceCanUserDeleteTabs)); public bool CanUserDeleteTabs { get { return (bool)GetValue(CanUserDeleteTabsProperty); } set { SetValue(CanUserDeleteTabsProperty, value); } } public static RoutedUICommand DeleteCommand { get { return ApplicationCommands.Delete; } } public static readonly DependencyProperty NewTabCommandProperty = DependencyProperty.Register("NewTabCommand", typeof(ICommand), typeof(ExtendedTabControl)); public ICommand NewTabCommand { get { return (ICommand)GetValue(NewTabCommandProperty); } set { SetValue(NewTabCommandProperty, value); } } private IEditableCollectionView EditableItems { get { return (IEditableCollectionView)Items; } } private bool ItemIsSelected { get { if (this.SelectedItem != CollectionView.NewItemPlaceholder) return true; return false; } } private static void OnCanExecuteDelete(object sender, CanExecuteRoutedEventArgs e) { ((ExtendedTabControl)sender).OnCanExecuteDelete(e); } private static void OnCanUserAddTabsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((ExtendedTabControl)d).UpdateNewItemPlaceholder(); } private static void OnCanUserDeleteTabsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
CustomStyleSelector.cs
internal class CustomStyleSelector : StyleSelector { public Style NewItemStyle { get; set; } public override Style SelectStyle(object item, DependencyObject container) { if (item == CollectionView.NewItemPlaceholder) return NewItemStyle; else return Application.Current.FindResource(typeof(TabItem)) as Style; } }
TemplateSelector.cs
internal class TemplateSelector : DataTemplateSelector { public DataTemplate ItemTemplate { get; set; } public DataTemplate NewItemTemplate { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { if (item == CollectionView.NewItemPlaceholder) return NewItemTemplate; else return ItemTemplate; } }
Generic.xaml
<Style x:Key="NewTabItemStyle" TargetType="{x:Type TabItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TabItem}"> <ContentPresenter ContentSource="Header" HorizontalAlignment="Left" /> </ControlTemplate> </Setter.Value> </Setter> </Style> <DataTemplate x:Key="ClosableTabItemHeader"> <DockPanel MinWidth="120"> <Button DockPanel.Dock="Right" Command="ApplicationCommands.Delete" CommandParameter="{Binding}" Content="X" Cursor="Hand" Focusable="False" FontSize="10" FontWeight="Bold" Height="16" Width="16" /> <TextBlock Padding="0,0,10,0" Text="{Binding DisplayName}" VerticalAlignment="Center" /> </DockPanel> </DataTemplate> <DataTemplate x:Key="NewTabItemHeader"> <Button Command="{Binding NewTabCommand, RelativeSource={RelativeSource AncestorType={x:Type local:ExtendedTabControl}}}" Content="+" Cursor="Hand" Focusable="False" FontWeight="Bold" Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"/> </DataTemplate> <local:CustomStyleSelector x:Key="StyleSelector" NewItemStyle="{StaticResource NewTabItemStyle}" /> <local:TemplateSelector x:Key="HeaderTemplateSelector" ItemTemplate="{StaticResource ClosableTabItemHeader}" NewItemTemplate="{StaticResource NewTabItemHeader}" /> <Style x:Key="{x:Type local:ExtendedTabControl}" BasedOn="{StaticResource {x:Type TabControl}}" TargetType="{x:Type local:ExtendedTabControl}"> <Setter Property="ItemContainerStyleSelector" Value="{StaticResource StyleSelector}" /> <Setter Property="ItemTemplateSelector" Value="{StaticResource HeaderTemplateSelector}" /> </Style>
Derrick Moeller Jan 6 '15 at 18:55 2015-01-06 18:55
source share