1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004 Novell, Inc.
23 // Jackson Harper (jackson@ximian.com)
28 using System.Runtime.Serialization;
30 namespace System.Windows.Forms {
33 public class TreeNode : MarshalByRefObject /*, ICloneable, ISerializable */ {
35 private TreeView tree_view;
36 internal TreeNode parent;
40 private int image_index = -1;
41 private int selected_image_index;
42 private string full_path;
43 internal TreeNodeCollection nodes;
45 private bool is_expanded = true;
46 private Rectangle bounds = Rectangle.Empty;
48 internal OwnerDrawPropertyBag prop_bag;
51 private IntPtr handle;
53 internal TreeNode (TreeView tree_view) : this ()
55 this.tree_view = tree_view;
60 nodes = new TreeNodeCollection (this);
63 public TreeNode (string text) : this ()
68 public TreeNode (string text, TreeNode [] children) : this (text)
70 Nodes.AddRange (children);
73 public TreeNode (string text, int image_index, int selected_image_index) : this (text)
75 this.image_index = image_index;
76 this.selected_image_index = image_index;
79 public TreeNode (string text, int image_index, int selected_image_index,
80 TreeNode [] children) : this (text, image_index, selected_image_index)
82 Nodes.AddRange (children);
85 internal TreeView TreeView {
87 if (tree_view != null)
89 TreeNode walk = parent;
90 while (walk != null) {
91 if (walk.TreeView != null)
92 tree_view = walk.TreeView;
99 public TreeNode Parent {
101 if (tree_view != null && tree_view.root_node == parent)
121 public Rectangle Bounds {
122 get { return bounds; }
125 public bool Checked {
126 get { return check; }
127 set { check = value; }
130 public Color BackColor {
131 get { return prop_bag.BackColor; }
132 set { prop_bag.BackColor = value; }
135 public Color ForeColor {
136 get { return prop_bag.ForeColor; }
137 set { prop_bag.ForeColor = value; }
140 public Font NodeFont {
141 get { return prop_bag.Font; }
142 set { prop_bag.Font = value; }
145 public TreeNodeCollection Nodes {
148 nodes = new TreeNodeCollection (this);
153 public TreeNode FirstNode {
161 public string FullPath {
163 if (full_path != null)
166 StringBuilder builder = new StringBuilder ();
167 string ps = (TreeView == null ? "/" : TreeView.PathSeparator);
168 for (int i = 0; i < nodes.Count; i++) {
169 builder.Append (nodes [i].Text);
170 if (i - 1 != nodes.Count)
173 full_path = builder.ToString ();
178 public bool IsExpanded {
179 get { return is_expanded; }
182 public TreeNode NextNode {
186 if (parent.Nodes.Count > index + 1)
187 return parent.Nodes [index + 1];
192 public TreeNode PrevNode {
196 if (index == 0 || index > parent.Nodes.Count)
198 return parent.Nodes [index - 1];
202 public TreeNode NextVisibleNode {
204 OpenTreeNodeEnumerator o = new OpenTreeNodeEnumerator (this);
207 TreeNode c = (TreeNode) o.Current;
208 if (!c.IsInClippingRect)
214 public TreeNode PrevVisibleNode {
216 OpenTreeNodeEnumerator o = new OpenTreeNodeEnumerator (this);
217 if (!o.MovePrevious ())
219 TreeNode c = (TreeNode) o.Current;
220 if (!c.IsInClippingRect)
226 public TreeNode LastNode {
228 return Nodes [Nodes.Count - 1];
233 get { return index; }
236 public int ImageIndex {
237 get { return image_index; }
238 set { image_index = value; }
241 public int SelectedImageIndex {
242 get { return selected_image_index; }
243 set { selected_image_index = value; }
251 public void Expand ()
257 if (TreeView != null) {
258 TreeViewCancelEventArgs e = new TreeViewCancelEventArgs (this, false, TreeViewAction.Expand);
259 TreeView.OnBeforeCollapse (e);
265 if (TreeView != null)
266 TreeView.OnAfterCollapse (new TreeViewEventArgs (this));
267 if (IsNodeVisible () && TreeView != null)
268 TreeView.UpdateBelow (this);
272 public void Collapse ()
278 if (TreeView != null) {
279 TreeViewCancelEventArgs e = new TreeViewCancelEventArgs (this, false, TreeViewAction.Collapse);
280 TreeView.OnBeforeCollapse (e);
286 if (TreeView != null)
287 TreeView.OnAfterCollapse (new TreeViewEventArgs (this));
288 if (IsNodeVisible () && TreeView != null)
289 TreeView.UpdateBelow (this);
293 public void Remove ()
297 parent.Nodes.RemoveAt (Index);
300 public void ExpandAll ()
302 ExpandRecursive (this);
305 private void ExpandRecursive (TreeNode node)
308 foreach (TreeNode child in node.Nodes) {
309 ExpandRecursive (child);
313 internal void CollapseAll ()
315 CollapseRecursive (this);
318 private void CollapseRecursive (TreeNode node)
321 foreach (TreeNode child in node.Nodes) {
322 CollapseRecursive (child);
326 public int GetNodeCount (bool include_subtrees)
328 if (!include_subtrees)
332 GetNodeCountRecursive (this, ref count);
337 public void Toggle ()
344 if (TreeView != null)
348 internal void SetNodes (TreeNodeCollection nodes)
353 private void GetNodeCountRecursive (TreeNode node, ref int count)
355 count += node.Nodes.Count;
356 foreach (TreeNode child in node.Nodes) {
357 GetNodeCountRecursive (child, ref count);
361 public override String ToString ()
363 return String.Concat ("TreeNode: ", Text);
366 internal void UpdateBounds (int x, int y, int width, int height)
370 bounds.Width = width;
371 bounds.Height = height;
374 internal void SetAddedData (TreeView tree_view, TreeNode parent, int index)
376 this.tree_view = tree_view;
377 this.parent = parent;
381 private bool IsInClippingRect
384 if (TreeView == null)
386 if (bounds.Y < 0 && bounds.Y > tree_view.ClientRectangle.Height)
392 private bool IsNodeVisible ()
394 if (TreeView == null)
397 if (bounds.Y < 0 && bounds.Y > TreeView.ClientRectangle.Height)
400 TreeNode parent = Parent;
401 while (parent != null) {
402 if (!parent.IsExpanded)
404 parent = parent.Parent;