Here is a little example project I made to allow the tabitem header to be of a usercontrol and tabitem content to be of another usercontrol. It allows for adding and removing tabitems in the same way internet explorer functions. I have also included a flag button next to the close button on each tab item that you can toggle.
This is a full MVVM application written in VB.Net.
 
Imports System.Collections.ObjectModel
  
Imports System.ComponentModel
  
  
Namespace ViewModel
  
    Public Class TabControlVM
  
        Implements INotifyPropertyChanged
  
  
#Region "Properties"
  
  
        ''Holds collection of tab items
  
        Private _myTab As ObservableCollection(Of Model.MyTab) = Nothing
  
        Public Property MyTabCollection As ObservableCollection(Of Model.MyTab)
  
            Get
  
                Return _myTab
  
            End Get
  
            Set(ByVal value As ObservableCollection(Of Model.MyTab))
  
                _myTab = value
  
                OnPropertyChanged("MyTabCollection")
  
            End Set
  
        End Property
  
  
        ''Selected tab item index
  
        Private _selectedIndex As Integer = 0
  
        Public Property SelectedIndex As Integer
  
            Get
  
                Return _selectedIndex
  
            End Get
  
            Set(ByVal value As Integer)
  
                _selectedIndex = value
  
                OnPropertyChanged("SelectedIndex")
  
            End Set
  
        End Property
  
  
#End Region
  
  
#Region "Relay Commands"
  
  
        Private _addTab As RelayCommand = Nothing
  
        Public ReadOnly Property AddTabCommand() As ICommand
  
            Get
  
                If _addTab Is Nothing Then
  
                    Dim commandAction As New Action(Of Object)(AddressOf Me.AddTab)
  
                    _addTab = New RelayCommand(commandAction)
  
                End If
  
                Return _addTab
  
            End Get
  
        End Property
  
  
        Private _removeTab As RelayCommand = Nothing
  
        Public ReadOnly Property RemoveTabCommand() As ICommand
  
            Get
  
                If _removeTab Is Nothing Then
  
                    Dim commandAction As New Action(Of Object)(AddressOf Me.RemoveTab)
  
                    _removeTab = New RelayCommand(commandAction)
  
                End If
  
                Return _removeTab
  
            End Get
  
        End Property
  
  
#End Region
  
  
#Region "Constructor"
  
  
        ''' <summary>
  
        ''' <para>Creates a new obeservable collection with tab items for tab control.
  
        ''' Uses usercontrol for tab item header and content.</para>
  
        ''' </summary>
  
        ''' <remarks></remarks>
  
        Public Sub New()
  
  
            ''Create a MyTab collection (tabitems)
  
            _myTab = New ObservableCollection(Of Model.MyTab)
  
  
            ''Create tabitem header object
  
            Dim tabHeaderObj = New TabHeaderAddUC
  
            tabHeaderObj.DataContext = Me
  
  
            ''Create the Add Tab content object 
  
            Dim tabContentObj As New TabContentAddUC
  
            tabContentObj.DataContext = Me
  
  
            ''Add to collection
  
            _myTab.Add(New Model.MyTab(tabHeaderObj, tabContentObj, 0))
  
  
        End Sub
  
  
#End Region
  
  
#Region "Add Tab"
  
  
        ''' <summary>
  
        ''' <para>Method which creates a new tabitem object and adds it to MyTab collection.</para>
  
        ''' </summary>
  
        ''' <param name="obj">Object of command parameter from view.</param>
  
        ''' <remarks></remarks>
  
        Private Sub AddTab(ByVal obj As Object)
  
  
            ''Checks the highest MyTab.Index which will be used when assigingin
  
            ''a new tab item (index + 1)
  
            Dim i As Integer = 0
  
            For Each tb As Model.MyTab In MyTabCollection
  
                If tb.Index > i Then i = tb.Index
  
            Next
  
  
            ''Create tabitem header object
  
            Dim tabHeaderObj = New TabHeaderUC
  
            ''Enable if you want to explicitly set view model class here instead of in the view
  
            ''-----------------------------------------------------------------------------
  
            tabHeaderObj.DataContext = New ViewModel.TabHeaderVM With {.HeaderText = "Tab item " & i}
  
            ''-----------------------------------------------------------------------------
  
  
            ''Create tabitem content object
  
            Dim tabContentObj As New TabContentMyContentUC
  
            tabContentObj.DataContext = Me
  
  
            ''Have the add tab on the left side
  
            ''-----------------------------------------------------------------------------
  
            ''Add to collection
  
            'MyTabCollection.Add(New Model.MyTab(tabHeaderObj, tabContentObj, i + 1))
  
            ''-----------------------------------------------------------------------------
  
  
            ''Have the add tab on the right side
  
            ''-----------------------------------------------------------------------------
  
            ''Insert to collection
  
            MyTabCollection.Insert(i, New Model.MyTab(tabHeaderObj, tabContentObj, i + 1))
  
            ''-----------------------------------------------------------------------------
  
  
            ''Set the highest tab item to visible
  
            SelectedIndex = i
  
  
        End Sub
  
  
