LayoutSerializationService is an ILayoutSerializationService implementation that allows you to save/restore layout of serializable DevExpress WPF Controls located on a View.(i.e., DXGrid, DXPivotGrid, DXDocking, DXBars and DXLayoutControl).
Getting Started with the LayoutSerializationService
To save/restore a layout of your View and its child element, add the LayoutSerializationService to the View’s Interaction.Behaviors collection.
<UserControl x:Class="LayoutSerializationService.Views.MainView"
...
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:ViewModels="clr-namespace:LayoutSerializationService.ViewModels"
DataContext="{dxmvvm:ViewModelSource Type=ViewModels:MainViewModel}">
...
<dxmvvm:Interaction.Behaviors>
<dxmvvm:LayoutSerializationService />
</dxmvvm:Interaction.Behaviors>
...
</UserControl>
Refer to the following help topic for more information: Add Behaviors in XAML.
Then, use one of the following ways to access the defined service.
Next, call the service’s Serialize/Deserialize method to save/restore the View’s layout respectively. The Serialize method returns a string object that contains layout settings that you can restore by using the Deserialize method in the sequel. To restore a specific layout, pass the corresponding string object to the Deserialize method using its parameter.
When the Serialize/Deserialize method is invoked, the LayoutSerializationService iterates through visual tree elements and saves/restores the layout of controls supporting serialization and their child elements by using the DXSerializer methods. Therefore, to properly perform serialization and deserialization, follow the recommendations described in the Save/Restore Control Layout topic.
Serialization Capabilities
To prevent a specific control and its child elements from being serialized/deserialized, set the DXSerializer.Enabled attached property to false
for this control.
Example
View Example
using System;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using DocumentManagerSerialization.Properties;
using System.Collections.Generic;
using DocumentManagerSerialization.Common;
namespace DocumentManagerSerialization.ViewModels {
[POCOViewModel]
public class MainViewModel : ISupportLogicalLayout {
public IDocumentManagerService DocumentManagerService { get { return this.GetService<IDocumentManagerService>(); } }
public ILayoutSerializationService LayoutSerializationService { get { return this.GetService<ILayoutSerializationService>(); } }
public virtual ViewModelState State { get; set; }
public MainViewModel() {
State = new ViewModelState() { State = "I'm Root!" };
}
[Command]
public void OnWindowClosing() {
Settings.Default.LogicalLayout = this.SerializeDocumentManagerService();
Settings.Default.RootLayout = LayoutSerializationService.Serialize();
Settings.Default.Save();
}
[Command]
public void OnWindowLoaded() {
if (Settings.Default.LogicalLayout != null) {
this.RestoreDocumentManagerService(Settings.Default.LogicalLayout);
}
if (Settings.Default.RootLayout != null) {
LayoutSerializationService.Deserialize(Settings.Default.RootLayout);
}
}
[Command]
public void OpenDocument() {
var document = DocumentManagerService.CreateDocument("DocumentView", null, this);
document.Id = "Document" + Guid.NewGuid().ToString().Replace("-", "");
document.DestroyOnClose = false;
document.Title = "Root Document";
document.Show();
}
#region ISupportLogicalLayout
public bool CanSerialize {
get { return true; }
}
public IEnumerable<object> LookupViewModels {
get { return null; }
}
#endregion
}
}
using System;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.Mvvm;
using DevExpress.Mvvm.POCO;
using System.Collections.Generic;
using DocumentManagerSerialization.Common;
namespace DocumentManagerSerialization.ViewModels {
[POCOViewModel]
public class DocumentViewModel : ISupportLogicalLayout<ViewModelState>, ISupportParentViewModel, IDocumentContent {
public IDocumentManagerService DocumentManagerService { get { return this.GetService<IDocumentManagerService>(); } }
public virtual string Caption { get; set; }
public virtual bool CanBeClosed { get; set; }
public virtual ViewModelState State { get; set; }
public DocumentViewModel() {
State = new ViewModelState() { State = "Default State" };
}
public void OpenChildDocument() {
var document = DocumentManagerService.CreateDocument("DocumentView", null, this);
document.DestroyOnClose = false;
document.Title = "Child Document";
document.Id = "Child" + Guid.NewGuid().ToString().Replace("-", "");
document.Show();
}
public ViewModelState SaveState() {
return State;
}
public void RestoreState(ViewModelState state) {
State = state;
}
#region ISupportLogicalLayout
bool ISupportLogicalLayout.CanSerialize {
get { return !String.IsNullOrEmpty(State.State); }
}
public IEnumerable<object> LookupViewModels {
get { return null; }
}
#endregion
#region ISupportParentViewModel
public virtual object ParentViewModel { get; set; }
#endregion
#region IDocumentContent
public IDocumentOwner DocumentOwner { get; set; }
public void OnClose(System.ComponentModel.CancelEventArgs e) {
e.Cancel = !CanBeClosed;
}
public void OnDestroy() { }
public object Title {
get { return Caption; }
}
#endregion
}
}
<UserControl x:Class="DocumentManagerSerialization.Views.DocumentView"
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:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:ViewModels="clr-namespace:DocumentManagerSerialization.ViewModels"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"
DataContext="{dxmvvm:ViewModelSource Type=ViewModels:DocumentViewModel}">
<DockPanel>
<dxb:ToolBarControl DockPanel.Dock="Top">
<dxb:ToolBarControl.Items>
<dxb:BarButtonItem Content="New Sub Document" BarItemDisplayMode="ContentAndGlyph" Glyph="{dx:DXImage Image=New_16x16.png}" Command="{Binding OpenChildDocumentCommand}"/>
<dxb:BarEditItem Content="Document state: " EditValue="{Binding State.State, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }">
<dxb:BarEditItem.EditSettings>
<dxe:TextEditSettings/>
</dxb:BarEditItem.EditSettings>
</dxb:BarEditItem>
<dxb:BarEditItem Content="Can be Closed" EditValue="{Binding CanBeClosed, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }">
<dxb:BarEditItem.EditSettings>
<dxe:CheckEditSettings/>
</dxb:BarEditItem.EditSettings>
</dxb:BarEditItem>
</dxb:ToolBarControl.Items>
</dxb:ToolBarControl>
<dxb:StatusBarControl DockPanel.Dock="Bottom">
<dxb:StatusBarControl.Items>
<dxb:BarStaticItem Content="{Binding ParentViewModel.State.State}">
<dxb:BarStaticItem.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Parent's state: "/>
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</dxb:BarStaticItem.ContentTemplate>
</dxb:BarStaticItem>
</dxb:StatusBarControl.Items>
</dxb:StatusBarControl>
<Border>
<TextBlock Text="Document" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="32"/>
</Border>
</DockPanel>
</UserControl>
<UserControl x:Class="DocumentManagerSerialization.Views.MainView"
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:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
xmlns:ViewModels="clr-namespace:DocumentManagerSerialization.ViewModels"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"
DataContext="{dxmvvm:ViewModelSource Type=ViewModels:MainViewModel}">
<DockPanel>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:CurrentWindowSerializationBehavior/>
<dxmvvm:LayoutSerializationService/>
<dxmvvm:CurrentWindowService ClosingCommand="{Binding OnWindowClosingCommand}"/>
<dxmvvm:EventToCommand EventName="Initialized" Command="{Binding OnWindowLoadedCommand}"/>
</dxmvvm:Interaction.Behaviors>
<dxb:MainMenuControl DockPanel.Dock="Top">
<dxb:MainMenuControl.Items>
<dxb:BarButtonItem Content="New Root Document" Command="{Binding OpenDocumentCommand}"/>
<dxb:BarSplitButtonItem Content="Thems">
<dxmvvm:Interaction.Behaviors>
<dxb:BarSplitItemThemeSelectorBehavior/>
</dxmvvm:Interaction.Behaviors>
</dxb:BarSplitButtonItem>
</dxb:MainMenuControl.Items>
</dxb:MainMenuControl>
<dxdo:DockLayoutManager>
<dxdo:LayoutGroup Caption="LayoutRoot">
<dxdo:DocumentGroup x:Name="documentGroup" DestroyOnClosingChildren="False">
<dxmvvm:Interaction.Behaviors>
<dxdo:DockingDocumentUIService/>
</dxmvvm:Interaction.Behaviors>
</dxdo:DocumentGroup>
</dxdo:LayoutGroup>
</dxdo:DockLayoutManager>
</DockPanel>
</UserControl>
using DevExpress.Mvvm;
namespace DocumentManagerSerialization.Common {
public class ViewModelState : ViewModelBase {
public string State {
get { return GetProperty(() => State); }
set { SetProperty(() => State, value); }
}
public string FullOwnerName {
get { return GetProperty(() => FullOwnerName); }
set { SetProperty(() => FullOwnerName, value); }
}
}
}
Imports DevExpress.Mvvm
Namespace DocumentManagerSerialization.Common
Public Class ViewModelState
Inherits ViewModelBase
Public Property State() As String
Get
Return GetProperty(Function() State)
End Get
Set(ByVal value As String)
SetProperty(Function() State, value)
End Set
End Property
Public Property FullOwnerName() As String
Get
Return GetProperty(Function() FullOwnerName)
End Get
Set(ByVal value As String)
SetProperty(Function() FullOwnerName, value)
End Set
End Property
End Class
End Namespace
Imports System
Imports DevExpress.Mvvm.DataAnnotations
Imports DevExpress.Mvvm
Imports DevExpress.Mvvm.POCO
Imports System.Collections.Generic
Imports DocumentManagerSerialization.Common
Namespace DocumentManagerSerialization.ViewModels
<POCOViewModel> _
Public Class DocumentViewModel
Implements ISupportLogicalLayout(Of ViewModelState), ISupportParentViewModel, IDocumentContent
Public ReadOnly Property DocumentManagerService() As IDocumentManagerService Implements ISupportLogicalLayout(Of DocumentManagerSerialization.Common.ViewModelState).DocumentManagerService
Get
Return Me.GetService(Of IDocumentManagerService)()
End Get
End Property
Public Overridable Property Caption() As String
Public Overridable Property CanBeClosed() As Boolean
Public Overridable Property State() As ViewModelState
Public Sub New()
State = New ViewModelState() With {.State = "Default State"}
End Sub
Public Sub OpenChildDocument()
Dim document = DocumentManagerService.CreateDocument("DocumentView", Nothing, Me)
document.DestroyOnClose = False
document.Title = "Child Document"
document.Id = "Child" & Guid.NewGuid().ToString().Replace("-", "")
document.Show()
End Sub
#Region "ISupportLogicalLayout"
Public Function SaveState() As ViewModelState Implements ISupportLogicalLayout(Of DocumentManagerSerialization.Common.ViewModelState).SaveState
Return State
End Function
Public Sub RestoreState(ByVal state As ViewModelState) Implements ISupportLogicalLayout(Of DocumentManagerSerialization.Common.ViewModelState).RestoreState
Me.State = state
End Sub
Private ReadOnly Property ISupportLogicalLayout_CanSerialize() As Boolean Implements ISupportLogicalLayout.CanSerialize
Get
Return Not String.IsNullOrEmpty(State.State)
End Get
End Property
Public ReadOnly Property LookupViewModels() As IEnumerable(Of Object) Implements ISupportLogicalLayout.LookupViewModels
Get
Return Nothing
End Get
End Property
#End Region
#Region "ISupportParentViewModel"
Public Overridable Property ParentViewModel() As Object Implements ISupportParentViewModel.ParentViewModel
#End Region
#Region "IDocumentContent"
Public Property DocumentOwner() As IDocumentOwner Implements IDocumentContent.DocumentOwner
Public Sub OnClose(ByVal e As System.ComponentModel.CancelEventArgs) Implements IDocumentContent.OnClose
e.Cancel = Not CanBeClosed
End Sub
Public Sub OnDestroy() Implements IDocumentContent.OnDestroy
End Sub
Public ReadOnly Property Title() As Object Implements IDocumentContent.Title
Get
Return Caption
End Get
End Property
#End Region
End Class
End Namespace
Imports System
Imports DevExpress.Mvvm.DataAnnotations
Imports DevExpress.Mvvm
Imports DevExpress.Mvvm.POCO
Imports System.Collections.Generic
Imports DocumentManagerSerialization.Common
Namespace DocumentManagerSerialization.ViewModels
<POCOViewModel> _
Public Class MainViewModel
Implements ISupportLogicalLayout
Public ReadOnly Property DocumentManagerService() As IDocumentManagerService Implements ISupportLogicalLayout.DocumentManagerService
Get
Return Me.GetService(Of IDocumentManagerService)()
End Get
End Property
Public ReadOnly Property LayoutSerializationService() As ILayoutSerializationService
Get
Return Me.GetService(Of ILayoutSerializationService)()
End Get
End Property
Public Overridable Property State() As ViewModelState
Public Sub New()
State = New ViewModelState() With {.State = "I'm Root!"}
End Sub
<Command> _
Public Sub OnWindowClosing()
My.Settings.Default.LogicalLayout = Me.SerializeDocumentManagerService()
My.Settings.Default.RootLayout = LayoutSerializationService.Serialize()
My.Settings.Default.Save()
End Sub
<Command> _
Public Sub OnWindowLoaded()
If My.Settings.Default.LogicalLayout IsNot Nothing Then
Me.RestoreDocumentManagerService(My.Settings.Default.LogicalLayout)
End If
If My.Settings.Default.RootLayout IsNot Nothing Then
LayoutSerializationService.Deserialize(My.Settings.Default.RootLayout)
End If
End Sub
<Command> _
Public Sub OpenDocument()
Dim document = DocumentManagerService.CreateDocument("DocumentView", Nothing, Me)
document.Id = "Document" & Guid.NewGuid().ToString().Replace("-", "")
document.DestroyOnClose = False
document.Title = "Root Document"
document.Show()
End Sub
#Region "ISupportLogicalLayout"
Public ReadOnly Property CanSerialize() As Boolean Implements ISupportLogicalLayout.CanSerialize
Get
Return True
End Get
End Property
Public ReadOnly Property LookupViewModels() As IEnumerable(Of Object) Implements ISupportLogicalLayout.LookupViewModels
Get
Return Nothing
End Get
End Property
#End Region
End Class
End Namespace
See Also