you create a tabViewModel, in the tab view model you create the collection of user control. so each control in the collection will have its own instance and be bind to each tab. This way you will maintain the separation.
App.xaml ( set the App.xaml to fire the start up event)
<Application x:Class="WPFUserControlBinding.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="App_OnStartup">
<Application.Resources>
</Application.Resources>
</Application>
you need to set the Startup event of the App.xaml
Then edit the App.xaml.cs file as below
using System.Windows;
namespace WPFUserControlBinding
{
public partial class App : Application
{
private void App_OnStartup(object sender, StartupEventArgs e)
{
var mainWindowViewModel = new MainWindowViewModel();
var mainWindow = new MainWindow()
{
DataContext = mainWindowViewModel,
MainTab = {DataContext = mainWindowViewModel.TabViewModel}
};
mainWindow.Show();
}
}
}
MainWindow.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFUserControlBinding"
x:Class="WPFUserControlBinding.MainWindow"
Title="MainWindow" Height="350" Width="525"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
>
<Window.Resources>
<local:MainWindowViewModel x:Key="MainWindowViewModel"></local:MainWindowViewModel>
</Window.Resources>
<Grid d:DataContext ="{d:DesignInstance local:MainWindowViewModel}">
<TabControl x:Name="MainTab" HorizontalAlignment="Left" Height="261" Margin="10,24,0,0" VerticalAlignment="Top" Width="460">
<TabItem Header="TabItem1" d:DataContext="{d:DesignInstance local:TabViewModel}">
<local:MyUserControl HorizontalAlignment="Left" Margin="32,31,0,0" VerticalAlignment="Top" Width="172" DataContext="{Binding Path=.TabItems[0]}"/>
</TabItem>
<TabItem Header="TabItem2" d:DataContext="{d:DesignInstance local:TabViewModel}">
<local:MyUserControl HorizontalAlignment="Left" Margin="32,31,0,0" VerticalAlignment="Top" Width="172" DataContext="{Binding Path=.TabItems[1]}"/>
</TabItem>
</TabControl>
</Grid>
</Window>
There should be no code in the MainWindow.xaml.cs file.
Note: you can see that each control in the each tabitem is bound to the exact item in the collection.
MainWindowViewModel.cs
namespace WPFUserControlBinding
{
public class MainWindowViewModel
{
public TabViewModel TabViewModel { get; set; }
public MainWindowViewModel()
{
TabViewModel = new TabViewModel();
}
}
}
MyUserControl.xaml
<UserControl x:Class="WPFUserControlBinding.MyUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:WPFUserControlBinding"
mc:Ignorable="d" d:DesignWidth="300" Height="120">
<Grid d:DataContext="{d:DesignInstance vm:MyUserControlViewModel}">
<StackPanel >
<TextBlock x:Name="NameLabel" Text="Name:"/>
<TextBlock x:Name="Name" Text="{Binding Name}"/>
</StackPanel>
</Grid>
</UserControl>
MyUserControlViewModel.cs
namespace WPFUserControlBinding
{
public class MyUserControlViewModel
{
private string _name = string.Empty;
public string Name
{
get { return _name; }
set
{
if (!_name.Equals(value))
{
_name = value;
}
}
}
}
}
TabViewModel.cs
namespace WPFUserControlBinding
{
public class TabViewModel
{
public MyUserControlViewModel[] TabItems { get; set; }
public TabViewModel()
{
TabItems = new MyUserControlViewModel[]
{
new MyUserControlViewModel() {Name = "Peter"},
new MyUserControlViewModel() {Name = "Bob"},
new MyUserControlViewModel() {Name = "Tom"}
};
}
}
}
When you run this code, you will see each tab will display the name as from the collection. you can modify the tabViewModel to dynamically load the tab items as per the collection if you want.