Everything's easier with data binding and MVVM. Harder at first, but ultimately lots easier.
Make two classes, Item and ItemCollection, that both implement INotifyPropertyChanged. Item should expose a string Text property, while ItemCollection should expose an ObservableCollection<Item> Items property and an Item SelectedItem property.
Make the ItemCollection class's constructor populate Items with test data and set SelectedItem.
This seems like a lot to do before you actually get around to implementing your tab control, but trust me, you'll like the result. Your XAML for the TabControl will look something like this:
<TabControl
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}">
<TabControl.DataContext>
<local:ItemsCollection/>
</TabControl.DataContext>
<TabControl.Resources>
<DataTemplate DataType="{x:Type local:Item}">
<TextBlock Background="AliceBlue" Text="{Binding Text}"/>
</DataTemplate>
</TabControl.Resources>
<TabControl.ItemContainerStyle>
<Style TargetType="{x:Type TabItem}">
<Style.Setters>
<Setter Property="Header" Value="{Binding Text}"/>
</Style.Setters>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
Let's understand what this does. It creates a TabControl. It creates an ItemsCollection object and sets it as the TabControl's DataContext. You've bound ItemSource to Items, so the TabControl will create a TabItem for each item. It will apply the ItemContainerStyle to each TabItem, which sets its Header property to the Item's Text property.
When the control renders the content of a tab, it finds the item it's rendering, searches through the resources to find a DataTemplate whose DataType matches the item, and uses that template. Since we've defined one in TabControl.Resources, you get a nice blue background and the Text property again.
This seems like a lot to go through. But now you don't have to write any code that manipulates the UI; you just write code that manipulates your ItemsCollection, and the UI pretty much takes care of itself.
Now let's take care of adding new tabs. What we're going to do is add a new item to the control that, when it becomes selected, adds a new item to the Items collection.
Create a new class, called, oh, ControlItem. Have it derive from Item. Modify your ItemsCollection constructor so that the last item it adds is a ControlItem, not an Item. And have it set the Text property on that item to "+".
Add this method to ItemsCollection:
public Item AddItem()
{
Item newItem = new Item {Text = "New item"};
Items.Insert(Items.Count-1, newItem);
return newItem;
}
Now add to your window's code-behind, and as the SelectionChanged event handler for your TabControl:
void TabControl_SelectionChanged(object sender, RoutedEventArgs e)
{
TabControl tc = (TabControl) sender;
if (tc.SelectedItem is ControlItem)
{
ItemsCollection ic = (ItemsCollection) tc.DataContext;
tc.SelectedItem = ic.AddItem();
}
}
You can implement similar logic to remove an item from the list, but you'll need to introduce another variable to ItemsCollection to track the previously selected item, so that you can know which item to delete.
Another thing you can do: implement a Background property in Item and add a setter to the ItemContainerStyle that binds the TabItem's Background property to it. Then you can overload that property in ControlItem, so that your add and delete tabs look different.
You can also implement different subclasses for your control items, and have them expose a method that you call in the SelectionChanged event handler. That way, the event handler doesn't have to know anything about what the control item being clicked is doing. In fact, if you make the method part of Item, and have it do nothing unless it's overriden, the window doesn't even need to know that Item has subclasses.
That's the philosophy behind MVVM in a nutshell: Bind the view to objects about which it knows almost nothing. Let the view-model objects control what happens, so that the view doesn't have to.