moel@345
|
1 |
using System;
|
moel@345
|
2 |
using System.Collections.Generic;
|
moel@345
|
3 |
using System.Text;
|
moel@345
|
4 |
using System.Collections.ObjectModel;
|
moel@345
|
5 |
|
moel@345
|
6 |
namespace Aga.Controls.Tree
|
moel@345
|
7 |
{
|
moel@345
|
8 |
/// <summary>
|
moel@345
|
9 |
/// Provides a simple ready to use implementation of <see cref="ITreeModel"/>. Warning: this class is not optimized
|
moel@345
|
10 |
/// to work with big amount of data. In this case create you own implementation of <c>ITreeModel</c>, and pay attention
|
moel@345
|
11 |
/// on GetChildren and IsLeaf methods.
|
moel@345
|
12 |
/// </summary>
|
moel@345
|
13 |
public class TreeModel : ITreeModel
|
moel@345
|
14 |
{
|
moel@345
|
15 |
private Node _root;
|
moel@345
|
16 |
public Node Root
|
moel@345
|
17 |
{
|
moel@345
|
18 |
get { return _root; }
|
moel@345
|
19 |
}
|
moel@345
|
20 |
|
moel@345
|
21 |
public Collection<Node> Nodes
|
moel@345
|
22 |
{
|
moel@345
|
23 |
get { return _root.Nodes; }
|
moel@345
|
24 |
}
|
moel@345
|
25 |
|
moel@345
|
26 |
public TreeModel()
|
moel@345
|
27 |
{
|
moel@345
|
28 |
_root = new Node();
|
moel@345
|
29 |
_root.Model = this;
|
moel@345
|
30 |
}
|
moel@345
|
31 |
|
moel@345
|
32 |
public TreePath GetPath(Node node)
|
moel@345
|
33 |
{
|
moel@345
|
34 |
if (node == _root)
|
moel@345
|
35 |
return TreePath.Empty;
|
moel@345
|
36 |
else
|
moel@345
|
37 |
{
|
moel@345
|
38 |
Stack<object> stack = new Stack<object>();
|
moel@345
|
39 |
while (node != _root)
|
moel@345
|
40 |
{
|
moel@345
|
41 |
stack.Push(node);
|
moel@345
|
42 |
node = node.Parent;
|
moel@345
|
43 |
}
|
moel@345
|
44 |
return new TreePath(stack.ToArray());
|
moel@345
|
45 |
}
|
moel@345
|
46 |
}
|
moel@345
|
47 |
|
moel@345
|
48 |
public Node FindNode(TreePath path)
|
moel@345
|
49 |
{
|
moel@345
|
50 |
if (path.IsEmpty())
|
moel@345
|
51 |
return _root;
|
moel@345
|
52 |
else
|
moel@345
|
53 |
return FindNode(_root, path, 0);
|
moel@345
|
54 |
}
|
moel@345
|
55 |
|
moel@345
|
56 |
private Node FindNode(Node root, TreePath path, int level)
|
moel@345
|
57 |
{
|
moel@345
|
58 |
foreach (Node node in root.Nodes)
|
moel@345
|
59 |
if (node == path.FullPath[level])
|
moel@345
|
60 |
{
|
moel@345
|
61 |
if (level == path.FullPath.Length - 1)
|
moel@345
|
62 |
return node;
|
moel@345
|
63 |
else
|
moel@345
|
64 |
return FindNode(node, path, level + 1);
|
moel@345
|
65 |
}
|
moel@345
|
66 |
return null;
|
moel@345
|
67 |
}
|
moel@345
|
68 |
|
moel@345
|
69 |
#region ITreeModel Members
|
moel@345
|
70 |
|
moel@345
|
71 |
public System.Collections.IEnumerable GetChildren(TreePath treePath)
|
moel@345
|
72 |
{
|
moel@345
|
73 |
Node node = FindNode(treePath);
|
moel@345
|
74 |
if (node != null)
|
moel@345
|
75 |
foreach (Node n in node.Nodes)
|
moel@345
|
76 |
yield return n;
|
moel@345
|
77 |
else
|
moel@345
|
78 |
yield break;
|
moel@345
|
79 |
}
|
moel@345
|
80 |
|
moel@345
|
81 |
public bool IsLeaf(TreePath treePath)
|
moel@345
|
82 |
{
|
moel@345
|
83 |
Node node = FindNode(treePath);
|
moel@345
|
84 |
if (node != null)
|
moel@345
|
85 |
return node.IsLeaf;
|
moel@345
|
86 |
else
|
moel@345
|
87 |
throw new ArgumentException("treePath");
|
moel@345
|
88 |
}
|
moel@345
|
89 |
|
moel@345
|
90 |
public event EventHandler<TreeModelEventArgs> NodesChanged;
|
moel@345
|
91 |
internal void OnNodesChanged(TreeModelEventArgs args)
|
moel@345
|
92 |
{
|
moel@345
|
93 |
if (NodesChanged != null)
|
moel@345
|
94 |
NodesChanged(this, args);
|
moel@345
|
95 |
}
|
moel@345
|
96 |
|
moel@345
|
97 |
public event EventHandler<TreePathEventArgs> StructureChanged;
|
moel@345
|
98 |
public void OnStructureChanged(TreePathEventArgs args)
|
moel@345
|
99 |
{
|
moel@345
|
100 |
if (StructureChanged != null)
|
moel@345
|
101 |
StructureChanged(this, args);
|
moel@345
|
102 |
}
|
moel@345
|
103 |
|
moel@345
|
104 |
public event EventHandler<TreeModelEventArgs> NodesInserted;
|
moel@345
|
105 |
internal void OnNodeInserted(Node parent, int index, Node node)
|
moel@345
|
106 |
{
|
moel@345
|
107 |
if (NodesInserted != null)
|
moel@345
|
108 |
{
|
moel@345
|
109 |
TreeModelEventArgs args = new TreeModelEventArgs(GetPath(parent), new int[] { index }, new object[] { node });
|
moel@345
|
110 |
NodesInserted(this, args);
|
moel@345
|
111 |
}
|
moel@345
|
112 |
|
moel@345
|
113 |
}
|
moel@345
|
114 |
|
moel@345
|
115 |
public event EventHandler<TreeModelEventArgs> NodesRemoved;
|
moel@345
|
116 |
internal void OnNodeRemoved(Node parent, int index, Node node)
|
moel@345
|
117 |
{
|
moel@345
|
118 |
if (NodesRemoved != null)
|
moel@345
|
119 |
{
|
moel@345
|
120 |
TreeModelEventArgs args = new TreeModelEventArgs(GetPath(parent), new int[] { index }, new object[] { node });
|
moel@345
|
121 |
NodesRemoved(this, args);
|
moel@345
|
122 |
}
|
moel@345
|
123 |
}
|
moel@345
|
124 |
|
moel@345
|
125 |
#endregion
|
moel@345
|
126 |
}
|
moel@345
|
127 |
}
|