Your problem is very simple if you make a MVVM application. For 1 ViewModel (the fonctionnality), you can attach many View (UI). In your case, on a single application, create one instance of a ViewModel and set the DataContext of each View to this viewmodel. Each view can be on different monitor, sizing different, content different ...
Full Example
First, create a model ( = Data)
using System;
namespace WpfApplication1
{
public class MyModel
{
public String Text1 { get; set; }
public Int32 Int1 { get; set; }
public Int32 Int2 { get; set; }
}
}
Then, a ViewModel (how the data interact and must live)
using System;
namespace WpfApplication1
{
public class MyViewModel
{
private MyModel myModel;
public MyViewModel()
{
this.myModel = new MyModel() { Int1 = 1, Int2 = 12, Text1 = "toto" };
}
public String MyText
{
get { return this.myModel.Text1; }
set { this.myModel.Text1 = value; }
}
public Int32 MyInt1
{
get { return this.myModel.Int1; }
set { this.myModel.Int1 = value; }
}
public Int32 MyInt2
{
get { return this.myModel.Int2; }
set { this.myModel.Int2 = value; }
}
}
}
Then, first view (UI, how the data must be shown)
<Window x:Class="WpfApplication1.View1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="View1" Height="300" Width="300"
Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}"
xmlns:local="clr-namespace:WpfApplication1"
>
<Window.DataContext>
<local:MyViewModel />
</Window.DataContext>
<Grid>
<TextBox Text="{Binding MyText, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Window>
The code behind for this view (only UI code)
using System.Windows;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for View1.xaml
/// </summary>
public partial class View1 : Window
{
public View1()
{
InitializeComponent();
}
public View1(MyViewModel viewModel)
: this()
{
this.DataContext = viewModel;
}
}
}
The 2nd view (different of the first)
<Window x:Class="WpfApplication1.View2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="View2" Height="300" Width="300"
Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}"
xmlns:local="clr-namespace:WpfApplication1"
>
<Window.DataContext>
<local:MyViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox Text="{Binding MyText, UpdateSourceTrigger=PropertyChanged}" />
<Slider Value="{Binding MyInt1, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" />
</Grid>
</Window>
using System.Windows;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for View2.xaml
/// </summary>
public partial class View2 : Window
{
public View2()
{
InitializeComponent();
}
public View2(MyViewModel viewModel)
: this()
{
this.DataContext = viewModel;
}
}
}
The 3rd view (different of the first and the second)
<Window x:Class="WpfApplication1.View3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="View2" Height="300" Width="300"
Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}"
xmlns:local="clr-namespace:WpfApplication1"
>
<Window.DataContext>
<local:MyViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox Text="{Binding MyText, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding MyInt1, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" />
<TextBox Text="{Binding MyInt2, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" />
</Grid>
</Window>
using System.Windows;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for View3.xaml
/// </summary>
public partial class View3 : Window
{
public View3()
{
InitializeComponent();
}
public View3(MyViewModel viewModel)
: this()
{
this.DataContext = viewModel;
}
}
}
And to finish, your starting point, where all views are called :
public MainWindow()
{
MyViewModel myOnlyViewModel = new MyViewModel();
View1 view1 = new View1(myOnlyViewModel);
view1.Show();
View2 view2 = new View2(myOnlyViewModel);
view2.Show();
View3 view3 = new View3(myOnlyViewModel);
view3.Show();
}
As you can see, each change in a UI is shown in others UI (You don't need to launch 3 instances of your app, only 1 !). For example, moving the slider will modify value of MyInt1 in other views. All you have to do is to design all Views you want, and always think to separate how the data live and how the data are shown