As a summary: Can Docking Windows through MVVM data bind UserControls to DocumentWindows?
I have a project, where my viewmodel contains an ObservableCollection of UserControls and a few strings. When I use the DockingBehavior example as a starting point, I am able to bind the DocumentItemSource to the voewmodel, but the DocumentItemTemplate and DocumentItemStyle fails to render the control, just it's string representation (MVVMDockingTest.TestModel. Also, the additional properties of the DocumentWindow (like Title) are not displayed in the docking tab, though surprisingly they show up in the 'Active Files' dropdown box.
Window XAML
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:docking="http://schemas.actiprosoftware.com/winfx/xaml/docking" xmlns:local="clr-namespace:MVVMDockingTest" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sampleCommon="clr-namespace:MVVMDockingTest"
xmlns:themes="http://schemas.actiprosoftware.com/winfx/xaml/themes" mc:Ignorable="d" x:Class="MVVMDockingTest.MainWindow"
Title="MainWindow" SizeToContent="WidthAndHeight">
<Window.Resources>
<sampleCommon:TestViewModel x:Key="TestViewModelDataSource" d:IsDataSource="True"/>
<Style x:Key="DocumentItemStyle" TargetType="{x:Type docking:DocumentWindow}">
<Setter Property="Title" Value="{Binding TestName}" />
<Setter Property="Description" Value="{Binding TestDescription}" />
</Style>
<DataTemplate x:Key="DocTemplate" >
<UserControl Content="{Binding TestName}" BorderThickness="0" BorderBrush="#FFE22B2B" />
</DataTemplate>
</Window.Resources>
<Grid MinHeight="768" MinWidth="1024" DataContext="{Binding Source={StaticResource TestViewModelDataSource}}">
<docking:DockSite sampleCommon:DockingBehavior.IsManaged="True" HorizontalAlignment="Stretch" x:Name="dockSite1" VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" Margin="0" DocumentItemsSource="{Binding TestCollection}" DocumentItemContainerStyle="{DynamicResource DocumentItemStyle}" DocumentItemTemplate="{StaticResource DocTemplate}">
<docking:SplitContainer>
<docking:ToolWindowContainer MaxWidth="175" MinWidth="175">
<docking:ToolWindow Title="Instruments" x:Name="instrumentToolWindow">
<StackPanel>
<TextBox MaxWidth="100" MaxHeight="30" MinHeight="30" Margin="30" x:Name="textBox1" />
<Button MinWidth="75" MinHeight="30" MaxWidth="75" MaxHeight="30" Content="AddTab" Click="Button_Click" x:Name="button1" />
</StackPanel>
</docking:ToolWindow>
<docking:ToolWindow Title="Test" x:Name="testToolWindow"/>
</docking:ToolWindowContainer>
<docking:Workspace>
<docking:TabbedMdiHost>
<docking:TabbedMdiContainer/>
</docking:TabbedMdiHost>
</docking:Workspace>
</docking:SplitContainer>
</docking:DockSite>
</Grid>
</Window>
Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.ComponentModel;
namespace MVVMDockingTest
{
class TestModel : INotifyPropertyChanged
{
private UserControl testControl = new UserControl();
private string testName;
private string testDescription;
public event PropertyChangedEventHandler PropertyChanged;
public UserControl TestControl
{
get
{
return testControl;
}
set
{
testControl = value;
OnPropertyChanged("TestControl");
}
}
public string TestName
{
get
{
return testName;
}
set
{
testName = value;
OnPropertyChanged("TestName");
}
}
public string TestDescription
{
get
{
return testDescription;
}
set
{
testDescription = value;
OnPropertyChanged("TestDescription");
}
}
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
ViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Collections;
using ActiproSoftware.Windows.Controls.Docking;
namespace MVVMDockingTest
{
class TestViewModel : INotifyPropertyChanged
{
private ObservableCollection<TestModel> testCollection = new ObservableCollection<TestModel>();
private string viewModelName;
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<TestModel> TestCollection
{
get
{
return testCollection;
}
set
{
testCollection = value;
OnPropertyChanged("TestCollection");
}
}
public void addTest(TestModel test)
{
testCollection.Add(test);
OnPropertyChanged("TestCollection");
}
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public string ViewModelName
{
get
{
return viewModelName;
}
set
{
viewModelName = value;
OnPropertyChanged("ViewModelName");
}
}
}
}