Back to Devexpress

How to: Save and Restore the Expanded State of Nodes

windowsforms-403853-controls-and-libraries-tree-list-examples-nodes-how-to-save-and-restore-the-expanded-state-of-nodes-when-reloading-data.md

latest8.0 KB
Original Source

How to: Save and Restore the Expanded State of Nodes

  • Jul 11, 2025
  • 4 minutes to read

This example demonstrates how to save and load the expanded state of nodes, the focused node’s position, and selected nodes.

View Example

Play the animation below to see the result.

Implement the TreeListViewState class

The TreeListViewState class implements the SaveState and LoadState methods. These methods allow you to persist and restore the state of nodes.

csharp
using System.Collections;
using DevExpress.XtraTreeList;
using DevExpress.XtraTreeList.Nodes;
using DevExpress.XtraTreeList.Nodes.Operations;

public class TreeListViewState {
    private ArrayList expanded;
    private ArrayList selected;
    private object focused;
    private object topNode;

    public TreeListViewState() : this(null) { }
    public TreeListViewState(TreeList treeList) {
        this.treeList = treeList;
        expanded = new ArrayList();
        selected = new ArrayList();
    }

    public void Clear() {
        expanded.Clear();
        selected.Clear();
        focused = null;
        topNode = null;
    }
    private ArrayList GetExpanded() {
        OperationSaveExpanded op = new OperationSaveExpanded();
        TreeList.NodesIterator.DoOperation(op);
        return op.Nodes;
    }
    private ArrayList GetSelected() {
        ArrayList al = new ArrayList();
        foreach(TreeListNode node in TreeList.Selection)
            al.Add(node.GetValue(TreeList.KeyFieldName));
        return al;
    }

    public void LoadState() {
        TreeList.BeginUpdate();
        try {
            TreeList.CollapseAll();
            TreeListNode node;
            foreach(object key in expanded) {
                node = TreeList.FindNodeByKeyID(key);
                if(node != null)
                    node.Expanded = true;
            }
            TreeList.FocusedNode = TreeList.FindNodeByKeyID(focused);
            foreach(object key in selected) {
                node = TreeList.FindNodeByKeyID(key);
                if(node != null)
                    TreeList.Selection.Add(node);
            }

        } finally {
            TreeList.EndUpdate();
            TreeListNode topVisibleNode = TreeList.FindNodeByKeyID(topNode);
            if(topVisibleNode == null) topVisibleNode = TreeList.FocusedNode;
            TreeList.TopVisibleNodeIndex = TreeList.GetVisibleIndexByNode(topVisibleNode);
        }
    }
    public void SaveState() {
        if(TreeList.FocusedNode != null) {
            expanded = GetExpanded();
            selected = GetSelected();
            focused = TreeList.FocusedNode[TreeList.KeyFieldName];
            topNode = TreeList.GetNodeByVisibleIndex(TreeList.TopVisibleNodeIndex)[TreeList.KeyFieldName];
        } else
            Clear();
    }

    private TreeList treeList;
    public TreeList TreeList {
        get {
            return treeList;
        }
        set {
            treeList = value;
            Clear();
        }
    }

    class OperationSaveExpanded : TreeListOperation {
        private ArrayList al = new ArrayList();
        public override void Execute(TreeListNode node) {
            if(node.HasChildren && node.Expanded)
                al.Add(node.GetValue(node.TreeList.KeyFieldName));
        }
        public ArrayList Nodes { get { return al; } }
    }
}
vb
Imports System.Collections
Imports DevExpress.XtraTreeList
Imports DevExpress.XtraTreeList.Nodes
Imports DevExpress.XtraTreeList.Nodes.Operations

Public Class TreeListViewState
    Private expanded As ArrayList
    Private selected As ArrayList
    Private focused As Object
    Private topNode As Object

    Public Sub New()
        Me.New(Nothing)
    End Sub
    Public Sub New(ByVal treeList As TreeList)
        Me.treeList_Renamed = treeList
        expanded = New ArrayList()
        selected = New ArrayList()
    End Sub

    Public Sub Clear()
        expanded.Clear()
        selected.Clear()
        focused = Nothing
        topNode = Nothing
    End Sub
    Private Function GetExpanded() As ArrayList
        Dim op As New OperationSaveExpanded()
        TreeList.NodesIterator.DoOperation(op)
        Return op.Nodes
    End Function
    Private Function GetSelected() As ArrayList
        Dim al As New ArrayList()
        For Each node As TreeListNode In TreeList.Selection
            al.Add(node.GetValue(TreeList.KeyFieldName))
        Next node
        Return al
    End Function

    Public Sub LoadState()
        TreeList.BeginUpdate()
        Try
            TreeList.CollapseAll()
            Dim node As TreeListNode
            For Each key As Object In expanded
                node = TreeList.FindNodeByKeyID(key)
                If node IsNot Nothing Then
                    node.Expanded = True
                End If
            Next key
            TreeList.FocusedNode = TreeList.FindNodeByKeyID(focused)
            For Each key As Object In selected
                node = TreeList.FindNodeByKeyID(key)
                If node IsNot Nothing Then
                    TreeList.Selection.Add(node)
                End If
            Next key

        Finally
            TreeList.EndUpdate()
            Dim topVisibleNode As TreeListNode = TreeList.FindNodeByKeyID(topNode)
            If topVisibleNode Is Nothing Then
                topVisibleNode = TreeList.FocusedNode
            End If
            TreeList.TopVisibleNodeIndex = TreeList.GetVisibleIndexByNode(topVisibleNode)
        End Try
    End Sub
    Public Sub SaveState()
        If TreeList.FocusedNode IsNot Nothing Then
            expanded = GetExpanded()
            selected = GetSelected()
            focused = TreeList.FocusedNode(TreeList.KeyFieldName)
            topNode = TreeList.GetNodeByVisibleIndex(TreeList.TopVisibleNodeIndex)(TreeList.KeyFieldName)
        Else
            Clear()
        End If
    End Sub

    Private tree_List As TreeList
    Public Property TreeList() As TreeList
        Get
            Return tree_List
        End Get
        Set(ByVal value As TreeList)
            tree_List = value
            Clear()
        End Set
    End Property

    Private Class OperationSaveExpanded
        Inherits TreeListOperation

        Private al As New ArrayList()
        Public Overrides Sub Execute(ByVal node As TreeListNode)
            If node.HasChildren AndAlso node.Expanded Then
                al.Add(node.GetValue(node.TreeList.KeyFieldName))
            End If
        End Sub
        Public ReadOnly Property Nodes() As ArrayList
            Get
                Return al
            End Get
        End Property
    End Class
End Class

Save/Restore the State of Nodes

csharp
TreeListViewState treeListViewState;

private void Form1_Load(object sender, EventArgs e) {
    treeListViewState = new TreeListViewState(treeList1);
}

// Save the state of nodes.
private void saveNodeStateButton_Click(object sender, EventArgs e) {
    treeListViewState.SaveState();
}

// Restore the state of nodes.
private void loadNodeStateButton_Click(object sender, EventArgs e) {
    treeListViewState.LoadState();
}
vb
Private treeListViewState As TreeListViewState

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
    treeListViewState = New TreeListViewState(treeList1)
End Sub

' Save the state of nodes.
Private Sub saveNodeStateButton_Click(ByVal sender As Object, ByVal e As EventArgs)
    treeListViewState.SaveState()
End Sub

' Restore the state of nodes.
Private Sub loadNodeStateButton_Click(ByVal sender As Object, ByVal e As EventArgs)
    treeListViewState.LoadState()
End Sub

See Also

Tree Traversal