#End Region
  
  
#Region "Remove Tab"
  
  
        ''' <summary>
  
        ''' <para>Removes the tab item at specified index.</para>
  
        ''' </summary>
  
        ''' <param name="obj">Object of command parameter from view containing the TabItem.</param>
  
        ''' <remarks></remarks>
  
        Private Sub RemoveTab(ByVal obj As Object)
  
  
            ''Gets the tabitem MyTab.Index from tabitem Tag and 
  
            ''removes the item at this location from the collection
  
            Dim tabItemObj = DirectCast(obj, TabItem)
  
  
            ''Have the add tab on the left side
  
            ''-----------------------------------------------------------------------------
  
            'If Not tabItemObj.Tag = 0 Then MyTabCollection.RemoveAt(tabItemObj.Tag)
  
            ''-----------------------------------------------------------------------------
  
  
            ''Have the add tab on the right side
  
            ''-----------------------------------------------------------------------------
  
            If Not tabItemObj.Tag = 0 Then MyTabCollection.RemoveAt(tabItemObj.Tag - 1)            
  
            ''-----------------------------------------------------------------------------
  
  
            ''Rebuild the MyTab.Index to match tabitem index
  
            Dim j As Integer = 1
  
            For Each item As Model.MyTab In _myTab
  
                If Not item.Index = 0 Then
  
                    item.Index = j
  
                    j += 1
  
                End If
  
            Next
  
  
            ''Set the highest tab item to visible
  
            SelectedIndex = j
  
        End Sub
  
  
#End Region
  
  
#Region "INotifyPropertyChanged"
  
  
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
  
  
        Protected Overridable Sub OnPropertyChanged(ByVal PropertyName As String)
  
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyName))
  
  
        End Sub
  
  
#End Region
  
  
    End Class
  
  
End Namespace
  
    
Imports System.ComponentModel
  
  
Namespace Model
  
    Public Class MyTab
  
        Implements INotifyPropertyChanged
  
  
#Region "Properties"
  
  
        ''Tab item header usercontrol
  
        Private _header As UserControl = Nothing
  
        Property Header As UserControl
  
            Get
  
                Return _header
  
            End Get
  
            Set(ByVal value As UserControl)
  
                _header = value
  
                OnPropertyChanged("Header")
  
            End Set
  
        End Property
  
  
        ''Tab content user control
  
        Private _content As UserControl = Nothing
  
        Property Content As UserControl
  
            Get
  
                Return _content
  
            End Get
  
            Set(ByVal value As UserControl)
  
                _content = value
  
                OnPropertyChanged("Content")
  
            End Set
  
        End Property
  
  
        ''Tab item index in tabcontrol
  
        Private _indexObj As Integer = 0
  
        Property Index As Integer
  
            Get
  
                Return _indexObj
  
            End Get
  
            Set(ByVal value As Integer)
  
                _indexObj = value
  
                OnPropertyChanged("Index")
  
            End Set
  
        End Property
  
  
#End Region
  
  
#Region "Constructor"
  
  
        ''' <summary>
  
        ''' <para>Constructor accepting two user controls as parameters for header and content.</para>
  
        ''' </summary>
  
        ''' <param name="h">UserControl containing header information.</param>
  
        ''' <param name="c">UserControl containing content information.</param>
  
        ''' <param name="i">Integer representing an artificial index of the tabitems.</param>
  
        ''' <remarks></remarks>
  
        Public Sub New(ByVal h As UserControl, ByVal c As UserControl, ByVal i As Integer)
  
            Try
  
                Header = h
  
                Content = c
  
                Index = i
  
            Catch ex As Exception
  
                Throw New Exception("Error in MyTab constructor.")
  
            End Try
  
        End Sub
  
  
