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-2005 Novell, Inc.
23 // Jackson Harper (jackson@ximian.com)
24 // Kazuki Oikawa (kazuki@panicode.com)
27 using System
.Collections
;
28 using System
.ComponentModel
;
29 using System
.ComponentModel
.Design
;
31 using System
.Drawing
.Drawing2D
;
32 using System
.Runtime
.InteropServices
;
34 namespace System
.Windows
.Forms
{
35 [DefaultProperty("Nodes")]
36 [DefaultEvent("AfterSelect")]
37 [Designer("System.Windows.Forms.Design.TreeViewDesigner, " + Consts
.AssemblySystem_Design
, "System.ComponentModel.Design.IDesigner")]
38 public class TreeView
: Control
{
40 private string path_separator
= "\\";
41 private int item_height
= -1;
43 internal TreeNode top_node
;
44 internal TreeNode root_node
;
45 internal bool nodes_added
;
46 private TreeNodeCollection nodes
;
48 private TreeViewAction selection_action
= TreeViewAction
.Unknown
;
49 internal TreeNode selected_node
= null;
50 private TreeNode focused_node
= null;
51 private TreeNode highlighted_node
;
52 private Rectangle mouse_rect
= Rectangle
.Empty
;
53 private bool select_mmove
= false;
55 private ImageList image_list
;
56 private int image_index
= -1;
57 private int selected_image_index
= -1;
59 private bool full_row_select
;
60 private bool hot_tracking
;
61 private int indent
= 19;
63 private NodeLabelEditEventArgs edit_args
;
64 private LabelEditTextBox edit_text_box
;
65 internal TreeNode edit_node
;
67 private bool checkboxes
;
68 private bool label_edit
;
69 private bool scrollable
= true;
70 private bool show_lines
= true;
71 private bool show_root_lines
= true;
72 private bool show_plus_minus
= true;
73 private bool hide_selection
= true;
75 private int max_visible_order
= -1;
76 private VScrollBar vbar
;
77 private HScrollBar hbar
;
78 private bool vbar_bounds_set
;
79 private bool hbar_bounds_set
;
80 internal int skipped_nodes
;
81 internal int hbar_offset
;
83 private int update_stack
;
84 private bool update_needed
;
87 private StringFormat string_format
;
89 private int drag_begin_x
= 0;
90 private int drag_begin_y
= 0;
91 private long handle_count
= 1;
95 #region Public Constructors
98 border_style
= BorderStyle
.Fixed3D
;
99 base.background_color
= ThemeEngine
.Current
.ColorWindow
;
100 base.foreground_color
= ThemeEngine
.Current
.ColorWindowText
;
102 root_node
= new TreeNode (this);
103 root_node
.Text
= "ROOT NODE";
104 nodes
= new TreeNodeCollection (root_node
);
105 root_node
.SetNodes (nodes
);
107 MouseDown
+= new MouseEventHandler (MouseDownHandler
);
108 MouseUp
+= new MouseEventHandler(MouseUpHandler
);
109 MouseMove
+= new MouseEventHandler(MouseMoveHandler
);
110 SizeChanged
+= new EventHandler (SizeChangedHandler
);
111 FontChanged
+= new EventHandler (FontChangedHandler
);
112 LostFocus
+= new EventHandler (LostFocusHandler
);
113 GotFocus
+= new EventHandler (GotFocusHandler
);
114 MouseWheel
+= new MouseEventHandler(MouseWheelHandler
);
115 VisibleChanged
+= new EventHandler (VisibleChangedHandler
);
117 SetStyle (ControlStyles
.UserPaint
| ControlStyles
.StandardClick
119 | ControlStyles
.UseTextForAccessibility
123 string_format
= new StringFormat ();
124 string_format
.LineAlignment
= StringAlignment
.Center
;
125 string_format
.Alignment
= StringAlignment
.Center
;
127 vbar
= new ImplicitVScrollBar ();
128 hbar
= new ImplicitHScrollBar ();
130 vbar
.Visible
= false;
131 hbar
.Visible
= false;
132 vbar
.ValueChanged
+= new EventHandler (VScrollBarValueChanged
);
133 hbar
.ValueChanged
+= new EventHandler (HScrollBarValueChanged
);
136 Controls
.AddImplicit (vbar
);
137 Controls
.AddImplicit (hbar
);
141 #endregion // Public Constructors
143 #region Public Instance Properties
144 public override Color BackColor
{
145 get { return base.BackColor;}
146 set { base.BackColor = value; }
151 [EditorBrowsable(EditorBrowsableState
.Never
)]
152 public override Image BackgroundImage
{
153 get { return base.BackgroundImage; }
154 set { base.BackgroundImage = value; }
157 [DefaultValue(BorderStyle
.Fixed3D
)]
159 public BorderStyle BorderStyle
{
160 get { return InternalBorderStyle; }
161 set { InternalBorderStyle = value; }
164 [DefaultValue(false)]
165 public bool CheckBoxes
{
166 get { return checkboxes; }
168 if (value == checkboxes
)
172 // Match a "bug" in the MS implementation where disabling checkboxes
173 // collapses the entire tree, but enabling them does not affect the
174 // state of the tree.
176 root_node
.CollapseAllUncheck ();
182 public override Color ForeColor
{
183 get { return base.ForeColor; }
184 set { base.ForeColor = value; }
186 [DefaultValue(false)]
187 public bool FullRowSelect
{
188 get { return full_row_select; }
190 if (value == full_row_select
)
192 full_row_select
= value;
197 public bool HideSelection
{
198 get { return hide_selection; }
200 if (hide_selection
== value)
202 hide_selection
= value;
207 [DefaultValue(false)]
208 public bool HotTracking
{
209 get { return hot_tracking; }
210 set { hot_tracking = value; }
214 [Editor("System.Windows.Forms.Design.ImageIndexEditor, " + Consts
.AssemblySystem_Design
, typeof(System
.Drawing
.Design
.UITypeEditor
))]
216 [TypeConverter(typeof(TreeViewImageIndexConverter
))]
217 public int ImageIndex
{
218 get { return image_index; }
221 throw new ArgumentException ("'" + value + "' is not a valid value for 'value'. " +
222 "'value' must be greater than or equal to 0.");
224 if (image_index
== value)
232 public ImageList ImageList
{
233 get { return image_list; }
242 get { return indent; }
247 throw new ArgumentException ("'" + value + "' is not a valid value for 'Indent'. " +
248 "'Indent' must be less than or equal to 32000");
251 throw new ArgumentException ("'" + value + "' is not a valid value for 'Indent'. " +
252 "'Indent' must be greater than or equal to 0.");
260 public int ItemHeight
{
262 if (item_height
== -1)
263 return FontHeight
+ 3;
267 if (value == item_height
)
274 internal int ActualItemHeight
{
276 int res
= ItemHeight
;
277 if (ImageList
!= null && ImageList
.ImageSize
.Height
> res
)
278 res
= ImageList
.ImageSize
.Height
;
283 [DefaultValue(false)]
284 public bool LabelEdit
{
285 get { return label_edit; }
286 set { label_edit = value; }
289 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
)]
290 [MergableProperty(false)]
292 public TreeNodeCollection Nodes
{
293 get { return nodes; }
297 public string PathSeparator
{
298 get { return path_separator; }
299 set { path_separator = value; }
303 public bool Scrollable
{
304 get { return scrollable; }
306 if (scrollable
== value)
313 [Editor("System.Windows.Forms.Design.ImageIndexEditor, " + Consts
.AssemblySystem_Design
, typeof(System
.Drawing
.Design
.UITypeEditor
))]
314 [TypeConverter(typeof(TreeViewImageIndexConverter
))]
317 public int SelectedImageIndex
{
318 get { return selected_image_index; }
321 throw new ArgumentException ("'" + value + "' is not a valid value for 'value'. " +
322 "'value' must be greater than or equal to 0.");
324 UpdateNode (SelectedNode
);
329 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
330 public TreeNode SelectedNode
{
331 get { return selected_node; }
333 if (selected_node
== value) {
334 selection_action
= TreeViewAction
.Unknown
;
338 TreeViewCancelEventArgs e
= new TreeViewCancelEventArgs (value, false, selection_action
);
344 Rectangle invalid
= Rectangle
.Empty
;
346 if (selected_node
!= null) {
347 invalid
= Bloat (selected_node
.Bounds
);
349 if (focused_node
!= null) {
350 invalid
= Rectangle
.Union (invalid
,
351 Bloat (focused_node
.Bounds
));
355 invalid
= Rectangle
.Union (invalid
, Bloat (value.Bounds
));
357 highlighted_node
= value;
358 selected_node
= value;
359 focused_node
= value;
361 if (full_row_select
) {
363 invalid
.Width
= ViewportRectangle
.Width
;
366 if (invalid
!= Rectangle
.Empty
)
367 Invalidate (invalid
);
369 // We ensure its visible after we update because
370 // scrolling is used for insure visible
371 if (selected_node
!= null)
372 selected_node
.EnsureVisible ();
374 OnAfterSelect (new TreeViewEventArgs (value, TreeViewAction
.Unknown
));
375 selection_action
= TreeViewAction
.Unknown
;
379 private Rectangle
Bloat (Rectangle rect
)
389 public bool ShowLines
{
390 get { return show_lines; }
392 if (show_lines
== value)
400 public bool ShowPlusMinus
{
401 get { return show_plus_minus; }
403 if (show_plus_minus
== value)
405 show_plus_minus
= value;
411 public bool ShowRootLines
{
412 get { return show_root_lines; }
414 if (show_root_lines
== value)
416 show_root_lines
= value;
421 [DefaultValue(false)]
423 get { return sorted; }
429 top_node
= root_node
;
430 RecalculateVisibleOrder (root_node
);
438 [EditorBrowsable(EditorBrowsableState
.Never
)]
440 public override string Text
{
441 get { return base.Text; }
442 set { base.Text = value; }
446 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
447 public TreeNode TopNode
{
448 get { return top_node; }
452 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
453 public int VisibleCount
{
455 return ViewportRectangle
.Height
/ ActualItemHeight
;
459 #endregion // Public Instance Properties
461 #region Protected Instance Properties
462 protected override CreateParams CreateParams
{
464 CreateParams cp
= base.CreateParams
;
469 protected override Size DefaultSize
{
470 get { return new Size (121, 97); }
473 #endregion // Protected Instance Properties
475 #region Public Instance Methods
476 public void BeginUpdate ()
481 public void EndUpdate ()
483 if (update_stack
> 1) {
488 RecalculateVisibleOrder (root_node
);
490 if (SelectedNode
!= null)
491 SelectedNode
.EnsureVisible ();
492 Invalidate (ViewportRectangle
);
493 update_needed
= false;
498 public void ExpandAll ()
501 root_node
.ExpandAll ();
505 // Walk all the way to the end, then walk back visible count
506 //to find the new top node
507 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (root_node
);
508 while (walk
.MoveNext ())
511 for (int i
= 0; i
< VisibleCount
- 1; i
++)
512 walk
.MovePrevious ();
514 SetTop (walk
.CurrentNode
);
518 public void CollapseAll ()
520 TreeNode walk
= top_node
;
522 while (walk
.parent
!= root_node
)
526 root_node
.CollapseAll ();
532 public TreeNode
GetNodeAt (Point pt
) {
533 return GetNodeAt (pt
.Y
);
536 public TreeNode
GetNodeAt (int x
, int y
)
538 return GetNodeAt (y
);
541 private TreeNode
GetNodeAtUseX (int x
, int y
) {
542 TreeNode node
= GetNodeAt (y
);
543 if (node
== null || !(IsTextArea (node
, x
) || full_row_select
))
549 public int GetNodeCount (bool include_subtrees
) {
550 return root_node
.GetNodeCount (include_subtrees
);
553 public override string ToString () {
554 int count
= Nodes
.Count
;
556 return String
.Concat (base.ToString (), "Node Count: 0");
557 return String
.Concat (base.ToString (), "Node Count: ", count
, " Nodes[0]: ", Nodes
[0]);
561 #endregion // Public Instance Methods
563 #region Protected Instance Methods
564 protected override void CreateHandle () {
565 base.CreateHandle ();
570 protected override void Dispose (bool disposing
) {
574 base.Dispose (disposing
);
577 protected OwnerDrawPropertyBag
GetItemRenderStyles (TreeNode node
, int state
) {
578 return node
.prop_bag
;
581 protected override bool IsInputKey (Keys key_data
)
583 if ((key_data
& Keys
.Alt
) == 0) {
584 switch (key_data
& Keys
.KeyCode
) {
598 return base.IsInputKey (key_data
);
601 protected override void OnKeyDown (KeyEventArgs e
)
603 OpenTreeNodeEnumerator ne
;
605 switch (e
.KeyData
& Keys
.KeyCode
) {
607 if (selected_node
!= null && selected_node
.IsExpanded
)
608 selected_node
.Expand ();
611 if (selected_node
!= null && selected_node
.IsExpanded
)
612 selected_node
.Collapse ();
615 if (selected_node
!= null) {
616 if (selected_node
.IsExpanded
)
617 selected_node
.Collapse ();
619 TreeNode parent
= selected_node
.Parent
;
620 if (parent
!= null) {
621 selection_action
= TreeViewAction
.ByKeyboard
;
622 SelectedNode
= parent
;
628 if (selected_node
!= null) {
629 if (!selected_node
.IsExpanded
)
630 selected_node
.Expand ();
632 TreeNode child
= selected_node
.FirstNode
;
634 SelectedNode
= child
;
639 if (selected_node
!= null) {
640 ne
= new OpenTreeNodeEnumerator (selected_node
);
641 if (ne
.MovePrevious () && ne
.MovePrevious ()) {
642 selection_action
= TreeViewAction
.ByKeyboard
;
643 SelectedNode
= ne
.CurrentNode
;
648 if (selected_node
!= null) {
649 ne
= new OpenTreeNodeEnumerator (selected_node
);
650 if (ne
.MoveNext () && ne
.MoveNext ()) {
651 selection_action
= TreeViewAction
.ByKeyboard
;
652 SelectedNode
= ne
.CurrentNode
;
657 if (root_node
.Nodes
.Count
> 0) {
658 ne
= new OpenTreeNodeEnumerator (root_node
.Nodes
[0]);
659 if (ne
.MoveNext ()) {
660 selection_action
= TreeViewAction
.ByKeyboard
;
661 SelectedNode
= ne
.CurrentNode
;
666 if (root_node
.Nodes
.Count
> 0) {
667 ne
= new OpenTreeNodeEnumerator (root_node
.Nodes
[0]);
668 while (ne
.MoveNext ())
670 selection_action
= TreeViewAction
.ByKeyboard
;
671 SelectedNode
= ne
.CurrentNode
;
675 if (selected_node
!= null) {
676 ne
= new OpenTreeNodeEnumerator (selected_node
);
677 int move
= VisibleCount
;
678 for (int i
= 0; i
< move
&& ne
.MoveNext (); i
++) {
681 selection_action
= TreeViewAction
.ByKeyboard
;
682 SelectedNode
= ne
.CurrentNode
;
686 if (selected_node
!= null) {
687 ne
= new OpenTreeNodeEnumerator (selected_node
);
688 int move
= VisibleCount
;
689 for (int i
= 0; i
< move
&& ne
.MovePrevious (); i
++)
691 selection_action
= TreeViewAction
.ByKeyboard
;
692 SelectedNode
= ne
.CurrentNode
;
696 if (selected_node
!= null)
697 selected_node
.ExpandAll ();
702 if (!e
.Handled
&& checkboxes
&&
703 selected_node
!= null &&
704 (e
.KeyData
& Keys
.KeyCode
) == Keys
.Space
) {
705 selected_node
.check_reason
= TreeViewAction
.ByKeyboard
;
706 selected_node
.Checked
= !selected_node
.Checked
;
711 protected override void OnKeyPress (KeyPressEventArgs e
)
714 if (e
.KeyChar
== ' ')
718 protected override void OnKeyUp (KeyEventArgs e
)
721 if ((e
.KeyData
& Keys
.KeyCode
) == Keys
.Space
)
725 protected virtual void OnItemDrag (ItemDragEventArgs e
)
727 ItemDragEventHandler eh
= (ItemDragEventHandler
)(Events
[ItemDragEvent
]);
732 protected internal virtual void OnAfterCheck (TreeViewEventArgs e
) {
733 TreeViewEventHandler eh
= (TreeViewEventHandler
)(Events
[AfterCheckEvent
]);
738 protected internal virtual void OnAfterCollapse (TreeViewEventArgs e
) {
739 TreeViewEventHandler eh
= (TreeViewEventHandler
)(Events
[AfterCollapseEvent
]);
744 protected internal virtual void OnAfterExpand (TreeViewEventArgs e
) {
745 TreeViewEventHandler eh
= (TreeViewEventHandler
)(Events
[AfterExpandEvent
]);
750 protected virtual void OnAfterLabelEdit (NodeLabelEditEventArgs e
) {
751 NodeLabelEditEventHandler eh
= (NodeLabelEditEventHandler
)(Events
[AfterLabelEditEvent
]);
756 protected virtual void OnAfterSelect (TreeViewEventArgs e
) {
757 TreeViewEventHandler eh
= (TreeViewEventHandler
)(Events
[AfterSelectEvent
]);
762 protected internal virtual void OnBeforeCheck (TreeViewCancelEventArgs e
) {
763 TreeViewCancelEventHandler eh
= (TreeViewCancelEventHandler
)(Events
[BeforeCheckEvent
]);
768 protected internal virtual void OnBeforeCollapse (TreeViewCancelEventArgs e
) {
769 TreeViewCancelEventHandler eh
= (TreeViewCancelEventHandler
)(Events
[BeforeCollapseEvent
]);
774 protected internal virtual void OnBeforeExpand (TreeViewCancelEventArgs e
) {
775 TreeViewCancelEventHandler eh
= (TreeViewCancelEventHandler
)(Events
[BeforeExpandEvent
]);
780 protected virtual void OnBeforeLabelEdit (NodeLabelEditEventArgs e
) {
781 NodeLabelEditEventHandler eh
= (NodeLabelEditEventHandler
)(Events
[BeforeLabelEditEvent
]);
786 protected virtual void OnBeforeSelect (TreeViewCancelEventArgs e
) {
787 TreeViewCancelEventHandler eh
= (TreeViewCancelEventHandler
)(Events
[BeforeSelectEvent
]);
792 protected override void OnHandleCreated (EventArgs e
) {
793 base.OnHandleCreated (e
);
796 protected override void OnHandleDestroyed (EventArgs e
) {
797 base.OnHandleDestroyed (e
);
800 protected override void WndProc(ref Message m
) {
801 switch ((Msg
) m
.Msg
) {
803 case Msg
.WM_LBUTTONDBLCLK
:
804 int val
= m
.LParam
.ToInt32();
805 DoubleClickHandler (null, new
806 MouseEventArgs (MouseButtons
.Left
,
808 (val
>>16) & 0xffff, 0));
811 base.WndProc (ref m
);
814 #endregion // Protected Instance Methods
816 #region Internal & Private Methods and Properties
817 internal IntPtr
CreateNodeHandle ()
819 return (IntPtr
) handle_count
++;
822 internal TreeNode
NodeFromHandle (IntPtr handle
)
824 // This method is called rarely, so instead of maintaining a table
825 // we just walk the tree nodes to find the matching handle
826 return NodeFromHandleRecursive (root_node
, handle
);
829 private TreeNode
NodeFromHandleRecursive (TreeNode node
, IntPtr handle
)
831 if (node
.handle
== handle
)
833 foreach (TreeNode child
in node
.Nodes
) {
834 TreeNode match
= NodeFromHandleRecursive (child
, handle
);
841 internal Rectangle ViewportRectangle
{
843 Rectangle res
= ClientRectangle
;
845 if (vbar
!= null && vbar
.Visible
)
846 res
.Width
-= vbar
.Width
;
847 if (hbar
!= null && hbar
.Visible
)
848 res
.Height
-= hbar
.Height
;
853 private TreeNode
GetNodeAt (int y
)
855 if (nodes
.Count
<= 0)
858 if (top_node
== null)
859 top_node
= nodes
[0];
861 OpenTreeNodeEnumerator o
= new OpenTreeNodeEnumerator (TopNode
);
862 int move
= y
/ ActualItemHeight
;
863 for (int i
= -1; i
< move
; i
++) {
868 return o
.CurrentNode
;
871 private bool IsTextArea (TreeNode node
, int x
)
873 return node
!= null && node
.Bounds
.Left
<= x
&& node
.Bounds
.Right
>= x
;
876 private bool IsSelectableArea (TreeNode node
, int x
)
880 int l
= node
.Bounds
.Left
;
881 if (ImageList
!= null)
882 l
-= ImageList
.ImageSize
.Width
;
883 return l
<= x
&& node
.Bounds
.Right
>= x
;
887 private bool IsPlusMinusArea (TreeNode node
, int x
)
889 if (node
.Nodes
.Count
== 0 || (node
.parent
== root_node
&& !show_root_lines
))
892 int l
= node
.Bounds
.Left
+ 5;
894 if (show_root_lines
|| node
.Parent
!= null)
896 if (ImageList
!= null)
897 l
-= ImageList
.ImageSize
.Width
+ 3;
900 return (x
> l
&& x
< l
+ 8);
903 private bool IsCheckboxArea (TreeNode node
, int x
)
905 int l
= CheckBoxLeft (node
);
906 return (x
> l
&& x
< l
+ 10);
909 private int CheckBoxLeft (TreeNode node
)
911 int l
= node
.Bounds
.Left
+ 5;
913 if (show_root_lines
|| node
.Parent
!= null)
915 if (ImageList
!= null)
916 l
-= ImageList
.ImageSize
.Width
+ 3;
921 internal void RecalculateVisibleOrder (TreeNode start
)
923 if (update_stack
> 0)
931 order
= start
.visible_order
;
933 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (start
);
934 while (walk
.MoveNext ()) {
935 walk
.CurrentNode
.visible_order
= order
;
939 max_visible_order
= order
;
942 internal void SetTop (TreeNode node
)
944 if (!vbar
.is_visible
)
947 TreeNode first
= root_node
.FirstNode
;
950 return; // I don't think its possible for this to happen
952 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (first
);
954 int vc
= VisibleCount
;
955 while (walk
.CurrentNode
!= node
&& walk
.MoveNext () && offset
< vbar
.Maximum
- vc
)
958 SetVScrollTop (walk
.CurrentNode
);
961 internal void SetBottom (TreeNode node
)
963 if (!vbar
.is_visible
)
966 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (node
);
968 int bottom
= ViewportRectangle
.Bottom
;
970 while (walk
.MovePrevious ()) {
971 if (walk
.CurrentNode
.Bounds
.Bottom
<= bottom
)
976 int nv
= vbar
.Value
+ offset
;
977 if (vbar
.Value
+ offset
< vbar
.Maximum
) {
981 Console
.Error
.WriteLine ("setting bottom to value greater then maximum ({0}, {1})",
988 internal void UpdateBelow (TreeNode node
)
990 if (update_stack
> 0) {
991 update_needed
= true;
995 if (node
== root_node
) {
996 Invalidate (ViewportRectangle
);
1000 // We need to update the current node so the plus/minus block gets update too
1001 int top
= Math
.Max (node
.Bounds
.Top
- 1, 0);
1002 Rectangle invalid
= new Rectangle (0, top
,
1003 Width
, Height
- top
);
1004 Invalidate (invalid
);
1007 internal void UpdateNode (TreeNode node
)
1012 if (update_stack
> 0) {
1013 update_needed
= true;
1017 if (node
== root_node
) {
1022 Rectangle invalid
= new Rectangle (0, node
.Bounds
.Top
- 1, Width
,
1023 node
.Bounds
.Height
+ 1);
1024 Invalidate (invalid
);
1027 internal void UpdateNodePlusMinus (TreeNode node
)
1029 if (update_stack
> 0) {
1030 update_needed
= true;
1034 int l
= node
.Bounds
.Left
+ 5;
1036 if (show_root_lines
|| node
.Parent
!= null)
1038 if (ImageList
!= null)
1039 l
-= ImageList
.ImageSize
.Width
+ 3;
1043 Invalidate (new Rectangle (l
, node
.Bounds
.Top
, 8, node
.Bounds
.Height
));
1046 internal override void OnPaintInternal (PaintEventArgs pe
)
1048 Draw (pe
.ClipRectangle
, pe
.Graphics
);
1051 private void Draw (Rectangle clip
, Graphics dc
)
1053 dc
.FillRectangle (ThemeEngine
.Current
.ResPool
.GetSolidBrush (BackColor
), clip
);
1055 Color dash_color
= ControlPaint
.Dark (BackColor
);
1056 if (dash_color
== BackColor
)
1057 dash_color
= ControlPaint
.Light (BackColor
);
1058 dash
= new Pen (dash_color
, 1);
1059 dash
.DashStyle
= DashStyle
.Dot
;
1061 Rectangle viewport
= ViewportRectangle
;
1062 Rectangle original_clip
= clip
;
1063 if (clip
.Bottom
> viewport
.Bottom
)
1064 clip
.Height
= viewport
.Bottom
- clip
.Top
;
1066 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (TopNode
);
1067 while (walk
.MoveNext ()) {
1068 TreeNode current
= walk
.CurrentNode
;
1070 // Haven't gotten to visible nodes yet
1071 if (current
.GetY () + ActualItemHeight
< clip
.Top
)
1074 // Past the visible nodes
1075 if (current
.GetY () > clip
.Bottom
)
1078 DrawNode (current
, dc
, clip
);
1081 if (hbar
.Visible
&& vbar
.Visible
) {
1082 Rectangle corner
= new Rectangle (hbar
.Right
, vbar
.Bottom
, vbar
.Width
, hbar
.Height
);
1083 if (original_clip
.IntersectsWith (corner
))
1084 dc
.FillRectangle (ThemeEngine
.Current
.ResPool
.GetSolidBrush (ThemeEngine
.Current
.ColorControl
),
1089 private void DrawNodePlusMinus (TreeNode node
, Graphics dc
, int x
, int middle
)
1091 dc
.DrawRectangle (SystemPens
.ControlDark
, x
, middle
- 4, 8, 8);
1093 if (node
.IsExpanded
) {
1094 dc
.DrawLine (SystemPens
.ControlDarkDark
, x
+ 2, middle
, x
+ 6, middle
);
1096 dc
.DrawLine (SystemPens
.ControlDarkDark
, x
+ 2, middle
, x
+ 6, middle
);
1097 dc
.DrawLine (SystemPens
.ControlDarkDark
, x
+ 4, middle
- 2, x
+ 4, middle
+ 2);
1101 private void DrawNodeCheckBox (TreeNode node
, Graphics dc
, int x
, int middle
)
1103 Pen pen
= ThemeEngine
.Current
.ResPool
.GetSizedPen(Color
.Black
, 2);
1104 dc
.DrawRectangle (pen
, x
+ 3, middle
- 4, 11, 11);
1107 Pen check_pen
= ThemeEngine
.Current
.ResPool
.GetPen(Color
.Black
);
1112 Rectangle rect
= new Rectangle (x
+ 5, middle
- 2, check_size
, check_size
);
1114 for (int i
= 0; i
< lineWidth
; i
++) {
1115 dc
.DrawLine (check_pen
, rect
.Left
+ 1, rect
.Top
+ lineWidth
+ i
, rect
.Left
+ 3, rect
.Top
+ 5 + i
);
1116 dc
.DrawLine (check_pen
, rect
.Left
+ 3, rect
.Top
+ 5 + i
, rect
.Left
+ 7, rect
.Top
+ 1 + i
);
1121 private void DrawNodeLines (TreeNode node
, Graphics dc
, Rectangle clip
, Pen dash
, int x
, int y
, int middle
)
1126 if (node
.nodes
.Count
> 0 && show_plus_minus
)
1131 dc
.DrawLine (dash
, x
- indent
+ ladjust
, middle
, x
+ radjust
, middle
);
1133 if (node
.PrevNode
!= null || node
.Parent
!= null) {
1135 dc
.DrawLine (dash
, x
- indent
+ ladjust
, node
.Bounds
.Top
,
1136 x
- indent
+ ladjust
, middle
- (show_plus_minus
&& node
.Nodes
.Count
> 0 ? 4 : 0));
1139 if (node
.NextNode
!= null) {
1141 dc
.DrawLine (dash
, x
- indent
+ ladjust
, middle
+ (show_plus_minus
&& node
.Nodes
.Count
> 0 ? 4 : 0),
1142 x
- indent
+ ladjust
, node
.Bounds
.Bottom
);
1147 if (show_plus_minus
)
1149 TreeNode parent
= node
.Parent
;
1150 while (parent
!= null) {
1151 if (parent
.NextNode
!= null) {
1152 int px
= parent
.GetLinesX () - indent
+ ladjust
;
1153 dc
.DrawLine (dash
, px
, node
.Bounds
.Top
, px
, node
.Bounds
.Bottom
);
1155 parent
= parent
.Parent
;
1159 private void DrawNodeImage (TreeNode node
, Graphics dc
, Rectangle clip
, int x
, int y
)
1161 // Rectangle r = new Rectangle (x, y + 2, ImageList.ImageSize.Width, ImageList.ImageSize.Height);
1163 if (!RectsIntersect (clip
, x
, y
+ 2, ImageList
.ImageSize
.Width
, ImageList
.ImageSize
.Height
))
1166 if (ImageList
== null)
1170 if (node
.ImageIndex
> -1 && node
.ImageIndex
< ImageList
.Images
.Count
) {
1171 use_index
= node
.ImageIndex
;
1172 } else if (ImageIndex
> -1 && ImageIndex
< ImageList
.Images
.Count
) {
1173 use_index
= ImageIndex
;
1176 if (use_index
== -1 && ImageList
.Images
.Count
> 0) {
1180 if (use_index
!= -1) {
1181 ImageList
.Draw (dc
, x
, y
+ 2, ImageList
.ImageSize
.Width
,
1182 ImageList
.ImageSize
.Height
, use_index
);
1186 private void LabelEditFinished (object sender
, EventArgs e
)
1188 EndEdit (edit_node
);
1191 internal void BeginEdit (TreeNode node
)
1193 if (edit_node
!= null)
1194 EndEdit (edit_node
);
1196 if (edit_text_box
== null) {
1197 edit_text_box
= new LabelEditTextBox ();
1198 edit_text_box
.BorderStyle
= BorderStyle
.FixedSingle
;
1199 edit_text_box
.EditingFinished
+= new EventHandler (LabelEditFinished
);
1200 Controls
.Add (edit_text_box
);
1203 edit_text_box
.Bounds
= node
.Bounds
;
1204 edit_text_box
.Width
+= 4;
1206 edit_text_box
.Text
= node
.Text
;
1207 edit_text_box
.Visible
= true;
1208 edit_text_box
.Focus ();
1209 edit_text_box
.SelectAll ();
1211 edit_args
= new NodeLabelEditEventArgs (edit_node
);
1212 OnBeforeLabelEdit (edit_args
);
1214 if (edit_args
.CancelEdit
)
1220 internal void EndEdit (TreeNode node
)
1222 if (edit_text_box
!= null && edit_text_box
.Visible
) {
1223 edit_text_box
.Visible
= false;
1226 if (edit_node
!= null && edit_node
== node
) {
1227 OnAfterLabelEdit (edit_args
);
1229 if (!edit_args
.CancelEdit
) {
1230 if (edit_args
.Label
!= null)
1231 edit_node
.Text
= edit_args
.Label
;
1233 edit_node
.Text
= edit_text_box
.Text
;
1243 internal int GetNodeWidth (TreeNode node
)
1245 Font font
= node
.NodeFont
;
1246 if (node
.NodeFont
== null)
1248 return (int) DeviceContext
.MeasureString (node
.Text
, font
, 0, string_format
).Width
+ 3;
1251 private void DrawSelectionAndFocus(TreeNode node
, Graphics dc
, Rectangle r
)
1253 if (Focused
&& focused_node
== node
) {
1254 ControlPaint
.DrawFocusRectangle (dc
, r
, ForeColor
, BackColor
);
1257 if (Focused
&& node
== highlighted_node
) {
1258 dc
.FillRectangle (ThemeEngine
.Current
.ResPool
.GetSolidBrush (ThemeEngine
.Current
.ColorHighlight
), r
);
1259 } else if (!hide_selection
&& node
== highlighted_node
) {
1260 dc
.FillRectangle (SystemBrushes
.Control
, r
);
1262 dc
.FillRectangle (ThemeEngine
.Current
.ResPool
.GetSolidBrush (node
.BackColor
), r
);
1266 private void DrawStaticNode (TreeNode node
, Graphics dc
)
1268 if (!full_row_select
)
1269 DrawSelectionAndFocus(node
, dc
, node
.Bounds
);
1271 Font font
= node
.NodeFont
;
1272 if (node
.NodeFont
== null)
1274 Color text_color
= (Focused
&& node
== highlighted_node
?
1275 ThemeEngine
.Current
.ColorHighlightText
: node
.ForeColor
);
1276 dc
.DrawString (node
.Text
, font
,
1277 ThemeEngine
.Current
.ResPool
.GetSolidBrush (text_color
),
1278 node
.Bounds
, string_format
);
1281 private void DrawNode (TreeNode node
, Graphics dc
, Rectangle clip
)
1283 int child_count
= node
.nodes
.Count
;
1284 int y
= node
.GetY ();
1285 int middle
= y
+ (ActualItemHeight
/ 2);
1287 if (full_row_select
) {
1288 Rectangle r
= new Rectangle (1, y
+ 2, ViewportRectangle
.Width
- 2, ActualItemHeight
);
1289 DrawSelectionAndFocus (node
, dc
, r
);
1292 if ((show_root_lines
|| node
.Parent
!= null) && show_plus_minus
&& child_count
> 0)
1293 DrawNodePlusMinus (node
, dc
, node
.GetLinesX () - Indent
+ 5, middle
);
1296 DrawNodeCheckBox (node
, dc
, CheckBoxLeft (node
) - 3, middle
);
1299 DrawNodeLines (node
, dc
, clip
, dash
, node
.GetLinesX (), y
, middle
);
1301 if (ImageList
!= null)
1302 DrawNodeImage (node
, dc
, clip
, node
.GetImageX (), y
);
1304 if (!node
.IsEditing
)
1305 DrawStaticNode (node
, dc
);
1308 internal void UpdateScrollBars ()
1310 if (IsDisposed
|| update_stack
> 0 || !IsHandleCreated
|| !Visible
)
1319 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (root_node
);
1321 while (walk
.MoveNext ()) {
1322 int r
= walk
.CurrentNode
.Bounds
.Right
;
1323 int b
= walk
.CurrentNode
.Bounds
.Bottom
;
1331 // Remove scroll adjustments
1332 if (nodes
.Count
> 0)
1333 height
-= nodes
[0].Bounds
.Top
;
1334 width
+= hbar_offset
;
1336 if (height
> ClientRectangle
.Height
) {
1339 if (width
> ClientRectangle
.Width
- SystemInformation
.VerticalScrollBarWidth
)
1341 } else if (width
> ClientRectangle
.Width
) {
1345 if (!vert
&& horz
&& height
> ClientRectangle
.Height
- SystemInformation
.HorizontalScrollBarHeight
)
1350 int visible_height
= horz
? ClientRectangle
.Height
- hbar
.Height
: ClientRectangle
.Height
;
1351 vbar
.SetValues (Math
.Max (0, max_visible_order
- 2), visible_height
/ ActualItemHeight
);
1353 vbar.Maximum = max_visible_order;
1354 vbar.LargeChange = ClientRectangle.Height / ItemHeight;
1357 if (!vbar_bounds_set
) {
1358 vbar
.Bounds
= new Rectangle (ClientRectangle
.Width
- vbar
.Width
, 0, vbar
.Width
,
1359 ClientRectangle
.Height
-
1360 (horz
? SystemInformation
.VerticalScrollBarWidth
: 0));
1361 vbar_bounds_set
= true;
1363 // We need to recalc the hbar if the vbar is now visible
1364 hbar_bounds_set
= false;
1367 vbar
.Visible
= true;
1370 top_node
= root_node
.FirstNode
;
1371 RecalculateVisibleOrder (root_node
);
1372 vbar
.Visible
= false;
1373 vbar_bounds_set
= false;
1377 hbar
.SetValues (width
+ 1, ClientRectangle
.Width
- (vert
? SystemInformation
.VerticalScrollBarWidth
: 0));
1379 hbar.LargeChange = ClientRectangle.Width;
1380 hbar.Maximum = width + 1;
1383 if (!hbar_bounds_set
) {
1384 hbar
.Bounds
= new Rectangle (0, ClientRectangle
.Height
- hbar
.Height
,
1385 ClientRectangle
.Width
- (vert
? SystemInformation
.VerticalScrollBarWidth
: 0),
1387 hbar_bounds_set
= true;
1389 hbar
.Visible
= true;
1392 hbar
.Visible
= false;
1393 hbar_bounds_set
= false;
1397 private void SizeChangedHandler (object sender
, EventArgs e
)
1399 if (IsHandleCreated
) {
1400 if (max_visible_order
== -1)
1401 RecalculateVisibleOrder (root_node
);
1402 UpdateScrollBars ();
1406 vbar
.Bounds
= new Rectangle (ClientRectangle
.Width
- vbar
.Width
, 0, vbar
.Width
,
1407 ClientRectangle
.Height
- (hbar
.Visible
? SystemInformation
.HorizontalScrollBarHeight
: 0));
1411 hbar
.Bounds
= new Rectangle (0, ClientRectangle
.Height
- hbar
.Height
,
1412 ClientRectangle
.Width
- (vbar
.Visible
? SystemInformation
.VerticalScrollBarWidth
: 0), hbar
.Height
);
1416 private void VScrollBarValueChanged (object sender
, EventArgs e
)
1418 EndEdit (edit_node
);
1420 SetVScrollPos (vbar
.Value
, null);
1423 private void SetVScrollPos (int pos
, TreeNode new_top
)
1428 if (skipped_nodes
== pos
)
1431 int old_skip
= skipped_nodes
;
1432 skipped_nodes
= pos
;
1433 int diff
= old_skip
- skipped_nodes
;
1435 // Determine the new top node if we have to
1436 if (new_top
== null) {
1437 if (top_node
== null)
1438 top_node
= nodes
[0];
1440 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (TopNode
);
1442 for (int i
= diff
; i
<= 0; i
++)
1444 new_top
= walk
.CurrentNode
;
1446 for (int i
= 0; i
<= diff
; i
++)
1447 walk
.MovePrevious ();
1448 new_top
= walk
.CurrentNode
;
1453 int y_move
= diff
* ActualItemHeight
;
1454 XplatUI
.ScrollWindow (Handle
, ViewportRectangle
, 0, y_move
, false);
1457 private void SetVScrollTop (TreeNode new_top
)
1459 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (root_node
);
1462 while (walk
.MoveNext () && walk
.CurrentNode
!= new_top
)
1466 vbar
.Value
= skipped_nodes
;
1469 private void HScrollBarValueChanged(object sender
, EventArgs e
)
1471 EndEdit (edit_node
);
1473 int old_offset
= hbar_offset
;
1474 hbar_offset
= hbar
.Value
;
1476 if (hbar_offset
< 0) {
1480 XplatUI
.ScrollWindow (Handle
, ViewportRectangle
, old_offset
- hbar_offset
, 0, false);
1483 internal void ExpandBelow (TreeNode node
, int count_to_next
)
1485 if (update_stack
> 0) {
1486 update_needed
= true;
1490 Rectangle below
= new Rectangle (0, node
.Bounds
.Bottom
+ 2, ViewportRectangle
.Width
,
1491 ViewportRectangle
.Height
- node
.Bounds
.Bottom
);
1493 int amount
= count_to_next
* ActualItemHeight
;
1496 XplatUI
.ScrollWindow (Handle
, below
, 0, amount
, false);
1498 if (show_plus_minus
) {
1499 //int linesx = node.GetLinesX ();
1500 Invalidate (new Rectangle (0, node
.GetY (), Width
, ActualItemHeight
));
1504 internal void CollapseBelow (TreeNode node
, int count_to_next
)
1506 if (update_stack
> 0) {
1507 update_needed
= true;
1511 Rectangle below
= new Rectangle (0, node
.Bounds
.Bottom
+ 2, ViewportRectangle
.Width
,
1512 ViewportRectangle
.Height
- node
.Bounds
.Bottom
+ 2);
1514 int amount
= count_to_next
* ActualItemHeight
;
1517 XplatUI
.ScrollWindow (Handle
, below
, 0, -amount
, false);
1519 if (show_plus_minus
) {
1520 //int linesx = node.GetLinesX ();
1521 Invalidate (new Rectangle (0, node
.GetY (), Width
, ActualItemHeight
));
1525 private void MouseWheelHandler(object sender
, MouseEventArgs e
) {
1527 if (vbar
== null || !vbar
.is_visible
) {
1532 vbar
.Value
= Math
.Min(vbar
.Value
+ SystemInformation
.MouseWheelScrollLines
, vbar
.Maximum
- VisibleCount
+ 1);
1534 vbar
.Value
= Math
.Max(0, vbar
.Value
- SystemInformation
.MouseWheelScrollLines
);
1538 private void VisibleChangedHandler (object sender
, EventArgs e
)
1541 UpdateScrollBars ();
1545 private void FontChangedHandler (object sender
, EventArgs e
)
1547 InvalidateNodeWidthRecursive (root_node
);
1550 private void InvalidateNodeWidthRecursive (TreeNode node
)
1552 node
.InvalidateWidth ();
1553 foreach (TreeNode child
in node
.Nodes
) {
1554 InvalidateNodeWidthRecursive (child
);
1558 private void GotFocusHandler (object sender
, EventArgs e
)
1560 if (selected_node
== null)
1561 SelectedNode
= top_node
;
1563 UpdateNode (selected_node
);
1566 private void LostFocusHandler (object sender
, EventArgs e
)
1568 UpdateNode (SelectedNode
);
1571 private void MouseDownHandler (object sender
, MouseEventArgs e
)
1573 if (e
.Button
== MouseButtons
.Right
)
1576 TreeNode node
= GetNodeAt (e
.Y
);
1580 if (show_plus_minus
&& IsPlusMinusArea (node
, e
.X
)) {
1583 } else if (checkboxes
&& IsCheckboxArea (node
, e
.X
)) {
1584 node
.check_reason
= TreeViewAction
.ByMouse
;
1585 node
.Checked
= !node
.Checked
;
1588 } else if (IsSelectableArea (node
, e
.X
) || full_row_select
) {
1589 TreeNode old_highlighted
= highlighted_node
;
1590 highlighted_node
= node
;
1591 if (label_edit
&& e
.Clicks
== 1 && highlighted_node
== old_highlighted
) {
1593 } else if (highlighted_node
!= focused_node
) {
1594 Size ds
= SystemInformation
.DragSize
;
1595 mouse_rect
.X
= e
.X
- ds
.Width
;
1596 mouse_rect
.Y
= e
.Y
- ds
.Height
;
1597 mouse_rect
.Width
= ds
.Width
* 2;
1598 mouse_rect
.Height
= ds
.Height
* 2;
1600 select_mmove
= true;
1603 Invalidate (highlighted_node
.Bounds
);
1604 if (old_highlighted
!= null)
1605 Invalidate (Bloat (old_highlighted
.Bounds
));
1609 private void MouseUpHandler (object sender
, MouseEventArgs e
) {
1617 if (e
.Button
== MouseButtons
.Right
) {
1618 Invalidate (highlighted_node
.Bounds
);
1619 highlighted_node
= selected_node
;
1620 Invalidate (selected_node
.Bounds
);
1622 select_mmove
= false;
1624 TreeViewCancelEventArgs ce
= new TreeViewCancelEventArgs (highlighted_node
, false, TreeViewAction
.ByMouse
);
1625 OnBeforeSelect (ce
);
1629 if (focused_node
!= null) {
1630 invalid
= Rectangle
.Union (Bloat (focused_node
.Bounds
),
1631 Bloat (highlighted_node
.Bounds
));
1633 invalid
= Bloat (highlighted_node
.Bounds
);
1635 selected_node
= highlighted_node
;
1636 focused_node
= highlighted_node
;
1637 OnAfterSelect (new TreeViewEventArgs (selected_node
, TreeViewAction
.ByMouse
));
1639 Invalidate (invalid
);
1641 highlighted_node
= focused_node
;
1642 selected_node
= focused_node
;
1646 private void MouseMoveHandler (object sender
, MouseEventArgs e
) {
1648 if (e
.Button
== MouseButtons
.Left
|| e
.Button
== MouseButtons
.Right
) {
1649 if (drag_begin_x
== -1 && drag_begin_y
== -1) {
1653 double rise
= Math
.Pow (drag_begin_x
- e
.X
, 2);
1654 double run
= Math
.Pow (drag_begin_y
- e
.Y
, 2);
1655 double move
= Math
.Sqrt (rise
+ run
);
1657 TreeNode drag
= GetNodeAtUseX (e
.X
, e
.Y
);
1660 OnItemDrag (new ItemDragEventArgs (e
.Button
, drag
));
1669 // If there is enough movement before the mouse comes up,
1670 // selection is reverted back to the originally selected node
1671 if (!select_mmove
|| mouse_rect
.Contains (e
.X
, e
.Y
))
1674 Invalidate (highlighted_node
.Bounds
);
1675 Invalidate (selected_node
.Bounds
);
1676 Invalidate (focused_node
.Bounds
);
1678 highlighted_node
= selected_node
;
1679 focused_node
= selected_node
;
1681 select_mmove
= false;
1684 private void DoubleClickHandler (object sender
, MouseEventArgs e
) {
1685 TreeNode node
= GetNodeAtUseX (e
.X
,e
.Y
);
1692 private bool RectsIntersect (Rectangle r
, int left
, int top
, int width
, int height
)
1694 return !((r
.Left
> left
+ width
) || (r
.Right
< left
) ||
1695 (r
.Top
> top
+ height
) || (r
.Bottom
< top
));
1698 #endregion // Internal & Private Methods and Properties
1701 static object ItemDragEvent
= new object ();
1702 static object AfterCheckEvent
= new object ();
1703 static object AfterCollapseEvent
= new object ();
1704 static object AfterExpandEvent
= new object ();
1705 static object AfterLabelEditEvent
= new object ();
1706 static object AfterSelectEvent
= new object ();
1707 static object BeforeCheckEvent
= new object ();
1708 static object BeforeCollapseEvent
= new object ();
1709 static object BeforeExpandEvent
= new object ();
1710 static object BeforeLabelEditEvent
= new object ();
1711 static object BeforeSelectEvent
= new object ();
1713 public event ItemDragEventHandler ItemDrag
{
1714 add { Events.AddHandler (ItemDragEvent, value); }
1715 remove { Events.RemoveHandler (ItemDragEvent, value); }
1718 public event TreeViewEventHandler AfterCheck
{
1719 add { Events.AddHandler (AfterCheckEvent, value); }
1720 remove { Events.RemoveHandler (AfterCheckEvent, value); }
1723 public event TreeViewEventHandler AfterCollapse
{
1724 add { Events.AddHandler (AfterCollapseEvent, value); }
1725 remove { Events.RemoveHandler (AfterCollapseEvent, value); }
1728 public event TreeViewEventHandler AfterExpand
{
1729 add { Events.AddHandler (AfterExpandEvent, value); }
1730 remove { Events.RemoveHandler (AfterExpandEvent, value); }
1733 public event NodeLabelEditEventHandler AfterLabelEdit
{
1734 add { Events.AddHandler (AfterLabelEditEvent, value); }
1735 remove { Events.RemoveHandler (AfterLabelEditEvent, value); }
1738 public event TreeViewEventHandler AfterSelect
{
1739 add { Events.AddHandler (AfterSelectEvent, value); }
1740 remove { Events.RemoveHandler (AfterSelectEvent, value); }
1743 public event TreeViewCancelEventHandler BeforeCheck
{
1744 add { Events.AddHandler (BeforeCheckEvent, value); }
1745 remove { Events.RemoveHandler (BeforeCheckEvent, value); }
1748 public event TreeViewCancelEventHandler BeforeCollapse
{
1749 add { Events.AddHandler (BeforeCollapseEvent, value); }
1750 remove { Events.RemoveHandler (BeforeCollapseEvent, value); }
1753 public event TreeViewCancelEventHandler BeforeExpand
{
1754 add { Events.AddHandler (BeforeExpandEvent, value); }
1755 remove { Events.RemoveHandler (BeforeExpandEvent, value); }
1758 public event NodeLabelEditEventHandler BeforeLabelEdit
{
1759 add { Events.AddHandler (BeforeLabelEditEvent, value); }
1760 remove { Events.RemoveHandler (BeforeLabelEditEvent, value); }
1763 public event TreeViewCancelEventHandler BeforeSelect
{
1764 add { Events.AddHandler (BeforeSelectEvent, value); }
1765 remove { Events.RemoveHandler (BeforeSelectEvent, value); }
1769 [EditorBrowsable (EditorBrowsableState
.Never
)]
1770 public new event EventHandler BackgroundImageChanged
{
1771 add { base.BackgroundImageChanged += value; }
1772 remove { base.BackgroundImageChanged -= value; }
1775 [EditorBrowsable (EditorBrowsableState
.Never
)]
1777 public new event PaintEventHandler Paint
{
1778 add { base.Paint += value; }
1779 remove { base.Paint -= value; }
1782 [EditorBrowsable (EditorBrowsableState
.Never
)]
1784 public new event EventHandler TextChanged
{
1785 add { base.TextChanged += value; }
1786 remove { base.TextChanged -= value; }
1788 #endregion // Events