1 //Widgit is free software; you can redistribute it and/or modify
2 //it under the terms of the GNU General Public License as published by
3 //the Free Software Foundation; either version 2 of the License, or
4 //(at your option) any later version.
6 //Widgit is distributed in the hope that it will be useful,
7 //but WITHOUT ANY WARRANTY; without even the implied warranty of
8 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 //GNU General Public License for more details.
11 //You should have received a copy of the GNU General Public License
12 //along with Widgit; if not, write to the Free Software
13 //Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USAusing System;
16 using System
.Collections
;
18 using System
.Windows
.Forms
;
23 public class MultiselectTreeview
: TreeView
25 protected ArrayList m_coll
;
26 protected TreeNode m_firstNode
;
28 public ArrayList SelectedNodes
36 removePaintFromNodes();
43 protected override void OnAfterSelect(TreeViewEventArgs e
)
45 // e.Node is the current node exposed by the base TreeView control
47 base.OnAfterSelect(e
);
48 removePaintFromNodes();
50 bool bControl
= (ModifierKeys
== Keys
.Control
);
51 //bool bShift = (ModifierKeys == Keys.Shift);
55 if (!m_coll
.Contains(e
.Node
)) // new node ?
59 else // not new, remove it from the collection
61 m_coll
.Remove(e
.Node
);
68 Queue myQueue = new Queue();
70 TreeNode uppernode = m_firstNode;
71 TreeNode bottomnode = e.Node;
73 // case 1 : begin and end nodes are parent
74 bool bParent = isParent(m_firstNode, e.Node);
77 bParent = isParent(bottomnode, uppernode);
78 if (bParent) // swap nodes
80 TreeNode t = uppernode;
81 uppernode = bottomnode;
87 TreeNode n = bottomnode;
88 while (n != uppernode.Parent)
90 if (!m_coll.Contains(n)) // new node ?
96 // case 2 : nor the begin nor the
97 // end node are descendant one another
100 // are they siblings ?
102 if ((uppernode.Parent == null && bottomnode.Parent == null)
103 || (uppernode.Parent != null &&
104 uppernode.Parent.Nodes.Contains(bottomnode)))
106 int nIndexUpper = uppernode.Index;
107 int nIndexBottom = bottomnode.Index;
108 if (nIndexBottom < nIndexUpper) // reversed?
110 TreeNode t = uppernode;
111 uppernode = bottomnode;
113 nIndexUpper = uppernode.Index;
114 nIndexBottom = bottomnode.Index;
117 TreeNode n = uppernode;
118 while (nIndexUpper <= nIndexBottom)
120 if (!m_coll.Contains(n)) // new node ?
131 if (!m_coll.Contains(uppernode))
132 myQueue.Enqueue(uppernode);
133 if (!m_coll.Contains(bottomnode))
134 myQueue.Enqueue(bottomnode);
139 m_coll.AddRange(myQueue);
141 paintSelectedNodes();
142 // let us chain several SHIFTs if we like it
143 m_firstNode = e.Node;
148 // in the case of a simple click, just add this item
149 if (m_coll
!= null && m_coll
.Count
> 0)
156 removePaintFromNodes();
159 protected bool isParent(TreeNode parentNode
, TreeNode childNode
)
161 if (parentNode
== childNode
)
164 TreeNode n
= childNode
;
166 while (!bFound
&& n
!= null)
169 bFound
= (n
== parentNode
);
175 protected void paintSelectedNodes()
177 foreach (TreeNode n
in m_coll
)
179 n
.BackColor
= SystemColors
.Highlight
;
180 n
.ForeColor
= SystemColors
.HighlightText
;
184 protected void removePaintFromNodes()
186 if (m_coll
.Count
== 0) return;
188 TreeNode n0
= (TreeNode
)m_coll
[0];
189 Color back
= n0
.TreeView
.BackColor
;
190 Color fore
= n0
.TreeView
.ForeColor
;
192 foreach (TreeNode n
in m_coll
)