Skip to main content

Persistence Behavior

  • 5 minutes to read

Use PersistenceBehavior to automatically save and restore a form’s bounds and its state to/from a file or the system registry. Along with the form-related information, it can optionally save/restore the layout of all DevExpress controls/components that reside within this form.

You can also bind PersistenceBehavior to an individual serializable DevExpress control/component to automatically save/restore only its layout.

Note

Use Workspace Manager to manually save/restore the layout of DevExpress controls/components, and the form’s bounds and state when necessary. The Workspace Manager provides additional features:

  • maintain multiple layouts (workspaces);
  • animation effects when you apply workspaces.

The following animation illustrates a form with attached PersistenceBehavior.

PersistenceBehavior-anim.gif

Save and restore the form’s bounds and state and its child controls’ layouts to a file/system registry

  1. Drop the BehaviorManager component on the form. Invoke the Behavior Editor from the smart tag menu and add PersistenceBehavior.

    PersistentBehavior-Add

  2. Ensure the Target property is set to the form.
  3. Optionally set the StoreChildLayouts setting to True to save/restore the layouts of all serializable DevExpress components within this form.

    Examples of serializable components are BarManager, DockManager, GridControl, TreeList, VGridControl, LayoutControl, GaugeControl, DocumentManager.

    Tip

    You can disable layout (de)serialization for an individual component with the static PersistenceBehavior.SetSerializationEnabled method. Call this method before the layout is saved/restored (typically, in the form’s constructor). See an example below.

  4. Use the Storage property to specify the storage type (the system registry or a XML file).
  5. Set the Path property to a target system registry key or the path to a target XML file.

    If you leave this property set to an empty string, PersistenceBehavior will store the layout in the current directory. The file’s name will be generated based on the target component’s name or its type name (if the name is empty).

    Note

    Environment.CurrentDirectory can be changed by file dialogs. This may affect the location of the saved layout file. We recommend that you specify the path manually.

When you need to create PersistenceBehavior in code, do so in the form’s constructor after the InitializeComponent method call. The following code shows how to create PersistenceBehavior in code to save/restore the layout of the form and DevExpress controls in this form. The example excludes a GaugeControl from (de)serialization.

using DevExpress.Utils.Behaviors.Common;

public Form1() {
    InitializeComponent();
    behaviorManager1.Attach<PersistenceBehavior>(this, behavior => {
        behavior.Properties.StoreChildLayouts = DefaultBoolean.True;
        behavior.Properties.Storage = Storage.File;
        behavior.Properties.Path = "mylayout.xml";
        //save the layout to the system registry:
        //behavior.Properties.Storage = Storage.Registry;
        //behavior.Properties.Path = "HKEY_CURRENT_USER\\Software\\MyCompany\\MyProject\\Layout";
    });
    //Disable layout (de)serialization for a GaugeControl
    PersistenceBehavior.SetSerializationEnabled(gaugeControl1, false);
}

Binding to Form Specifics

PersistenceBehavior bound to a form saves the layout when the Form.FormClosed event fires, and it restores the saved layout when the Form.Load event fires.

Ensure safe layout deserialization

If you create DevExpress controls/components at design time, call the controls’ ForceInitialize methods (e.g., BarManager.ForceInitialize, DockManager.ForceInitialize and GridControl.ForceInitialize) before you restore control layouts during form initialization. These methods finish control initialization and ensure you can safely modify their settings (e.g., by loading a layout). The following example calls the RibbonControl.ForceInitialize method before the Form.Load event by overriding the form’s OnLoad method.

public partial class Form1 : Form {
    protected override void OnLoad(EventArgs e) {
        ribbonControl1.ForceInitialize();
        base.OnLoad(e);
    }
}

Save and restore a specific control’s (component’s) layout

You can save/restore a specific control’s layout using the SaveLayoutTo… and RestoreLayoutFrom… methods the control provides. You can also use PersistenceBehavior for the same purpose.

  1. Create PersistenceBehavior as demonstrated above.
  2. Instead of setting its Target property to a form, set it to a specific control/component.

Target controls and components include: DockManager, GridControl, TreeList, VGridControl, LayoutControl, DocumentManager‘s Views, etc.

Binding to Control specifics

When bound to a control, PersistenceBehavior handles the Control.HandleCreated and Control.HandleDestroyed events to automatically restore/save the control’s layout.

Binding to Component specifics

When bound to a component (e.g., DockManager, DocumentManager‘s Views), PersistenceBehavior saves/restores the layout when the owner form is closed and loaded (the Form.FormClosing and Form.Load events, respectively). If you set the PersistenceBehavior.StoreChildLayouts to True, PersistenceBehavios saves/restores the layout of all serializable controls within the owner form.

public Form1() {
    InitializeComponent();
    behaviorManager1.Attach<PersistenceBehavior>(dockManager1, behavior => {
        behavior.Properties.Storage = Storage.File;
        behavior.Properties.Path = "mylayout.xml";
    });
}

Additional customization: layout (de)serialization options and deserialization events.

DevExpress controls provide settings to customize the layout save/restore operations. These settings allow you to specify:

  • which properties are saved/restored;
  • whether or not new items are retained after you load an old layout;
  • whether or not to discard the items that do not exist in the control, but still exist in the loaded layout
  • the layout version.

The list below shows the objects used to access the layout-aware settings.

When you load a layout, you can perform additional layout customization by handling the LayoutUpgrade deserialization events.

To prevent a layout from being loaded, you can handle the BeforeLoadLayout events.