# Save/Restore Control Layout | WPF Controls | DevExpress Documentation

DevExpress WPF Controls allow you to save (serialize) their **layouts** to an [XML file](https://docs.microsoft.com/en-us/dotnet/standard/serialization/xml-and-soap-serialization)/[Stream](https://learn.microsoft.com/dotnet/api/system.io.stream) and then restore (deserialize) them. 

DevExpress WPF Controls use the [DXSerializer](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer) class to save/restore their layouts. This class contains [events](/WPF/7410/common-concepts/saving-and-restoring-layouts/advanced-scenarios) that you can use to **customize** the serialization/deserialization processes. Refer to the following section for more information on how to cancel layout restoration, restore items from a collection, and more: Advanced Scenarios.

## Save/Restore a Layout of Individual Controls

1. Define unique Names for a control (and each of its parts) whose layout you want to save/restore. The [DXSerializer](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer) uses these names to identify elements during the save/restore operation.

- XAML

<section id="tabpanel_Y2qYIyVNQq_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;}" data-highlight-lines="[[5],[7],[10]]" class="lang-xaml">&lt;dx:ThemedWindow ...
    xmlns:dx=&quot;http://schemas.devexpress.com/winfx/2008/xaml/core&quot;
    xmlns:dxg=&quot;http://schemas.devexpress.com/winfx/2008/xaml/grid&quot;&gt;
    &lt;Grid&gt;
        &lt;dxg:GridControl x:Name=&quot;gridControl&quot; ...&gt;
            &lt;dxg:GridControl.Bands&gt;
                &lt;dxg:GridControlBand Name=&quot;band1&quot; ... &gt;
                    &lt;!-- ... --&gt;
                &lt;/dxg:GridControlBand&gt;
                &lt;dxg:GridControlBand Name=&quot;band2&quot; ... &gt;
                    &lt;!-- ... --&gt;
                &lt;/dxg:GridControlBand&gt;
            &lt;/dxg:GridControl.Bands&gt;
            &lt;dxg:GridControl.View&gt;
                &lt;dxg:TableView/&gt;
            &lt;/dxg:GridControl.View&gt;
        &lt;/dxg:GridControl&gt;
    &lt;/Grid&gt;
&lt;/dx:ThemedWindow&gt;
</code></pre></section>

     If you [generate the control’s elements from a View Model collection](/WPF/403274/controls-and-libraries/data-grid/mvvm-enhancements/bind-to-collections-specified-in-the-viewmodel), you cannot use bindings to define the element’s `Name` property. Instead, use the `DevExpress.Xpf.Core.XamlHelper.Name` attached property to pass the name specified in a View Model to the element’s `Name` property:

- XAML

<section id="tabpanel_Y2qYIyVNQq-1_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;}" class="lang-xaml">&lt;DataTemplate x:Key=&quot;BandTemplate&quot;&gt;
    &lt;dxg:GridControlBand ...
        dx:XamlHelper.Name=&quot;{Binding Path=(dxci:DependencyObjectExtensions.DataContext).UniqueName, RelativeSource={RelativeSource Self}}&quot;/&gt;
&lt;/DataTemplate&gt;
</code></pre></section>
2. Call the control’s **SaveLayoutTo**\* method to save its layout.

- C#
    - VB.NET

<section id="tabpanel_Y2qYIyVNQq-2_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;,&quot;/ (DevExpress.Xpf.Core.Serialization)(?:;|$)/&quot;:&quot;/WPF/DevExpress.Xpf.Core.Serialization&quot;}" data-highlight-lines="[[6]]" class="lang-csharp">using DevExpress.Xpf.Core.Serialization;
// ...
Stream gridControlLayout = new MemoryStream();

private void Button_Click(object sender, RoutedEventArgs e) {
    gridControl.SaveLayoutToStream(gridControlLayout);
}
</code></pre></section>
<section id="tabpanel_Y2qYIyVNQq-2_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;,&quot;/ (DevExpress.Xpf.Core.Serialization)(?:;|$)/&quot;:&quot;/WPF/DevExpress.Xpf.Core.Serialization&quot;}" data-highlight-lines="[[6]]" class="lang-vb">Imports DevExpress.Xpf.Core.Serialization
&#39;...
Dim gridLayoutStream As Stream = New MemoryStream()

Private Sub Button_Click_2(ByVal sender As Object, ByVal e As RoutedEventArgs)
    gridControl.SaveLayoutToStream(gridControlLayout)
End Sub
</code></pre></section>
3. To restore a control’s layout saved to an **XML file**, call the control’s **RestoreLayoutFromXML** method.
To restore a control’s layout saved to a [Stream](https://learn.microsoft.com/dotnet/api/system.io.stream), call the control’s **RestoreLayoutFromStream** method.

- C#
    - VB.NET

<section id="tabpanel_Y2qYIyVNQq-3_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;,&quot;/ (DevExpress.Xpf.Core.Serialization)(?:;|$)/&quot;:&quot;/WPF/DevExpress.Xpf.Core.Serialization&quot;}" data-highlight-lines="[[4]]" class="lang-csharp">using DevExpress.Xpf.Core.Serialization;
// ...
private void Button_Click_1(object sender, RoutedEventArgs e) {
    gridControl.RestoreLayoutFromStream(gridControlLayout);
}
</code></pre></section>
<section id="tabpanel_Y2qYIyVNQq-3_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;,&quot;/ (DevExpress.Xpf.Core.Serialization)(?:;|$)/&quot;:&quot;/WPF/DevExpress.Xpf.Core.Serialization&quot;}" data-highlight-lines="[[4]]" class="lang-vb">Imports DevExpress.Xpf.Core.Serialization

Private Sub Button_Click_1(ByVal sender As Object, ByVal e As RoutedEventArgs)
    gridControl.RestoreLayoutFromStream(gridLayoutStream)
End Sub 
</code></pre></section>

[View Example: Save Grid Layout and Restore It from a Memory Stream](https://github.com/DevExpress-Examples/wpf-data-grid-save-layout-and-restore-it-from-memory-stream)

[View Example: Use the Layout Upgrade Event to Upgrade a Layout from One Version to Another](https://github.com/DevExpress-Examples/wpf-dock-layout-manager-upgrade-layouts-between-versions)

Note

The serialization mechanism does not save properties that are not set locally and have default values. This mechanism resets all serializable properties to their default values before the restore layout operation.

### Supported Controls and Their Save/Restore Methods

| Control | Save Layout Methods | Restore Layout Methods | Documentation Topic (Control Specifics) | Uses DXSerializer |
| --- | --- | --- | --- | --- |
| Bars | [SaveLayoutToStream(Stream)](/WPF/DevExpress.Xpf.Bars.BarManager.SaveLayoutToStream%28System.IO.Stream%29) | [RestoreLayoutFromStream(Stream)](/WPF/DevExpress.Xpf.Bars.BarManager.RestoreLayoutFromStream%28System.IO.Stream%29) | [Saving and Restoring a Bar Layout](/WPF/7054/controls-and-libraries/ribbon-bars-and-menu/bars/saving-and-restoring-a-bar-layout) | ![yes](/WPF/images/yes.png) |
| [SaveLayoutToXml(String)](/WPF/DevExpress.Xpf.Bars.BarManager.SaveLayoutToXml%28System.String%29) | [RestoreLayoutFromXml(String)](/WPF/DevExpress.Xpf.Bars.BarManager.RestoreLayoutFromXml%28System.String%29) |
| Charts | [SaveToStream(Stream)](/WPF/DevExpress.Xpf.Charts.ChartControl.SaveToStream%28System.IO.Stream%29) | [LoadFromStream(Stream)](/WPF/DevExpress.Xpf.Charts.ChartControl.LoadFromStream%28System.IO.Stream%29) | [Save and Load the Chart Layout](/WPF/400443/controls-and-libraries/charts-suite/chart-control/save-and-load-the-chart-layout) | ![yes](/WPF/images/yes.png) |
| [SaveToFile(String)](/WPF/DevExpress.Xpf.Charts.ChartControl.SaveToFile%28System.String%29) | [LoadFromFile(String)](/WPF/DevExpress.Xpf.Charts.ChartControl.LoadFromFile%28System.String%29) |
| [LayoutControlBase](/WPF/DevExpress.Xpf.LayoutControl.LayoutControlBase) and its descendants ([FlowLayoutControl](/WPF/8148/controls-and-libraries/layout-management/tile-and-layout/flow-layout-control), [TileLayoutControl](/WPF/11541/controls-and-libraries/layout-management/tile-and-layout/tile-layout-control), [LayoutControl](/WPF/8147/controls-and-libraries/layout-management/tile-and-layout/layout-and-data-layout-controls/layout-control), [DataLayoutControl](/WPF/11540/controls-and-libraries/layout-management/tile-and-layout/layout-and-data-layout-controls/data-layout-control)) | [WriteToXML(XmlWriter)](/WPF/DevExpress.Xpf.LayoutControl.LayoutControlBase.WriteToXML%28System.Xml.XmlWriter%29) | [ReadFromXML(XmlReader)](/WPF/DevExpress.Xpf.LayoutControl.LayoutControlBase.ReadFromXML%28System.Xml.XmlReader%29) | [Save and Restore Item Layout](/WPF/8155/controls-and-libraries/layout-management/tile-and-layout/common-features/save-and-restore-item-layout) | ![no](/WPF/images/no.png) |
| DockLayoutManager | [SaveLayoutToStream(Stream)](/WPF/DevExpress.Xpf.Docking.DockLayoutManager.SaveLayoutToStream%28System.IO.Stream%29) | [RestoreLayoutFromStream(Stream)](/WPF/DevExpress.Xpf.Docking.DockLayoutManager.RestoreLayoutFromStream%28System.IO.Stream%29) | [Save and Restore the Layout of Dock Panels and Controls](/WPF/7059/controls-and-libraries/layout-management/dock-windows/saving-and-restoring-the-layout-of-dock-panels-and-controls) | ![yes](/WPF/images/yes.png) |
| [SaveLayoutToXml(String)](/WPF/DevExpress.Xpf.Docking.DockLayoutManager.SaveLayoutToXml%28System.String%29) | [RestoreLayoutFromXml(String)](/WPF/DevExpress.Xpf.Docking.DockLayoutManager.RestoreLayoutFromXml%28System.String%29) |
| DXTabControl | [SaveLayoutToStream(Stream)](/WPF/DevExpress.Xpf.Core.DXTabControl.SaveLayoutToStream%28System.IO.Stream%29) | [RestoreLayoutFromStream(Stream)](/WPF/DevExpress.Xpf.Core.DXTabControl.RestoreLayoutFromStream%28System.IO.Stream%29) | ![no](/WPF/images/no.png) | ![yes](/WPF/images/yes.png) |
| [SaveLayoutToXml(String)](/WPF/DevExpress.Xpf.Core.DXTabControl.SaveLayoutToXml%28System.String%29) | [RestoreLayoutFromXml(String)](/WPF/DevExpress.Xpf.Core.DXTabControl.RestoreLayoutFromXml%28System.String%29) |
| GridControl/TreeListControl/GanttControl | [SaveLayoutToStream(Stream)](/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream%28System.IO.Stream%29) | [RestoreLayoutFromStream(Stream)](/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream%28System.IO.Stream%29) | [Save and Restore Layout](/WPF/6797/controls-and-libraries/data-grid/miscellaneous/save-and-restore-layout) | ![yes](/WPF/images/yes.png) |
| [SaveLayoutToXml(String)](/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToXml%28System.String%29) | [RestoreLayoutFromXml(String)](/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromXml%28System.String%29) |
| PivotGridControl | [SaveLayoutToStream(Stream)](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.SaveLayoutToStream%28System.IO.Stream%29) | [RestoreLayoutFromStream(Stream)](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.RestoreLayoutFromStream%28System.IO.Stream%29) | [Save and Restore Layout](/WPF/8023/controls-and-libraries/pivot-grid/layout/save-and-restore-layout) | ![yes](/WPF/images/yes.png) |
| [RestoreLayoutFromStreamAsync(Stream)](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.RestoreLayoutFromStreamAsync%28System.IO.Stream%29) |
| [SaveLayoutToXml(String)](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.SaveLayoutToXml%28System.String%29) | [RestoreLayoutFromXml(String)](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.RestoreLayoutFromXml%28System.String%29) |
| [RestoreLayoutFromXmlAsync(String)](/WPF/DevExpress.Xpf.PivotGrid.PivotGridControl.RestoreLayoutFromXmlAsync%28System.String%29) |
| RibbonControl | [SaveLayout(String)](/WPF/DevExpress.Xpf.Ribbon.RibbonControl.SaveLayout%28System.String%29) | [RestoreLayout(String)](/WPF/DevExpress.Xpf.Ribbon.RibbonControl.RestoreLayout%28System.String%29) | ![no](/WPF/images/no.png) | ![yes](/WPF/images/yes.png) |
| [SaveDefaultLayout()](/WPF/DevExpress.Xpf.Ribbon.RibbonControl.SaveDefaultLayout) | [RestoreDefaultLayout()](/WPF/DevExpress.Xpf.Ribbon.RibbonControl.RestoreDefaultLayout) |
| ThemedWindow | [SaveLayoutToStream(Stream)](/WPF/DevExpress.Xpf.Core.ThemedWindow.SaveLayoutToStream%28System.IO.Stream%29) | [RestoreLayoutFromStream(Stream)](/WPF/DevExpress.Xpf.Core.ThemedWindow.RestoreLayoutFromStream%28System.IO.Stream%29) | ![no](/WPF/images/no.png) | ![yes](/WPF/images/yes.png) |
| [SaveLayoutToXml(String)](/WPF/DevExpress.Xpf.Core.ThemedWindow.SaveLayoutToXml%28System.String%29) | [RestoreLayoutFromXml(String)](/WPF/DevExpress.Xpf.Core.ThemedWindow.RestoreLayoutFromXml%28System.String%29) |

Note

If a control uses the [DXSerializer](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer) class to save/restore its layout, you can use the [DXSerializer’s events](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer) to customize the control’s serialization/deserialization.

Refer to the following section for more information on how use these events to cancel layout restoration, restore items from a collection, and more: Advanced Scenarios.

### Limitations

- The [WriteToXML(XmlWriter)](/WPF/DevExpress.Xpf.LayoutControl.LayoutControlBase.WriteToXML%28System.Xml.XmlWriter%29) and [ReadFromXML(XmlReader)](/WPF/DevExpress.Xpf.LayoutControl.LayoutControlBase.ReadFromXML%28System.Xml.XmlReader%29) methods of the [LayoutControlBase](/WPF/DevExpress.Xpf.LayoutControl.LayoutControlBase) and its descendants do not use the [DXSerializer](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer) class. Use the [DXSerializer](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer) to **customize** serialization/deserialization of these controls (for example, cancel layout restoration, restore items from a collection, and so on).

      **Section**: Save/Restore Layouts of a Container and its Child Controls
- Each control saves its layout to a separate XML file/[Stream](https://learn.microsoft.com/dotnet/api/system.io.stream).

## Save/Restore Layouts of a Container and its Child Controls

Use the [DXSerializer](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer) to save/restore layouts of a container (Window, View, UserControl, Control) and its child serializable^[1]^ DevExpress WPF Controls to an XML file/[Stream](https://learn.microsoft.com/dotnet/api/system.io.stream).

### Supported Controls

- [Bars](/WPF/6194/controls-and-libraries/ribbon-bars-and-menu/bars)
- [ChartControl](/WPF/115092/controls-and-libraries/charts-suite)
- [Data Layout Control](/WPF/11540/controls-and-libraries/layout-management/tile-and-layout/layout-and-data-layout-controls/data-layout-control)/[LayoutControl](/WPF/8147/controls-and-libraries/layout-management/tile-and-layout/layout-and-data-layout-controls/layout-control)/[TileLayoutControl](/WPF/11541/controls-and-libraries/layout-management/tile-and-layout/tile-layout-control)/[FlowLayoutControl](/WPF/8148/controls-and-libraries/layout-management/tile-and-layout/flow-layout-control)
- [DockLayoutManager](/WPF/6191/controls-and-libraries/layout-management/dock-windows)
- [DXTabControl](/WPF/7974/controls-and-libraries/layout-management/tab-control)
- [GridControl](/WPF/6084/controls-and-libraries/data-grid)/[GanttControl](/WPF/400329/controls-and-libraries/gantt-control)/[TreeListControl](/WPF/9759/controls-and-libraries/tree-list)
- [PivotGridControl](/WPF/7228/controls-and-libraries/pivot-grid)
- [RibbonControl](/WPF/7895/controls-and-libraries/ribbon-bars-and-menu/ribbon)
- [ThemedWindow](/WPF/DevExpress.Xpf.Core.ThemedWindow)

### Limitation

The [DXSerializer](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer) saves/restores layouts of controls that exist in the application’s visual tree. Because of that, it does not save/restore contents of the unopened [DXTabControl](/WPF/DevExpress.Xpf.Core.DXTabControl)/[LayoutGroup](/WPF/DevExpress.Xpf.Docking.LayoutGroup) tabs.

To save/restore layouts of serializable^[1]^ DevExpress WPF Controls that are placed into a [DXTabControl](/WPF/DevExpress.Xpf.Core.DXTabControl)/[LayoutGroup](/WPF/DevExpress.Xpf.Docking.LayoutGroup) tab, set the tab’s [DXTabControl.TabContentCacheMode](/WPF/DevExpress.Xpf.Core.DXTabControl.TabContentCacheMode)/[LayoutGroup.TabContentCacheMode](/WPF/DevExpress.Xpf.Docking.LayoutGroup.TabContentCacheMode) property to [TabContentCacheMode.CacheAllTabs](/WPF/DevExpress.Xpf.Core.TabContentCacheMode). In this case, the tab loads its contents to a visual tree when the control is loaded.

[View Example: Serialize DockLayoutManager When TabbedDocumentUIService Is Used](https://github.com/DevExpress-Examples/wpf-docklayoutmanager-serialize-docklayoutmanager-when-tabbeddocumentuiservice-is-used)

### Save (Serialize) Layout

1. Choose the target object whose layout you want to save/restore. It can be any parent container (Window, View, UserControl) that stores a serializable^[1]^ DevExpress WPF Control.
2. If your target object contains multiple serializable^[1]^ child objects of the same type, specify unique [SerializationID](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer.SerializationID)s (within the container) for each of these objects.

Note

RibbonControl and each instance of its category/page/group should also have unique [SerializationID](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer.SerializationID) attached property values.
3. Call any [DXSerializer.Serialize](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer.Serialize.overloads) method. [Serialize](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer.Serialize.overloads) methods save layouts of visual DevExpress controls to a single XML file/[Stream](https://learn.microsoft.com/dotnet/api/system.io.stream).
4. Call any [DXSerializer.Serialize](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer.Serialize.overloads) method. These methods save the layout of visual DevExpress controls to a single XML file/[Stream](https://learn.microsoft.com/dotnet/api/system.io.stream).

The following code saves the layout of the window and its child GridControls to an XML file:

- XAML

<section id="tabpanel_Y2qYIyVNQq-4_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;}" class="lang-xaml">&lt;Window . . .
    xmlns:dx=&quot;http://schemas.devexpress.com/winfx/2008/xaml/core&quot;
    x:Name=&quot;mainWindow&quot;&gt;
    &lt;Grid&gt;
        &lt;dxg:GridControl dx:DXSerializer.SerializationID=&quot;gridControl1&quot;&gt;
            &lt;!--...--&gt;
        &lt;/dxg:GridControl&gt;
        &lt;dxg:GridControl dx:DXSerializer.SerializationID=&quot;gridControl2&quot;&gt;
            &lt;!--...--&gt;
        &lt;/dxg:GridControl&gt;
    &lt;/Grid&gt;
&lt;/Window&gt;
</code></pre></section>

- C#
- VB.NET

<section id="tabpanel_Y2qYIyVNQq-5_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;,&quot;/ (DevExpress.Xpf.Core.Serialization)(?:;|$)/&quot;:&quot;/WPF/DevExpress.Xpf.Core.Serialization&quot;}" class="lang-csharp">using DevExpress.Xpf.Core.Serialization;

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
    DXSerializer.Serialize(mainWindow, &quot;Layout.xml&quot;);
}
</code></pre></section>
<section id="tabpanel_Y2qYIyVNQq-5_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;,&quot;/ (DevExpress.Xpf.Core.Serialization)(?:;|$)/&quot;:&quot;/WPF/DevExpress.Xpf.Core.Serialization&quot;}" class="lang-vb">Imports DevExpress.Xpf.Core.Serialization

Private Sub Window_Closing(ByVal sender As Object, ByVal e As RoutedEventArgs)
    DXSerializer.Serialize(mainWindow, &quot;Layout.xml&quot;);
End Sub 
</code></pre></section>

### Restore (Deserialize) Layout

To restore a saved layout, you should use the [DXSerializer.Deserialize](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer.Deserialize.overloads) method that corresponds to the saved layout structure (an XML file or a [Stream](https://learn.microsoft.com/dotnet/api/system.io.stream)).

For example, if you saved a control’s layout to a [Stream](https://learn.microsoft.com/dotnet/api/system.io.stream) (with the [DXSerializer.Serialize(DependencyObject,String)](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer.Serialize%28DependencyObject----String--String--DXOptionsLayout--SerializationType%29) method), you should call the [DXSerializer.Deserialize(DependencyObject,String)](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer.Deserialize%28DependencyObject--Stream--String--DXOptionsLayout--SerializationType%29) method to restore the saved layout from that [Stream](https://learn.microsoft.com/dotnet/api/system.io.stream).

The following code restores layouts of the *mainWindow* and its child GridControls that you saved in the previous section:

- C#
- VB.NET

<section id="tabpanel_Y2qYIyVNQq-6_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;,&quot;/ (DevExpress.Xpf.Core.Serialization)(?:;|$)/&quot;:&quot;/WPF/DevExpress.Xpf.Core.Serialization&quot;}" class="lang-csharp">using DevExpress.Xpf.Core.Serialization;

private void Window_Loaded(object sender, RoutedEventArgs e) {
    DXSerializer.Deserialize(mainWindow, &quot;Layout.xml&quot;);
}
</code></pre></section>
<section id="tabpanel_Y2qYIyVNQq-6_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;,&quot;/ (DevExpress.Xpf.Core.Serialization)(?:;|$)/&quot;:&quot;/WPF/DevExpress.Xpf.Core.Serialization&quot;}" class="lang-vb">Imports DevExpress.Xpf.Core.Serialization

Private Sub Window_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
    DXSerializer.Deserialize(mainWindow, &quot;Layout.xml&quot;);
End Sub 
</code></pre></section>

## MVVM Support

To save/restore an application layout in MVVM applications, you can use the [LayoutSerializationService](/WPF/114419/mvvm-framework/services/predefined-set/layoutserializationservice) and [CurrentWindowSerializationBehavior](/WPF/DevExpress.Mvvm.UI.CurrentWindowSerializationBehavior) classes.

[View Example: Serialize/Deserialize a View's Size and State with LayoutSerializationService and CurrentWindowSerializationBehavior](https://github.com/DevExpress-Examples/wpf-mvvm-behaviors-currentwindowserializationbehavior)

These classes are based on the [DXSerializer](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer) and you can use its events to customize a layout’s save/restore processes.

**Section**: Advanced Scenarios

## Save and Restore an Applied Theme

Call the [SaveApplicationThemeName](/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName)/[UpdateApplicationThemeName](/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName) methods to save/restore the theme applied to your application, respectively.

The following code sample saves the applied theme on application exit and restores it on application startup:

- App.xaml.cs
- Application.xaml.vb

<section id="tabpanel_Y2qYIyVNQq-7_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;}" class="lang-csharp">public partial class App : Application {
    protected override void OnStartup(StartupEventArgs e) {
        base.OnStartup(e);
        DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName();
    }
    protected override void OnExit(ExitEventArgs e) {
        base.OnExit(e);
        DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName();
    }
    private void OnAppStartup_UpdateThemeName(object sender, StartupEventArgs e) {
        DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName();
    }
}
</code></pre></section>
<section id="tabpanel_Y2qYIyVNQq-7_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;}" class="lang-vb">Partial Public Class App
    Inherits Application

    Protected Overrides Sub OnStartup(ByVal e As StartupEventArgs)
        MyBase.OnStartup(e)
        DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName()
    End Sub
    Protected Overrides Sub OnExit(ByVal e As ExitEventArgs)
        MyBase.OnExit(e)
        DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName()
    End Sub
    Private Sub OnAppStartup_UpdateThemeName(ByVal sender As Object, ByVal e As StartupEventArgs)
        DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName()
    End Sub
End Class
</code></pre></section>

## Increase Performance of the First Restore Layout Operation

The serialization mechanism caches property descriptors, attributes, and so on when you restore the control layout for the first time. As a result, the first restore action takes more time than subsequent actions. Execute the first restore operation asynchronously on application startup to avoid this behavior:

- C#
- VB.NET

<section id="tabpanel_Y2qYIyVNQq-8_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;}" class="lang-csharp">public partial class App : Application {
    protected override void OnStartup(StartupEventArgs e) {
        base.OnStartup(e);
        Dispatcher.BeginInvoke(
            new Action(() =&gt; {
                GridControl grid = new GridControl();
                grid.View = new TableView();
                grid.RestoreLayoutFromXml(&quot;Layout.xml&quot;);
            }), 
            DispatcherPriority.ApplicationIdle
        );
    }
}
</code></pre></section>
<section id="tabpanel_Y2qYIyVNQq-8_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code data-code-links="{&quot;SaveLayoutToStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.SaveLayoutToStream(System.IO.Stream)&quot;,&quot;RestoreLayoutFromStream&quot;:&quot;/WPF/DevExpress.Xpf.Grid.DataControlBase.RestoreLayoutFromStream(System.IO.Stream)&quot;,&quot;SaveApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.SaveApplicationThemeName&quot;,&quot;UpdateApplicationThemeName&quot;:&quot;/WPF/DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName&quot;}" class="lang-vb">Public Partial Class App
    Inherits Application

    Protected Overrides Sub OnStartup(ByVal e As StartupEventArgs)
        MyBase.OnStartup(e)
        Dispatcher.BeginInvoke(New Action(Function()
            Dim grid As GridControl = New GridControl()
            grid.View = New TableView()
            grid.RestoreLayoutFromXml(&quot;Layout.xml&quot;)
        End Function), DispatcherPriority.ApplicationIdle)
    End Sub
End Class
</code></pre></section>

## Advanced Scenarios

You can use the [DXSerializer](/WPF/DevExpress.Xpf.Core.Serialization.DXSerializer)‘s events to perform the following actions: 

- [Save/restore a custom property of a DevExpress WPF Control descendant](/WPF/7410/common-concepts/saving-and-restoring-layouts/advanced-scenarios#serializedeserialize-custom-properties-of-a-devexpress-wpf-control-descendant)
- [Serialize your attached properties](/WPF/7410/common-concepts/saving-and-restoring-layouts/advanced-scenarios#serialize-custom-attached-properties)
- [Serialize standard and custom controls](/WPF/7410/common-concepts/saving-and-restoring-layouts/advanced-scenarios#serialize-standard-and-custom-controls)
- [Prevent restoration of a control’s predefined property](/WPF/7410/common-concepts/saving-and-restoring-layouts/advanced-scenarios#do-not-restore-a-controls-predefined-property)
- [Stop layout restoration (deserialization)](/WPF/7410/common-concepts/saving-and-restoring-layouts/advanced-scenarios#stop-layout-restore-deserialization)
- [Restore items from a saved (serialized) collection](/WPF/7410/common-concepts/saving-and-restoring-layouts/advanced-scenarios#restore-items-from-a-saved-serialized-collection)
- [Save controls that do not exist in the visual Tree](/WPF/7410/common-concepts/saving-and-restoring-layouts/advanced-scenarios#save-controls-that-do-not-exist-in-the-visual-tree)
- [Save properties that are not marked with the XtraSerializablePropertyAttribute](/WPF/7410/common-concepts/saving-and-restoring-layouts/advanced-scenarios#serialize-properties-that-are-not-marked-with-the-xtraserializablepropertyattribute)
- [Update layout between different versions of your application](/WPF/7410/common-concepts/saving-and-restoring-layouts/advanced-scenarios#update-layout-between-different-versions-of-your-application)
- [Create a custom property deserialization handler](/WPF/7410/common-concepts/saving-and-restoring-layouts/advanced-scenarios#create-a-custom-property-deserialization-handler)

**Topic**: [DXSerializer Events - Advanced Scenarios](/WPF/7410/common-concepts/saving-and-restoring-layouts/advanced-scenarios)

Footnotes

1. DevExpress WPF Controls that support the save/restore layout feature.