moel@345: using System; moel@345: using System.Collections.Generic; moel@345: using System.Text; moel@345: using System.Collections.ObjectModel; moel@345: moel@345: namespace Aga.Controls.Tree moel@345: { moel@345: /// moel@345: /// Provides a simple ready to use implementation of . Warning: this class is not optimized moel@345: /// to work with big amount of data. In this case create you own implementation of ITreeModel, and pay attention moel@345: /// on GetChildren and IsLeaf methods. moel@345: /// moel@345: public class TreeModel : ITreeModel moel@345: { moel@345: private Node _root; moel@345: public Node Root moel@345: { moel@345: get { return _root; } moel@345: } moel@345: moel@345: public Collection Nodes moel@345: { moel@345: get { return _root.Nodes; } moel@345: } moel@345: moel@345: public TreeModel() moel@345: { moel@345: _root = new Node(); moel@345: _root.Model = this; moel@345: } moel@345: moel@345: public TreePath GetPath(Node node) moel@345: { moel@345: if (node == _root) moel@345: return TreePath.Empty; moel@345: else moel@345: { moel@345: Stack stack = new Stack(); moel@345: while (node != _root) moel@345: { moel@345: stack.Push(node); moel@345: node = node.Parent; moel@345: } moel@345: return new TreePath(stack.ToArray()); moel@345: } moel@345: } moel@345: moel@345: public Node FindNode(TreePath path) moel@345: { moel@345: if (path.IsEmpty()) moel@345: return _root; moel@345: else moel@345: return FindNode(_root, path, 0); moel@345: } moel@345: moel@345: private Node FindNode(Node root, TreePath path, int level) moel@345: { moel@345: foreach (Node node in root.Nodes) moel@345: if (node == path.FullPath[level]) moel@345: { moel@345: if (level == path.FullPath.Length - 1) moel@345: return node; moel@345: else moel@345: return FindNode(node, path, level + 1); moel@345: } moel@345: return null; moel@345: } moel@345: moel@345: #region ITreeModel Members moel@345: moel@345: public System.Collections.IEnumerable GetChildren(TreePath treePath) moel@345: { moel@345: Node node = FindNode(treePath); moel@345: if (node != null) moel@345: foreach (Node n in node.Nodes) moel@345: yield return n; moel@345: else moel@345: yield break; moel@345: } moel@345: moel@345: public bool IsLeaf(TreePath treePath) moel@345: { moel@345: Node node = FindNode(treePath); moel@345: if (node != null) moel@345: return node.IsLeaf; moel@345: else moel@345: throw new ArgumentException("treePath"); moel@345: } moel@345: moel@345: public event EventHandler NodesChanged; moel@345: internal void OnNodesChanged(TreeModelEventArgs args) moel@345: { moel@345: if (NodesChanged != null) moel@345: NodesChanged(this, args); moel@345: } moel@345: moel@345: public event EventHandler StructureChanged; moel@345: public void OnStructureChanged(TreePathEventArgs args) moel@345: { moel@345: if (StructureChanged != null) moel@345: StructureChanged(this, args); moel@345: } moel@345: moel@345: public event EventHandler NodesInserted; moel@345: internal void OnNodeInserted(Node parent, int index, Node node) moel@345: { moel@345: if (NodesInserted != null) moel@345: { moel@345: TreeModelEventArgs args = new TreeModelEventArgs(GetPath(parent), new int[] { index }, new object[] { node }); moel@345: NodesInserted(this, args); moel@345: } moel@345: moel@345: } moel@345: moel@345: public event EventHandler NodesRemoved; moel@345: internal void OnNodeRemoved(Node parent, int index, Node node) moel@345: { moel@345: if (NodesRemoved != null) moel@345: { moel@345: TreeModelEventArgs args = new TreeModelEventArgs(GetPath(parent), new int[] { index }, new object[] { node }); moel@345: NodesRemoved(this, args); moel@345: } moel@345: } moel@345: moel@345: #endregion moel@345: } moel@345: }