Skip to main content

Save/Restore Control Layout

  • 7 minutes to read

DevExpress WPF Controls allow you to save (serialize) their layouts to an XML file/Stream and then restore (deserialize) them.

DevExpress WPF Controls use the DXSerializer class to save/restore their layouts. This class contains events 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 uses these names to identify elements during the save/restore operation.

    <dx:ThemedWindow ...
        xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
        xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid">
        <Grid>
            <dxg:GridControl x:Name="gridControl" ...>
                <dxg:GridControl.Bands>
                    <dxg:GridControlBand Name="band1" ... >
                        <!-- ... -->
                    </dxg:GridControlBand>
                    <dxg:GridControlBand Name="band2" ... >
                        <!-- ... -->
                    </dxg:GridControlBand>
                </dxg:GridControl.Bands>
                <dxg:GridControl.View>
                    <dxg:TableView/>
                </dxg:GridControl.View>
            </dxg:GridControl>
        </Grid>
    </dx:ThemedWindow>
    

    If you generate the control’s elements from a View Model collection, 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:

    <DataTemplate x:Key="BandTemplate">
        <dxg:GridControlBand ...
            dx:XamlHelper.Name="{Binding Path=(dxci:DependencyObjectExtensions.DataContext).UniqueName, RelativeSource={RelativeSource Self}}"/>
    </DataTemplate>
    
  2. Call the control’s SaveLayoutTo* method to save its layout.

    using DevExpress.Xpf.Core.Serialization;
    // ...
    Stream gridControlLayout = new MemoryStream();
    
    private void Button_Click(object sender, RoutedEventArgs e) {
        gridControl.SaveLayoutToStream(gridControlLayout);
    }
    
  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, call the control’s RestoreLayoutFromStream method.

    using DevExpress.Xpf.Core.Serialization;
    // ...
    private void Button_Click_1(object sender, RoutedEventArgs e) {
        gridControl.RestoreLayoutFromStream(gridControlLayout);
    }
    

View Example: How to Save Grid Layout to and Restore It from a memory stream

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)

RestoreLayoutFromStream(Stream)

Saving and Restoring a Bar Layout

yes

SaveLayoutToXml(String)

RestoreLayoutFromXml(String)

Charts

SaveToStream(Stream)

LoadFromStream(Stream)

Save and Load the Chart Layout

yes

SaveToFile(String)

LoadFromFile(String)

LayoutControlBase and its descendants (FlowLayoutControl, TileLayoutControl, LayoutControl, DataLayoutControl)

WriteToXML(XmlWriter)

ReadFromXML(XmlReader)

Save and Restore Item Layout

no

DockLayoutManager

SaveLayoutToStream(Stream)

RestoreLayoutFromStream(Stream)

Save and Restore the Layout of Dock Panels and Controls

yes

SaveLayoutToXml(String)

RestoreLayoutFromXml(String)

DXTabControl

SaveLayoutToStream(Stream)

RestoreLayoutFromStream(Stream)

no

yes

SaveLayoutToXml(String)

RestoreLayoutFromXml(String)

GridControl/TreeListControl/GanttControl

SaveLayoutToStream(Stream)

RestoreLayoutFromStream(Stream)

Save and Restore Layout

yes

SaveLayoutToXml(String)

RestoreLayoutFromXml(String)

PivotGridControl

SaveLayoutToStream(Stream)

RestoreLayoutFromStream(Stream)

Save and Restore Layout

yes

RestoreLayoutFromStreamAsync(Stream)

SaveLayoutToXml(String)

RestoreLayoutFromXml(String)

RestoreLayoutFromXmlAsync(String)

RibbonControl

SaveLayout(Object)

RestoreLayout(Object)

no

yes

SaveDefaultLayout()

RestoreDefaultLayout()

ThemedWindow

SaveLayoutToStream(Stream)

RestoreLayoutFromStream(Stream)

no

yes

SaveLayoutToXml(String)

RestoreLayoutFromXml(String)

Note

If a control uses the DXSerializer class to save/restore its layout, you can use the DXSerializer’s events 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

Save/Restore Layouts of a Container and its Child Controls

Use the 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.

Supported Controls

Limitation

The 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/LayoutGroup tabs.

To save/restore layouts of serializable[1] DevExpress WPF Controls that are placed into a DXTabControl/LayoutGroup tab, set the tab’s DXTabControl.TabContentCacheMode/LayoutGroup.TabContentCacheMode property to TabContentCacheMode.CacheAllTabs. 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

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 SerializationIDs (within the container) for each of these objects.

    Note

    RibbonControl and each instance of its category/page/group should also have unique SerializationID attached property values.

  3. Call any DXSerializer.Serialize method. Serialize methods save layouts of visual DevExpress controls to a single XML file/Stream.

  4. Call any DXSerializer.Serialize method. These methods save the layout of visual DevExpress controls to a single XML file/Stream.

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

<Window . . .
    xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
    x:Name="mainWindow">
    <Grid>
        <dxg:GridControl dx:DXSerializer.SerializationID="gridControl1">
            <!--...-->
        </dxg:GridControl>
        <dxg:GridControl dx:DXSerializer.SerializationID="gridControl2">
            <!--...-->
        </dxg:GridControl>
    </Grid>
</Window>
using DevExpress.Xpf.Core.Serialization;

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
    DXSerializer.Serialize(mainWindow, "Layout.xml");
}

Restore (Deserialize) Layout

To restore a saved layout, you should use the DXSerializer.Deserialize method that corresponds to the saved layout structure (an XML file or a Stream).

For example, if you saved a control’s layout to a Stream (with the DXSerializer.Serialize(DependencyObject,Stream) method), you should call the DXSerializer.Deserialize(DependencyObject,Stream) method to restore the saved layout from that Stream.

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

using DevExpress.Xpf.Core.Serialization;

private void Window_Loaded(object sender, RoutedEventArgs e) {
    DXSerializer.Deserialize(mainWindow, "Layout.xml");
}

MVVM Support

To save/restore an application layout in MVVM applications, you can use the LayoutSerializationService and CurrentWindowSerializationBehavior classes.

View Example: Serialize/Deserialize a View's Size and State with LayoutSerializationService and CurrentWindowSerializationBehavior

These classes are based on the 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/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:

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();
    }
}

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:

public partial class App : Application {
    protected override void OnStartup(StartupEventArgs e) {
        base.OnStartup(e);
        Dispatcher.BeginInvoke(
            new Action(() => {
                GridControl grid = new GridControl();
                grid.View = new TableView();
                grid.RestoreLayoutFromXml("Layout.xml");
            }), 
            DispatcherPriority.ApplicationIdle
        );
    }
}

Advanced Scenarios

You can use the DXSerializer‘s events to perform the following actions:

Topic: DXSerializer Events - Advanced Scenarios

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