using System; using System.Collections.Generic; using System.Linq; using Core.Common.Controls.TreeView.Properties; namespace Core.Common.Controls.TreeView { /// /// This class takes a and maps the current collapsed/expanded /// state of that node and its children. Then the state instance can be used to fully /// restore those states at a later time. /// public class TreeNodeExpandCollapseState { readonly bool wasExpanded; readonly object tag; readonly IDictionary childStates; /// /// Initializes a new instance of the class, /// recording the expanded / collapsed state of the given node and its children. /// /// The node to be recorded. /// When is null. /// When /// does not have data on its . public TreeNodeExpandCollapseState(ITreeNode nodeToBeRecorded) { if (nodeToBeRecorded == null) { throw new ArgumentNullException("nodeToBeRecorded", Resources.TreeNodeExpandCollapseState_Node_cannot_be_null_for_record_to_work); } tag = nodeToBeRecorded.Tag; if (tag == null) { throw new ArgumentException(Resources.TreeNodeExpandCollapseState_Node_tag_cannot_be_null_for_record_to_work); } wasExpanded = nodeToBeRecorded.IsExpanded; childStates = nodeToBeRecorded.Nodes.Where(n => n.Nodes.Any()).ToDictionary(n => n.Tag, n => new TreeNodeExpandCollapseState(n)); } /// /// Restores the specified target node and its children to the recorded state. /// /// The target node. /// When data /// is not the same as was recorded. /// When has /// different node-tree than recorded. public void Restore(ITreeNode targetNode) { if (!targetNode.Tag.Equals(tag)) { throw new ArgumentException(Resources.TreeNodeExpandCollapseState_Node_not_matching_tag_for_restore, "targetNode"); } if (targetNode.IsExpanded) { if (!wasExpanded) { targetNode.Collapse(); } } else { if (wasExpanded) { targetNode.Expand(); } } foreach (var treeNode in targetNode.Nodes.Where(n => n.Nodes.Any() && childStates.ContainsKey(n.Tag))) { childStates[treeNode.Tag].Restore(treeNode); } } } }