#End Region
  
  
#Region "INotifyPropertyChanged"
  
  
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
  
  
        Protected Overridable Sub OnPropertyChanged(ByVal PropertyName As String)
  
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyName))
  
        End Sub
  
  
#End Region
  
  
    End Class
  
End Namespace
  
  
Imports System.Collections.ObjectModel
  
Imports System.ComponentModel
  
  
Namespace ViewModel
  
    Public Class TabHeaderVM
  
        Implements INotifyPropertyChanged
  
  
#Region "Properties"
  
  
        ''Set flag image
  
        Private _imageSource As String = ""
  
        Public Property ImageSource As String
  
            Get
  
                Return _imageSource
  
            End Get
  
            Set(ByVal value As String)
  
                _imageSource = value
  
                OnPropertyChanged("ImageSource")
  
            End Set
  
        End Property
  
  
        ''Header text
  
        Private _headerText As String = ""
  
        Public Property HeaderText As String
  
            Get
  
                Return _headerText
  
            End Get
  
            Set(ByVal value As String)
  
                _headerText = value
  
                OnPropertyChanged("HeaderText")
  
            End Set
  
        End Property
  
  
#End Region
  
  
#Region "Relay Commands"
  
  
        Private _SetTabItemFlagImageCommand As RelayCommand = Nothing
  
        Public ReadOnly Property SetTabItemFlagImageCommand() As ICommand
  
            Get
  
                If _SetTabItemFlagImageCommand Is Nothing Then
  
                    Dim commandAction As New Action(Of Object)(AddressOf Me.SetTabItemFlagImage)
  
                    _SetTabItemFlagImageCommand = New RelayCommand(commandAction)
  
                End If
  
                Return _SetTabItemFlagImageCommand
  
            End Get
  
        End Property
  
  
#End Region
  
  
#Region "Constructor"
  
  
        ''' <summary>
  
        ''' <para></para>
  
        ''' </summary>
  
        ''' <remarks></remarks>
  
        Public Sub New()
  
  
        End Sub
  
  
#End Region
  
  
#Region "Set Flag Visibility"
  
  
        Private Sub SetTabItemFlagImage()
  
            If ImageSource = "" Then
  
                ImageSource = "/Images/16x16/Flag-red.png"
  
            ElseIf ImageSource = "/Images/16x16/Flag-red.png" Then
  
                ImageSource = "/Images/16x16/Flag-gray.png"
  
            ElseIf ImageSource = "/Images/16x16/Flag-gray.png" Then
  
                ImageSource = ""
  
            End If
  
  
        End Sub
  
  
#End Region
  
  
#Region "INotifyPropertyChanged"
  
  
        Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
  
  
        Protected Overridable Sub OnPropertyChanged(ByVal PropertyName As String)
  
            RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyName))
  
  
        End Sub
  
  
#End Region
  
  
    End Class
  
  
End Namespace