Using the DockingCustomPropertyProvider I save the docking settings. When I try to load them back up, (after I have unpinned a panel) I get the following error: The given key was not present in the dictionary.
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using Telerik.Windows.Controls;using Telerik.Windows.Persistence.Services;namespace BasicDockingPersistenceExample{ public class DockingCustomPropertyProvider : ICustomPropertyProvider { public CustomPropertyInfo[] GetCustomProperties() { // Create two custom properties to serialize the Layout of the RadDocking and the Content of the RadPanes return new CustomPropertyInfo[] { new CustomPropertyInfo("Layout", typeof (string)), new CustomPropertyInfo("Content", typeof (List<PaneProxy>)) {AllowCreateInstance = false, TreatAsUI = false}, }; } public void InitializeObject(object context) { } public object InitializeValue(CustomPropertyInfo customPropertyInfo, object context) { if (customPropertyInfo.Name == "Content") { // See remarks in ProvideValue method: // provide the values on which the saved properties will be restored upon RadDocking docking = context as RadDocking; List<PaneProxy> proxies = new List<PaneProxy>(); foreach (RadPane pane in this.GetOrderedPanes(docking).ToArray()) { proxies.Add(new PaneProxy() { Content = pane.Content }); } return proxies; } return null; } public object ProvideValue(CustomPropertyInfo customPropertyInfo, object context) { RadDocking docking = context as RadDocking; if (customPropertyInfo.Name == "Layout") { // let the RadDocking save the layout of the Panes: return this.SaveLayoutAsString(docking); } else if (customPropertyInfo.Name == "Content") { // create proxies for all of the Panes and save their content IEnumerable<RadPane> panes = this.GetOrderedPanes(docking); List<PaneProxy> proxies = new List<PaneProxy>(); foreach (RadPane pane in panes) { proxies.Add(new PaneProxy() { Content = pane.Content }); } return proxies; } return null; } public void RestoreValue(CustomPropertyInfo customPropertyInfo, object context, object value) { if (customPropertyInfo.Name == "Layout") { // let the RadDocking load the layout of the RadPanes this.LoadLayoutFromString(value.ToString(), context as RadDocking); } else if (customPropertyInfo.Name == "Content") { // the PersistenceManager does not re-create UI elements - in this case the Content of the RadPane. // So, instead of providing a value on which the saved properties will be applied, // we will use the InitializeValue method. } } private string SaveLayoutAsString(RadDocking instance) { MemoryStream stream = new MemoryStream(); instance.SaveLayout(stream); stream.Seek(0, SeekOrigin.Begin); StreamReader reader = new StreamReader(stream); return reader.ReadToEnd(); } private void LoadLayoutFromString(string xml, RadDocking instance) { using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(xml))) { stream.Seek(0, SeekOrigin.Begin); instance.LoadLayout(stream); } } private IEnumerable<RadPane> GetOrderedPanes(RadDocking docking) { // get the RadPanes always in the same order: RadPane[] array = docking.Panes.ToArray(); Array.Sort(array, new RadPaneComparer()); return array; } } public class RadPaneComparer : IComparer<RadPane> { int IComparer<RadPane>.Compare(RadPane x, RadPane y) { // compare RadPanes by their serialization tag: string xSerializationTag = RadDocking.GetSerializationTag(x); string ySerializationTag = RadDocking.GetSerializationTag(y); return xSerializationTag.CompareTo(ySerializationTag); } } public class PaneProxy { public object Content { get; set; } }}using System;using System.Collections.Generic;using System.ComponentModel;using System.Linq;using System.Text;namespace BasicDockingPersistenceExample{ public class MainWindowViewModel : INotifyPropertyChanged { public MainWindowViewModel() { } #region DockPanel pinning properties private bool? _pane2PanelIsPinned = false; public bool? Pane2PanelIsPinned { get { return _pane2PanelIsPinned; } set { _pane2PanelIsPinned = value; FirePropertyChanged("Pane2PanelIsPinned"); } } private bool? _pane1PanelIsPinned = false; public bool? Pane1PanelIsPinned { get { return _pane1PanelIsPinned; } set { _pane1PanelIsPinned = value; FirePropertyChanged("Pane1PanelIsPinned"); } } private bool? _pane5PanelIsPinned = false; public bool? Pane5PanelIsPinned { get { return _pane5PanelIsPinned; } set { _pane5PanelIsPinned = value; FirePropertyChanged("Pane5PanelIsPinned"); } } private bool? _pane3PanelIsPinned = true; public bool? Pane3PanelIsPinned { get { return _pane3PanelIsPinned; } set { _pane3PanelIsPinned = value; FirePropertyChanged("Pane3PanelIsPinned"); } } private bool? _pane4PanelIsPinned = true; public bool? Pane4PanelIsPinned { get { return _pane4PanelIsPinned; } set { _pane4PanelIsPinned = value; FirePropertyChanged("Pane4PanelIsPinned"); } } #endregion public event PropertyChangedEventHandler PropertyChanged; protected void FirePropertyChanged(string property) { //Should only be called by ViewModel base class. Derived classes should use lambda/LINQ syntax to simplify refactoring if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(property)); } }}using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;using Telerik.Windows.Controls;using Telerik.Windows.Persistence.Services;using Telerik.Windows.Persistence.Storage;namespace BasicDockingPersistenceExample{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { ServiceProvider.RegisterPersistenceProvider<ICustomPropertyProvider>(typeof(RadDocking), new DockingCustomPropertyProvider()); this.DataContext = new MainWindowViewModel(); InitializeComponent(); Dispatcher.ShutdownStarted += new EventHandler(DispatcherShutdownStarted); } private void DispatcherShutdownStarted(object sender, EventArgs e) { Dispatcher.ShutdownStarted -= new EventHandler(DispatcherShutdownStarted); SaveLayout(); } private void SaveLayout() { var storage = new IsolatedStorageProvider(); storage.SaveToStorage(); } private void LoadLayout() { var storage = new IsolatedStorageProvider(); storage.LoadFromStorage(); } private void BuildDockingLoaded(object sender, RoutedEventArgs e) { LoadLayout(); } }}<Window x:Class="BasicDockingPersistenceExample.MainWindow" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" Title="MainWindow" Height="588" Width="876"> <telerik:RadDocking x:Name="BuildDocking" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Padding="2" HasDocumentHost="False" Loaded="BuildDockingLoaded" telerik:PersistenceManager.StorageId="BuildDocking"> <telerik:RadSplitContainer Orientation="Horizontal" InitialPosition="DockedBottom"> <telerik:RadPaneGroup > <telerik:RadPane x:Name="Pane1Panel" Header="Pane 1" telerik:RadDocking.SerializationTag="Pane1Panel" IsPinned="{Binding Path=Pane1PanelIsPinned, Mode=TwoWay}" CanUserClose="False" CanDockInDocumentHost="False"> </telerik:RadPane> </telerik:RadPaneGroup> </telerik:RadSplitContainer> <telerik:RadSplitContainer Orientation="Horizontal" InitialPosition="DockedLeft" > <telerik:RadPaneGroup telerik:ProportionalStackPanel.RelativeSize="200, 300"> <telerik:RadPane x:Name="Pane2Panel" Header="Pane 2" telerik:RadDocking.SerializationTag="Pane2Panel" IsPinned="{Binding Path=Pane2PanelIsPinned, Mode=TwoWay}" CanUserClose="False" CanDockInDocumentHost="False"> </telerik:RadPane> </telerik:RadPaneGroup> </telerik:RadSplitContainer> <telerik:RadSplitContainer Orientation="Horizontal" InitialPosition="DockedRight" MinWidth="300"> <telerik:RadPaneGroup > <telerik:RadPane Header="Pane 3" x:Name="Pane3Panel" telerik:RadDocking.SerializationTag="Pane3Panel" IsPinned="{Binding Path=Pane3PanelIsPinned, Mode=TwoWay}" CanUserClose="False" CanDockInDocumentHost="False" > </telerik:RadPane> </telerik:RadPaneGroup> </telerik:RadSplitContainer> <telerik:RadSplitContainer Orientation="Vertical" InitialPosition="DockedTop" MinHeight="100" > <telerik:RadPaneGroup > <telerik:RadPane Header="Pane 4" x:Name="Pane4Panel" telerik:RadDocking.SerializationTag="Pane4Panel" IsPinned="{Binding Path=Pane4PanelIsPinned, Mode=TwoWay}" CanUserClose="False" CanDockInDocumentHost="False" > </telerik:RadPane> </telerik:RadPaneGroup> </telerik:RadSplitContainer> <telerik:RadSplitContainer Orientation="Vertical" InitialPosition="DockedTop" MinHeight="100" > <telerik:RadPaneGroup > <telerik:RadPane Header="Pane 5" x:Name="Pane5Panel" telerik:RadDocking.SerializationTag="Pane5Panel" IsPinned="{Binding Path=Pane5PanelIsPinned, Mode=TwoWay}" CanUserClose="False" CanDockInDocumentHost="False" > </telerik:RadPane> </telerik:RadPaneGroup> </telerik:RadSplitContainer> </telerik:RadDocking></Window>