using System.ComponentModel;
using System.Globalization;
+#if NET_2_0
+using System.Collections.Generic;
+#endif
+
namespace System.Windows.Forms {
[Editor("System.Windows.Forms.Design.TreeNodeCollectionEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
public class TreeNodeCollection : IList, ICollection, IEnumerable {
nodes = new TreeNode [OrigSize];
}
- [Browsable(false)]
+#if !NET_2_0
[EditorBrowsable(EditorBrowsableState.Advanced)]
+#endif
+ [Browsable(false)]
public int Count {
get { return count; }
}
}
set {
if (!(value is TreeNode))
- throw new ArgumentException ("value");
+ throw new ArgumentException ("Parameter must be of type TreeNode.", "value");
this [index] = (TreeNode) value;
}
}
}
}
+#if NET_2_0
+ public virtual TreeNode this [string key] {
+ get {
+ for (int i = 0; i < count; i++)
+ if (string.Compare (key, nodes[i].Name, true) == 0)
+ return nodes[i];
+
+ return null;
+ }
+ }
+#endif
+
public virtual TreeNode Add (string text)
{
TreeNode res = new TreeNode (text);
int res;
TreeView tree_view = null;
+ if (owner != null)
+ tree_view = owner.TreeView;
+
if (tree_view != null && tree_view.Sorted) {
res = AddSorted (node);
} else {
if (count >= nodes.Length)
Grow ();
- nodes [count++] = node;
+ nodes[count] = node;
res = count;
+ count++;
}
SetupNode (node);
-
+#if NET_2_0
+ // UIA Framework Event: Collection Changed
+ if (tree_view != null)
+ tree_view.OnUIACollectionChanged (owner, new CollectionChangeEventArgs (CollectionChangeAction.Add, node));
+#endif
return res;
}
+#if NET_2_0
+ public virtual TreeNode Add (string key, string text)
+ {
+ TreeNode node = new TreeNode (text);
+ node.Name = key;
+ Add (node);
+ return node;
+ }
+
+ public virtual TreeNode Add (string key, string text, int imageIndex)
+ {
+ TreeNode node = Add (key, text);
+ node.ImageIndex = imageIndex;
+ return node;
+ }
+
+ public virtual TreeNode Add (string key, string text, string imageKey)
+ {
+ TreeNode node = Add (key, text);
+ node.ImageKey = imageKey;
+ return node;
+
+ }
+
+ public virtual TreeNode Add (string key, string text, int imageIndex, int selectedImageIndex)
+ {
+ TreeNode node = Add (key, text);
+ node.ImageIndex = imageIndex;
+ node.SelectedImageIndex = selectedImageIndex;
+ return node;
+ }
+
+ public virtual TreeNode Add (string key, string text, string imageKey, string selectedImageKey)
+ {
+ TreeNode node = Add (key, text);
+ node.ImageKey = imageKey;
+ node.SelectedImageKey = selectedImageKey;
+ return node;
+ }
+
+
+#endif
+
public virtual void AddRange (TreeNode [] nodes)
{
if (nodes == null)
- throw new ArgumentNullException("node");
+ throw new ArgumentNullException("nodes");
// We can't just use Array.Copy because the nodes also
// need to have some properties set when they are added.
TreeView tree_view = null;
if (owner != null) {
tree_view = owner.TreeView;
- if (owner.IsRoot)
- tree_view.top_node = null;
if (tree_view != null) {
tree_view.UpdateBelow (owner);
tree_view.RecalculateVisibleOrder (owner);
- tree_view.UpdateScrollBars ();
+ tree_view.UpdateScrollBars (false);
}
}
}
public bool Contains (TreeNode node)
{
- return (Array.BinarySearch (nodes, node) > 0);
+ return Array.IndexOf (nodes, node, 0, count) != -1;
}
+#if NET_2_0
+ public virtual bool ContainsKey (string key)
+ {
+ for (int i = 0; i < count; i++) {
+ if (string.Compare (nodes [i].Name, key, true, CultureInfo.InvariantCulture) == 0)
+ return true;
+ }
+ return false;
+ }
+#endif
public void CopyTo (Array dest, int index)
{
return Array.IndexOf (nodes, node);
}
+#if NET_2_0
+ public virtual int IndexOfKey (string key)
+ {
+ for (int i = 0; i < count; i++) {
+ if (string.Compare (nodes [i].Name, key, true, CultureInfo.InvariantCulture) == 0)
+ return i;
+ }
+ return -1;
+ }
+
+ public virtual TreeNode Insert (int index, string text)
+ {
+ TreeNode node = new TreeNode (text);
+ Insert (index, node);
+ return node;
+ }
+#endif
+
public virtual void Insert (int index, TreeNode node)
{
if (count >= nodes.Length)
SetupNode (node);
}
+#if NET_2_0
+ public virtual TreeNode Insert (int index, string key, string text)
+ {
+ TreeNode node = new TreeNode (text);
+ node.Name = key;
+ Insert (index, node);
+ return node;
+ }
+
+ public virtual TreeNode Insert (int index, string key, string text, int imageIndex)
+ {
+ TreeNode node = new TreeNode (text);
+ node.Name = key;
+ node.ImageIndex = imageIndex;
+ Insert (index, node);
+ return node;
+ }
+
+ public virtual TreeNode Insert (int index, string key, string text, string imageKey)
+ {
+ TreeNode node = new TreeNode (text);
+ node.Name = key;
+ node.ImageKey = imageKey;
+ Insert (index, node);
+ return node;
+ }
+
+ public virtual TreeNode Insert (int index, string key, string text, int imageIndex, int selectedImageIndex)
+ {
+ TreeNode node = new TreeNode (text, imageIndex, selectedImageIndex);
+ node.Name = key;
+ Insert (index, node);
+ return node;
+ }
+
+ public virtual TreeNode Insert (int index, string key, string text, string imageKey, string selectedImageKey)
+ {
+ TreeNode node = new TreeNode (text);
+ node.Name = key;
+ node.ImageKey = imageKey;
+ node.SelectedImageKey = selectedImageKey;
+ Insert (index, node);
+ return node;
+ }
+#endif
+
public void Remove (TreeNode node)
{
if (node == null)
TreeNode removed = nodes [index];
TreeNode prev = GetPrevNode (removed);
TreeNode new_selected = null;
+ bool re_set_selected = false;
bool visible = removed.IsVisible;
TreeView tree_view = null;
if (tree_view != null) {
tree_view.RecalculateVisibleOrder (prev);
- if (removed == tree_view.top_node) {
- if (removed.IsRoot) {
- tree_view.top_node = null;
- } else {
- OpenTreeNodeEnumerator oe = new OpenTreeNodeEnumerator (removed);
- if (oe.MovePrevious () && oe.MovePrevious ()) {
- tree_view.top_node = oe.CurrentNode;
- } else {
- removed.is_expanded = false;
- oe = new OpenTreeNodeEnumerator (removed);
- if (oe.MoveNext () && oe.MoveNext ()) {
- tree_view.top_node = oe.CurrentNode;
- } else {
- tree_view.top_node = null;
- }
- }
- }
- }
- if (removed == tree_view.selected_node) {
+ if (removed == tree_view.SelectedNode) {
+ re_set_selected = true;
OpenTreeNodeEnumerator oe = new OpenTreeNodeEnumerator (removed);
if (oe.MoveNext () && oe.MoveNext ()) {
new_selected = oe.CurrentNode;
} else {
oe = new OpenTreeNodeEnumerator (removed);
oe.MovePrevious ();
- new_selected = oe.CurrentNode;
+ new_selected = oe.CurrentNode == removed ? null : oe.CurrentNode;
}
}
}
- Array.Copy (nodes, index + 1, nodes, index, count - index);
+ Array.Copy (nodes, index + 1, nodes, index, count - index - 1);
count--;
+
+ nodes[count] = null;
+
if (nodes.Length > OrigSize && nodes.Length > (count * 2))
Shrink ();
- if (tree_view != null && new_selected != null) {
+ if (tree_view != null && re_set_selected) {
tree_view.SelectedNode = new_selected;
}
if (update && tree_view != null && visible) {
tree_view.RecalculateVisibleOrder (prev);
- tree_view.UpdateScrollBars ();
+ tree_view.UpdateScrollBars (false);
tree_view.UpdateBelow (parent);
}
+#if NET_2_0
+ // UIA Framework Event: Collection Changed
+ if (tree_view != null)
+ tree_view.OnUIACollectionChanged (owner, new CollectionChangeEventArgs (CollectionChangeAction.Remove, removed));
+#endif
}
+#if NET_2_0
+ public virtual void RemoveByKey (string key)
+ {
+ TreeNode node = this[key];
+
+ if (node != null)
+ Remove (node);
+ }
+#endif
+
private TreeNode GetPrevNode (TreeNode node)
{
OpenTreeNodeEnumerator one = new OpenTreeNodeEnumerator (node);
tree_view = owner.TreeView;
if (tree_view != null) {
- TreeNode prev = GetPrevNode (node);
+ bool sorted = false;
+ if (tree_view.Sorted || tree_view.TreeViewNodeSorter != null) {
+ owner.Nodes.Sort (tree_view.TreeViewNodeSorter);
+ tree_view.sorted = sorted = true;
+ }
- if (tree_view.top_node == null)
- tree_view.top_node = node;
+ // We may need to invalidate this entire node collection if sorted.
+ TreeNode prev = sorted ? owner : GetPrevNode (node);
- if (node.IsVisible)
+ if (tree_view.IsHandleCreated && node.ArePreviousNodesExpanded)
tree_view.RecalculateVisibleOrder (prev);
if (owner == tree_view.root_node || node.Parent.IsVisible && node.Parent.IsExpanded)
- tree_view.UpdateScrollBars ();
+ tree_view.UpdateScrollBars (false);
}
if (owner != null && tree_view != null && (owner.IsExpanded || owner.IsRoot)) {
- // tree_view.UpdateBelow (owner);
- tree_view.UpdateNode (owner);
- tree_view.UpdateNode (node);
+ tree_view.UpdateBelow (owner);
} else if (owner != null && tree_view != null) {
tree_view.UpdateBelow (owner);
}
}
// Would be nice to do this without running through the collection twice
- internal void Sort () {
- Array.Sort (nodes, 0, count, new TreeNodeComparer (Application.CurrentCulture.CompareInfo));
+ internal void Sort (IComparer sorter) {
+ Array.Sort (nodes, 0, count, sorter == null ? new TreeNodeComparer (Application.CurrentCulture.CompareInfo) : sorter);
for (int i = 0; i < count; i++) {
- nodes [i].Nodes.Sort ();
+ nodes [i].Nodes.Sort (sorter);
}
}
nodes = nn;
}
+#if NET_2_0
+ public TreeNode[] Find (string key, bool searchAllChildren)
+ {
+ List<TreeNode> results = new List<TreeNode> (0);
+ Find (key, searchAllChildren, this, results);
+
+ return results.ToArray ();
+ }
+ private static void Find (string key, bool searchAllChildren, TreeNodeCollection nodes, List<TreeNode> results)
+ {
+ for (int i = 0; i < nodes.Count; i++) {
+ TreeNode thisNode = nodes [i];
+
+ if (string.Compare (thisNode.Name, key, true, CultureInfo.InvariantCulture) == 0)
+ results.Add (thisNode);
+
+ }
+ // Need to match the Microsoft order.
+
+ if (searchAllChildren){
+ for (int i = 0; i < nodes.Count; i++){
+ TreeNodeCollection childNodes = nodes [i].Nodes;
+ if (childNodes.Count > 0) {
+ Find (key, searchAllChildren, childNodes, results);
+ }
+ }
+ }
+ }
+#endif
internal class TreeNodeEnumerator : IEnumerator {
private TreeNodeCollection collection;