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
);
116 SetStyle (ControlStyles
.UserPaint
| ControlStyles
.StandardClick
118 | ControlStyles
.UseTextForAccessibility
122 string_format
= new StringFormat ();
123 string_format
.LineAlignment
= StringAlignment
.Center
;
124 string_format
.Alignment
= StringAlignment
.Center
;
126 vbar
= new ImplicitVScrollBar ();
127 hbar
= new ImplicitHScrollBar ();
129 vbar
.Visible
= false;
130 hbar
.Visible
= false;
131 vbar
.ValueChanged
+= new EventHandler (VScrollBarValueChanged
);
132 hbar
.ValueChanged
+= new EventHandler (HScrollBarValueChanged
);
135 Controls
.AddImplicit (vbar
);
136 Controls
.AddImplicit (hbar
);
140 #endregion // Public Constructors
142 #region Public Instance Properties
143 public override Color BackColor
{
144 get { return base.BackColor;}
145 set { base.BackColor = value; }
150 [EditorBrowsable(EditorBrowsableState
.Never
)]
151 public override Image BackgroundImage
{
152 get { return base.BackgroundImage; }
153 set { base.BackgroundImage = value; }
156 [DefaultValue(BorderStyle
.Fixed3D
)]
158 public BorderStyle BorderStyle
{
159 get { return InternalBorderStyle; }
160 set { InternalBorderStyle = value; }
163 [DefaultValue(false)]
164 public bool CheckBoxes
{
165 get { return checkboxes; }
167 if (value == checkboxes
)
171 // Match a "bug" in the MS implementation where disabling checkboxes
172 // collapses the entire tree, but enabling them does not affect the
173 // state of the tree.
175 root_node
.CollapseAllUncheck ();
181 public override Color ForeColor
{
182 get { return base.ForeColor; }
183 set { base.ForeColor = value; }
185 [DefaultValue(false)]
186 public bool FullRowSelect
{
187 get { return full_row_select; }
189 if (value == full_row_select
)
191 full_row_select
= value;
196 public bool HideSelection
{
197 get { return hide_selection; }
199 if (hide_selection
== value)
201 hide_selection
= value;
206 [DefaultValue(false)]
207 public bool HotTracking
{
208 get { return hot_tracking; }
209 set { hot_tracking = value; }
213 [Editor("System.Windows.Forms.Design.ImageIndexEditor, " + Consts
.AssemblySystem_Design
, typeof(System
.Drawing
.Design
.UITypeEditor
))]
215 [TypeConverter(typeof(TreeViewImageIndexConverter
))]
216 public int ImageIndex
{
217 get { return image_index; }
220 throw new ArgumentException ("'" + value + "' is not a valid value for 'value'. " +
221 "'value' must be greater than or equal to 0.");
223 if (image_index
== value)
231 public ImageList ImageList
{
232 get { return image_list; }
241 get { return indent; }
246 throw new ArgumentException ("'" + value + "' is not a valid value for 'Indent'. " +
247 "'Indent' must be less than or equal to 32000");
250 throw new ArgumentException ("'" + value + "' is not a valid value for 'Indent'. " +
251 "'Indent' must be greater than or equal to 0.");
259 public int ItemHeight
{
261 if (item_height
== -1)
262 return FontHeight
+ 3;
266 if (value == item_height
)
273 internal int ActualItemHeight
{
275 int res
= ItemHeight
;
276 if (ImageList
!= null && ImageList
.ImageSize
.Height
> res
)
277 res
= ImageList
.ImageSize
.Height
;
282 [DefaultValue(false)]
283 public bool LabelEdit
{
284 get { return label_edit; }
285 set { label_edit = value; }
288 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Content
)]
289 [MergableProperty(false)]
291 public TreeNodeCollection Nodes
{
292 get { return nodes; }
296 public string PathSeparator
{
297 get { return path_separator; }
298 set { path_separator = value; }
302 public bool Scrollable
{
303 get { return scrollable; }
305 if (scrollable
== value)
312 [Editor("System.Windows.Forms.Design.ImageIndexEditor, " + Consts
.AssemblySystem_Design
, typeof(System
.Drawing
.Design
.UITypeEditor
))]
313 [TypeConverter(typeof(TreeViewImageIndexConverter
))]
316 public int SelectedImageIndex
{
317 get { return selected_image_index; }
320 throw new ArgumentException ("'" + value + "' is not a valid value for 'value'. " +
321 "'value' must be greater than or equal to 0.");
323 UpdateNode (SelectedNode
);
328 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
329 public TreeNode SelectedNode
{
330 get { return selected_node; }
332 if (selected_node
== value) {
333 selection_action
= TreeViewAction
.Unknown
;
337 TreeViewCancelEventArgs e
= new TreeViewCancelEventArgs (value, false, selection_action
);
343 Rectangle invalid
= Rectangle
.Empty
;
345 if (selected_node
!= null) {
346 invalid
= Bloat (selected_node
.Bounds
);
348 if (focused_node
!= null) {
349 invalid
= Rectangle
.Union (invalid
,
350 Bloat (focused_node
.Bounds
));
354 invalid
= Rectangle
.Union (invalid
, Bloat (value.Bounds
));
356 highlighted_node
= value;
357 selected_node
= value;
358 focused_node
= value;
360 if (full_row_select
) {
362 invalid
.Width
= ViewportRectangle
.Width
;
365 if (invalid
!= Rectangle
.Empty
)
366 Invalidate (invalid
);
368 // We ensure its visible after we update because
369 // scrolling is used for insure visible
370 if (selected_node
!= null)
371 selected_node
.EnsureVisible ();
373 OnAfterSelect (new TreeViewEventArgs (value, TreeViewAction
.Unknown
));
374 selection_action
= TreeViewAction
.Unknown
;
378 private Rectangle
Bloat (Rectangle rect
)
388 public bool ShowLines
{
389 get { return show_lines; }
391 if (show_lines
== value)
399 public bool ShowPlusMinus
{
400 get { return show_plus_minus; }
402 if (show_plus_minus
== value)
404 show_plus_minus
= value;
410 public bool ShowRootLines
{
411 get { return show_root_lines; }
413 if (show_root_lines
== value)
415 show_root_lines
= value;
420 [DefaultValue(false)]
422 get { return sorted; }
428 top_node
= root_node
;
429 RecalculateVisibleOrder (root_node
);
437 [EditorBrowsable(EditorBrowsableState
.Never
)]
439 public override string Text
{
440 get { return base.Text; }
441 set { base.Text = value; }
445 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
446 public TreeNode TopNode
{
447 get { return top_node; }
451 [DesignerSerializationVisibility(DesignerSerializationVisibility
.Hidden
)]
452 public int VisibleCount
{
454 return ViewportRectangle
.Height
/ ActualItemHeight
;
458 #endregion // Public Instance Properties
460 #region Protected Instance Properties
461 protected override CreateParams CreateParams
{
463 CreateParams cp
= base.CreateParams
;
468 protected override Size DefaultSize
{
469 get { return new Size (121, 97); }
472 #endregion // Protected Instance Properties
474 #region Public Instance Methods
475 public void BeginUpdate ()
480 public void EndUpdate ()
482 if (update_stack
> 1) {
487 RecalculateVisibleOrder (root_node
);
489 if (SelectedNode
!= null)
490 SelectedNode
.EnsureVisible ();
491 Invalidate (ViewportRectangle
);
492 update_needed
= false;
497 public void ExpandAll ()
500 root_node
.ExpandAll ();
504 // Walk all the way to the end, then walk back visible count
505 //to find the new top node
506 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (root_node
);
507 while (walk
.MoveNext ())
510 for (int i
= 0; i
< VisibleCount
- 1; i
++)
511 walk
.MovePrevious ();
513 SetTop (walk
.CurrentNode
);
517 public void CollapseAll ()
519 TreeNode walk
= top_node
;
521 while (walk
.parent
!= root_node
)
525 root_node
.CollapseAll ();
531 public TreeNode
GetNodeAt (Point pt
) {
532 return GetNodeAt (pt
.Y
);
535 public TreeNode
GetNodeAt (int x
, int y
)
537 return GetNodeAt (y
);
540 private TreeNode
GetNodeAtUseX (int x
, int y
) {
541 TreeNode node
= GetNodeAt (y
);
542 if (node
== null || !(IsTextArea (node
, x
) || full_row_select
))
548 public int GetNodeCount (bool include_subtrees
) {
549 return root_node
.GetNodeCount (include_subtrees
);
552 public override string ToString () {
553 int count
= Nodes
.Count
;
555 return String
.Concat (base.ToString (), "Node Count: 0");
556 return String
.Concat (base.ToString (), "Node Count: ", count
, " Nodes[0]: ", Nodes
[0]);
560 #endregion // Public Instance Methods
562 #region Protected Instance Methods
563 protected override void CreateHandle () {
564 base.CreateHandle ();
569 protected override void Dispose (bool disposing
) {
573 base.Dispose (disposing
);
576 protected OwnerDrawPropertyBag
GetItemRenderStyles (TreeNode node
, int state
) {
577 return node
.prop_bag
;
580 protected override bool IsInputKey (Keys key_data
)
582 if ((key_data
& Keys
.Alt
) == 0) {
583 switch (key_data
& Keys
.KeyCode
) {
597 return base.IsInputKey (key_data
);
600 protected override void OnKeyDown (KeyEventArgs e
)
602 OpenTreeNodeEnumerator ne
;
604 switch (e
.KeyData
& Keys
.KeyCode
) {
606 if (selected_node
!= null && selected_node
.IsExpanded
)
607 selected_node
.Expand ();
610 if (selected_node
!= null && selected_node
.IsExpanded
)
611 selected_node
.Collapse ();
614 if (selected_node
!= null) {
615 if (selected_node
.IsExpanded
)
616 selected_node
.Collapse ();
618 TreeNode parent
= selected_node
.Parent
;
619 if (parent
!= null) {
620 selection_action
= TreeViewAction
.ByKeyboard
;
621 SelectedNode
= parent
;
627 if (selected_node
!= null) {
628 if (!selected_node
.IsExpanded
)
629 selected_node
.Expand ();
631 TreeNode child
= selected_node
.FirstNode
;
633 SelectedNode
= child
;
638 if (selected_node
!= null) {
639 ne
= new OpenTreeNodeEnumerator (selected_node
);
640 if (ne
.MovePrevious () && ne
.MovePrevious ()) {
641 selection_action
= TreeViewAction
.ByKeyboard
;
642 SelectedNode
= ne
.CurrentNode
;
647 if (selected_node
!= null) {
648 ne
= new OpenTreeNodeEnumerator (selected_node
);
649 if (ne
.MoveNext () && ne
.MoveNext ()) {
650 selection_action
= TreeViewAction
.ByKeyboard
;
651 SelectedNode
= ne
.CurrentNode
;
656 if (root_node
.Nodes
.Count
> 0) {
657 ne
= new OpenTreeNodeEnumerator (root_node
.Nodes
[0]);
658 if (ne
.MoveNext ()) {
659 selection_action
= TreeViewAction
.ByKeyboard
;
660 SelectedNode
= ne
.CurrentNode
;
665 if (root_node
.Nodes
.Count
> 0) {
666 ne
= new OpenTreeNodeEnumerator (root_node
.Nodes
[0]);
667 while (ne
.MoveNext ())
669 selection_action
= TreeViewAction
.ByKeyboard
;
670 SelectedNode
= ne
.CurrentNode
;
674 if (selected_node
!= null) {
675 ne
= new OpenTreeNodeEnumerator (selected_node
);
676 int move
= VisibleCount
;
677 for (int i
= 0; i
< move
&& ne
.MoveNext (); i
++) {
680 selection_action
= TreeViewAction
.ByKeyboard
;
681 SelectedNode
= ne
.CurrentNode
;
685 if (selected_node
!= null) {
686 ne
= new OpenTreeNodeEnumerator (selected_node
);
687 int move
= VisibleCount
;
688 for (int i
= 0; i
< move
&& ne
.MovePrevious (); i
++)
690 selection_action
= TreeViewAction
.ByKeyboard
;
691 SelectedNode
= ne
.CurrentNode
;
695 if (selected_node
!= null)
696 selected_node
.ExpandAll ();
701 if (!e
.Handled
&& checkboxes
&&
702 selected_node
!= null &&
703 (e
.KeyData
& Keys
.KeyCode
) == Keys
.Space
) {
704 selected_node
.check_reason
= TreeViewAction
.ByKeyboard
;
705 selected_node
.Checked
= !selected_node
.Checked
;
710 protected override void OnKeyPress (KeyPressEventArgs e
)
713 if (e
.KeyChar
== ' ')
717 protected override void OnKeyUp (KeyEventArgs e
)
720 if ((e
.KeyData
& Keys
.KeyCode
) == Keys
.Space
)
724 protected virtual void OnItemDrag (ItemDragEventArgs e
)
726 ItemDragEventHandler eh
= (ItemDragEventHandler
)(Events
[ItemDragEvent
]);
731 protected internal virtual void OnAfterCheck (TreeViewEventArgs e
) {
732 TreeViewEventHandler eh
= (TreeViewEventHandler
)(Events
[AfterCheckEvent
]);
737 protected internal virtual void OnAfterCollapse (TreeViewEventArgs e
) {
738 TreeViewEventHandler eh
= (TreeViewEventHandler
)(Events
[AfterCollapseEvent
]);
743 protected internal virtual void OnAfterExpand (TreeViewEventArgs e
) {
744 TreeViewEventHandler eh
= (TreeViewEventHandler
)(Events
[AfterExpandEvent
]);
749 protected virtual void OnAfterLabelEdit (NodeLabelEditEventArgs e
) {
750 NodeLabelEditEventHandler eh
= (NodeLabelEditEventHandler
)(Events
[AfterLabelEditEvent
]);
755 protected virtual void OnAfterSelect (TreeViewEventArgs e
) {
756 TreeViewEventHandler eh
= (TreeViewEventHandler
)(Events
[AfterSelectEvent
]);
761 protected internal virtual void OnBeforeCheck (TreeViewCancelEventArgs e
) {
762 TreeViewCancelEventHandler eh
= (TreeViewCancelEventHandler
)(Events
[BeforeCheckEvent
]);
767 protected internal virtual void OnBeforeCollapse (TreeViewCancelEventArgs e
) {
768 TreeViewCancelEventHandler eh
= (TreeViewCancelEventHandler
)(Events
[BeforeCollapseEvent
]);
773 protected internal virtual void OnBeforeExpand (TreeViewCancelEventArgs e
) {
774 TreeViewCancelEventHandler eh
= (TreeViewCancelEventHandler
)(Events
[BeforeExpandEvent
]);
779 protected virtual void OnBeforeLabelEdit (NodeLabelEditEventArgs e
) {
780 NodeLabelEditEventHandler eh
= (NodeLabelEditEventHandler
)(Events
[BeforeLabelEditEvent
]);
785 protected virtual void OnBeforeSelect (TreeViewCancelEventArgs e
) {
786 TreeViewCancelEventHandler eh
= (TreeViewCancelEventHandler
)(Events
[BeforeSelectEvent
]);
791 protected override void OnHandleCreated (EventArgs e
) {
792 base.OnHandleCreated (e
);
795 protected override void OnHandleDestroyed (EventArgs e
) {
796 base.OnHandleDestroyed (e
);
799 protected override void WndProc(ref Message m
) {
800 switch ((Msg
) m
.Msg
) {
802 case Msg
.WM_LBUTTONDBLCLK
:
803 int val
= m
.LParam
.ToInt32();
804 DoubleClickHandler (null, new
805 MouseEventArgs (MouseButtons
.Left
,
807 (val
>>16) & 0xffff, 0));
810 base.WndProc (ref m
);
813 #endregion // Protected Instance Methods
815 #region Internal & Private Methods and Properties
816 internal IntPtr
CreateNodeHandle ()
818 return (IntPtr
) handle_count
++;
821 internal TreeNode
NodeFromHandle (IntPtr handle
)
823 // This method is called rarely, so instead of maintaining a table
824 // we just walk the tree nodes to find the matching handle
825 return NodeFromHandleRecursive (root_node
, handle
);
828 private TreeNode
NodeFromHandleRecursive (TreeNode node
, IntPtr handle
)
830 if (node
.handle
== handle
)
832 foreach (TreeNode child
in node
.Nodes
) {
833 TreeNode match
= NodeFromHandleRecursive (child
, handle
);
840 internal Rectangle ViewportRectangle
{
842 Rectangle res
= ClientRectangle
;
844 if (vbar
!= null && vbar
.Visible
)
845 res
.Width
-= vbar
.Width
;
846 if (hbar
!= null && hbar
.Visible
)
847 res
.Height
-= hbar
.Height
;
852 private TreeNode
GetNodeAt (int y
)
854 if (nodes
.Count
<= 0)
857 if (top_node
== null)
858 top_node
= nodes
[0];
860 OpenTreeNodeEnumerator o
= new OpenTreeNodeEnumerator (TopNode
);
861 int move
= y
/ ActualItemHeight
;
862 for (int i
= -1; i
< move
; i
++) {
867 return o
.CurrentNode
;
870 private bool IsTextArea (TreeNode node
, int x
)
872 return node
!= null && node
.Bounds
.Left
<= x
&& node
.Bounds
.Right
>= x
;
875 private bool IsSelectableArea (TreeNode node
, int x
)
879 int l
= node
.Bounds
.Left
;
880 if (ImageList
!= null)
881 l
-= ImageList
.ImageSize
.Width
;
882 return l
<= x
&& node
.Bounds
.Right
>= x
;
886 private bool IsPlusMinusArea (TreeNode node
, int x
)
888 if (node
.Nodes
.Count
== 0 || (node
.parent
== root_node
&& !show_root_lines
))
891 int l
= node
.Bounds
.Left
+ 5;
893 if (show_root_lines
|| node
.Parent
!= null)
895 if (ImageList
!= null)
896 l
-= ImageList
.ImageSize
.Width
+ 3;
899 return (x
> l
&& x
< l
+ 8);
902 private bool IsCheckboxArea (TreeNode node
, int x
)
904 int l
= CheckBoxLeft (node
);
905 return (x
> l
&& x
< l
+ 10);
908 private int CheckBoxLeft (TreeNode node
)
910 int l
= node
.Bounds
.Left
+ 5;
912 if (show_root_lines
|| node
.Parent
!= null)
914 if (ImageList
!= null)
915 l
-= ImageList
.ImageSize
.Width
+ 3;
920 internal void RecalculateVisibleOrder (TreeNode start
)
922 if (update_stack
> 0)
930 order
= start
.visible_order
;
932 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (start
);
933 while (walk
.MoveNext ()) {
934 walk
.CurrentNode
.visible_order
= order
;
938 max_visible_order
= order
;
941 internal void SetTop (TreeNode node
)
946 TreeNode first
= root_node
.FirstNode
;
949 return; // I don't think its possible for this to happen
951 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (first
);
953 int vc
= VisibleCount
;
954 while (walk
.CurrentNode
!= node
&& walk
.MoveNext () && offset
< vbar
.Maximum
- vc
)
957 SetVScrollTop (walk
.CurrentNode
);
960 internal void SetBottom (TreeNode node
)
965 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (node
);
967 int bottom
= ViewportRectangle
.Bottom
;
969 while (walk
.MovePrevious ()) {
970 if (walk
.CurrentNode
.Bounds
.Bottom
<= bottom
)
975 int nv
= vbar
.Value
+ offset
;
976 if (vbar
.Value
+ offset
< vbar
.Maximum
) {
980 Console
.Error
.WriteLine ("setting bottom to value greater then maximum ({0}, {1})",
987 internal void UpdateBelow (TreeNode node
)
989 if (update_stack
> 0) {
990 update_needed
= true;
994 if (node
== root_node
) {
995 Invalidate (ViewportRectangle
);
999 // We need to update the current node so the plus/minus block gets update too
1000 int top
= Math
.Max (node
.Bounds
.Top
- 1, 0);
1001 Rectangle invalid
= new Rectangle (0, top
,
1002 Width
, Height
- top
);
1003 Invalidate (invalid
);
1006 internal void UpdateNode (TreeNode node
)
1011 if (update_stack
> 0) {
1012 update_needed
= true;
1016 if (node
== root_node
) {
1021 Rectangle invalid
= new Rectangle (0, node
.Bounds
.Top
- 1, Width
,
1022 node
.Bounds
.Height
+ 1);
1023 Invalidate (invalid
);
1026 internal void UpdateNodePlusMinus (TreeNode node
)
1028 if (update_stack
> 0) {
1029 update_needed
= true;
1033 int l
= node
.Bounds
.Left
+ 5;
1035 if (show_root_lines
|| node
.Parent
!= null)
1037 if (ImageList
!= null)
1038 l
-= ImageList
.ImageSize
.Width
+ 3;
1042 Invalidate (new Rectangle (l
, node
.Bounds
.Top
, 8, node
.Bounds
.Height
));
1045 internal override void OnPaintInternal (PaintEventArgs pe
)
1047 Draw (pe
.ClipRectangle
, pe
.Graphics
);
1050 private void Draw (Rectangle clip
, Graphics dc
)
1052 dc
.FillRectangle (ThemeEngine
.Current
.ResPool
.GetSolidBrush (BackColor
), clip
);
1054 Color dash_color
= ControlPaint
.Dark (BackColor
);
1055 if (dash_color
== BackColor
)
1056 dash_color
= ControlPaint
.Light (BackColor
);
1057 dash
= new Pen (dash_color
, 1);
1058 dash
.DashStyle
= DashStyle
.Dot
;
1060 Rectangle viewport
= ViewportRectangle
;
1061 Rectangle original_clip
= clip
;
1062 if (clip
.Bottom
> viewport
.Bottom
)
1063 clip
.Height
= viewport
.Bottom
- clip
.Top
;
1065 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (TopNode
);
1066 while (walk
.MoveNext ()) {
1067 TreeNode current
= walk
.CurrentNode
;
1069 // Haven't gotten to visible nodes yet
1070 if (current
.GetY () + ActualItemHeight
< clip
.Top
)
1073 // Past the visible nodes
1074 if (current
.GetY () > clip
.Bottom
)
1077 DrawNode (current
, dc
, clip
);
1080 if (hbar
.Visible
&& vbar
.Visible
) {
1081 Rectangle corner
= new Rectangle (hbar
.Right
, vbar
.Bottom
, vbar
.Width
, hbar
.Height
);
1082 if (original_clip
.IntersectsWith (corner
))
1083 dc
.FillRectangle (ThemeEngine
.Current
.ResPool
.GetSolidBrush (ThemeEngine
.Current
.ColorControl
),
1088 private void DrawNodePlusMinus (TreeNode node
, Graphics dc
, int x
, int middle
)
1090 dc
.DrawRectangle (SystemPens
.ControlDark
, x
, middle
- 4, 8, 8);
1092 if (node
.IsExpanded
) {
1093 dc
.DrawLine (SystemPens
.ControlDarkDark
, x
+ 2, middle
, x
+ 6, middle
);
1095 dc
.DrawLine (SystemPens
.ControlDarkDark
, x
+ 2, middle
, x
+ 6, middle
);
1096 dc
.DrawLine (SystemPens
.ControlDarkDark
, x
+ 4, middle
- 2, x
+ 4, middle
+ 2);
1100 private void DrawNodeCheckBox (TreeNode node
, Graphics dc
, int x
, int middle
)
1102 Pen pen
= ThemeEngine
.Current
.ResPool
.GetSizedPen(Color
.Black
, 2);
1103 dc
.DrawRectangle (pen
, x
+ 3, middle
- 4, 11, 11);
1106 Pen check_pen
= ThemeEngine
.Current
.ResPool
.GetPen(Color
.Black
);
1111 Rectangle rect
= new Rectangle (x
+ 5, middle
- 2, check_size
, check_size
);
1113 for (int i
= 0; i
< lineWidth
; i
++) {
1114 dc
.DrawLine (check_pen
, rect
.Left
+ 1, rect
.Top
+ lineWidth
+ i
, rect
.Left
+ 3, rect
.Top
+ 5 + i
);
1115 dc
.DrawLine (check_pen
, rect
.Left
+ 3, rect
.Top
+ 5 + i
, rect
.Left
+ 7, rect
.Top
+ 1 + i
);
1120 private void DrawNodeLines (TreeNode node
, Graphics dc
, Rectangle clip
, Pen dash
, int x
, int y
, int middle
)
1125 if (node
.nodes
.Count
> 0 && show_plus_minus
)
1130 dc
.DrawLine (dash
, x
- indent
+ ladjust
, middle
, x
+ radjust
, middle
);
1132 if (node
.PrevNode
!= null || node
.Parent
!= null) {
1134 dc
.DrawLine (dash
, x
- indent
+ ladjust
, node
.Bounds
.Top
,
1135 x
- indent
+ ladjust
, middle
- (show_plus_minus
&& node
.Nodes
.Count
> 0 ? 4 : 0));
1138 if (node
.NextNode
!= null) {
1140 dc
.DrawLine (dash
, x
- indent
+ ladjust
, middle
+ (show_plus_minus
&& node
.Nodes
.Count
> 0 ? 4 : 0),
1141 x
- indent
+ ladjust
, node
.Bounds
.Bottom
);
1146 if (show_plus_minus
)
1148 TreeNode parent
= node
.Parent
;
1149 while (parent
!= null) {
1150 if (parent
.NextNode
!= null) {
1151 int px
= parent
.GetLinesX () - indent
+ ladjust
;
1152 dc
.DrawLine (dash
, px
, node
.Bounds
.Top
, px
, node
.Bounds
.Bottom
);
1154 parent
= parent
.Parent
;
1158 private void DrawNodeImage (TreeNode node
, Graphics dc
, Rectangle clip
, int x
, int y
)
1160 // Rectangle r = new Rectangle (x, y + 2, ImageList.ImageSize.Width, ImageList.ImageSize.Height);
1162 if (!RectsIntersect (clip
, x
, y
+ 2, ImageList
.ImageSize
.Width
, ImageList
.ImageSize
.Height
))
1165 if (ImageList
== null)
1169 if (node
.ImageIndex
> -1 && node
.ImageIndex
< ImageList
.Images
.Count
) {
1170 use_index
= node
.ImageIndex
;
1171 } else if (ImageIndex
> -1 && ImageIndex
< ImageList
.Images
.Count
) {
1172 use_index
= ImageIndex
;
1175 if (use_index
== -1 && ImageList
.Images
.Count
> 0) {
1179 if (use_index
!= -1) {
1180 ImageList
.Draw (dc
, x
, y
+ 2, ImageList
.ImageSize
.Width
,
1181 ImageList
.ImageSize
.Height
, use_index
);
1185 private void LabelEditFinished (object sender
, EventArgs e
)
1187 EndEdit (edit_node
);
1190 internal void BeginEdit (TreeNode node
)
1192 if (edit_node
!= null)
1193 EndEdit (edit_node
);
1195 if (edit_text_box
== null) {
1196 edit_text_box
= new LabelEditTextBox ();
1197 edit_text_box
.BorderStyle
= BorderStyle
.FixedSingle
;
1198 edit_text_box
.EditingFinished
+= new EventHandler (LabelEditFinished
);
1199 Controls
.Add (edit_text_box
);
1202 edit_text_box
.Bounds
= node
.Bounds
;
1203 edit_text_box
.Width
+= 4;
1205 edit_text_box
.Text
= node
.Text
;
1206 edit_text_box
.Visible
= true;
1207 edit_text_box
.Focus ();
1208 edit_text_box
.SelectAll ();
1210 edit_args
= new NodeLabelEditEventArgs (edit_node
);
1211 OnBeforeLabelEdit (edit_args
);
1213 if (edit_args
.CancelEdit
)
1219 internal void EndEdit (TreeNode node
)
1221 if (edit_text_box
!= null && edit_text_box
.Visible
) {
1222 edit_text_box
.Visible
= false;
1225 if (edit_node
!= null && edit_node
== node
) {
1226 OnAfterLabelEdit (edit_args
);
1228 if (!edit_args
.CancelEdit
) {
1229 if (edit_args
.Label
!= null)
1230 edit_node
.Text
= edit_args
.Label
;
1232 edit_node
.Text
= edit_text_box
.Text
;
1242 internal int GetNodeWidth (TreeNode node
)
1244 Font font
= node
.NodeFont
;
1245 if (node
.NodeFont
== null)
1247 return (int) DeviceContext
.MeasureString (node
.Text
, font
, 0, string_format
).Width
+ 3;
1250 private void DrawSelectionAndFocus(TreeNode node
, Graphics dc
, Rectangle r
)
1252 if (Focused
&& focused_node
== node
) {
1253 ControlPaint
.DrawFocusRectangle (dc
, r
, ForeColor
, BackColor
);
1256 if (Focused
&& node
== highlighted_node
) {
1257 dc
.FillRectangle (ThemeEngine
.Current
.ResPool
.GetSolidBrush (ThemeEngine
.Current
.ColorHighlight
), r
);
1258 } else if (!hide_selection
&& node
== highlighted_node
) {
1259 dc
.FillRectangle (SystemBrushes
.Control
, r
);
1261 dc
.FillRectangle (ThemeEngine
.Current
.ResPool
.GetSolidBrush (node
.BackColor
), r
);
1265 private void DrawStaticNode (TreeNode node
, Graphics dc
)
1267 if (!full_row_select
)
1268 DrawSelectionAndFocus(node
, dc
, node
.Bounds
);
1270 Font font
= node
.NodeFont
;
1271 if (node
.NodeFont
== null)
1273 Color text_color
= (Focused
&& node
== highlighted_node
?
1274 ThemeEngine
.Current
.ColorHighlightText
: node
.ForeColor
);
1275 dc
.DrawString (node
.Text
, font
,
1276 ThemeEngine
.Current
.ResPool
.GetSolidBrush (text_color
),
1277 node
.Bounds
, string_format
);
1280 private void DrawNode (TreeNode node
, Graphics dc
, Rectangle clip
)
1282 int child_count
= node
.nodes
.Count
;
1283 int y
= node
.GetY ();
1284 int middle
= y
+ (ActualItemHeight
/ 2);
1286 if (full_row_select
) {
1287 Rectangle r
= new Rectangle (1, y
+ 2, ViewportRectangle
.Width
- 2, ActualItemHeight
);
1288 DrawSelectionAndFocus (node
, dc
, r
);
1291 if ((show_root_lines
|| node
.Parent
!= null) && show_plus_minus
&& child_count
> 0)
1292 DrawNodePlusMinus (node
, dc
, node
.GetLinesX () - Indent
+ 5, middle
);
1295 DrawNodeCheckBox (node
, dc
, CheckBoxLeft (node
) - 3, middle
);
1298 DrawNodeLines (node
, dc
, clip
, dash
, node
.GetLinesX (), y
, middle
);
1300 if (ImageList
!= null)
1301 DrawNodeImage (node
, dc
, clip
, node
.GetImageX (), y
);
1303 if (!node
.IsEditing
)
1304 DrawStaticNode (node
, dc
);
1307 internal void UpdateScrollBars ()
1309 if (IsDisposed
|| update_stack
> 0 || !IsHandleCreated
|| !Visible
)
1318 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (root_node
);
1320 while (walk
.MoveNext ()) {
1321 int r
= walk
.CurrentNode
.Bounds
.Right
;
1322 int b
= walk
.CurrentNode
.Bounds
.Bottom
;
1330 // Remove scroll adjustments
1331 if (nodes
.Count
> 0)
1332 height
-= nodes
[0].Bounds
.Top
;
1333 width
+= hbar_offset
;
1335 if (height
> ClientRectangle
.Height
) {
1338 if (width
> ClientRectangle
.Width
- SystemInformation
.VerticalScrollBarWidth
)
1340 } else if (width
> ClientRectangle
.Width
) {
1344 if (!vert
&& horz
&& height
> ClientRectangle
.Height
- SystemInformation
.HorizontalScrollBarHeight
)
1349 int visible_height
= horz
? ClientRectangle
.Height
- hbar
.Height
: ClientRectangle
.Height
;
1350 vbar
.SetValues (Math
.Max (0, max_visible_order
- 2), visible_height
/ ActualItemHeight
);
1352 vbar.Maximum = max_visible_order;
1353 vbar.LargeChange = ClientRectangle.Height / ItemHeight;
1356 if (!vbar_bounds_set
) {
1357 vbar
.Bounds
= new Rectangle (ClientRectangle
.Width
- vbar
.Width
, 0, vbar
.Width
,
1358 ClientRectangle
.Height
-
1359 (horz
? SystemInformation
.VerticalScrollBarWidth
: 0));
1360 vbar_bounds_set
= true;
1362 // We need to recalc the hbar if the vbar is now visible
1363 hbar_bounds_set
= false;
1366 vbar
.Visible
= true;
1369 top_node
= root_node
.FirstNode
;
1370 RecalculateVisibleOrder (root_node
);
1371 vbar
.Visible
= false;
1372 vbar_bounds_set
= false;
1376 hbar
.SetValues (width
+ 1, ClientRectangle
.Width
);
1378 hbar.LargeChange = ClientRectangle.Width;
1379 hbar.Maximum = width + 1;
1382 if (!hbar_bounds_set
) {
1383 hbar
.Bounds
= new Rectangle (0, ClientRectangle
.Height
- hbar
.Height
,
1384 ClientRectangle
.Width
- (vert
? SystemInformation
.VerticalScrollBarWidth
: 0),
1386 hbar_bounds_set
= true;
1388 hbar
.Visible
= true;
1391 hbar
.Visible
= false;
1392 hbar_bounds_set
= false;
1396 private void SizeChangedHandler (object sender
, EventArgs e
)
1398 if (IsHandleCreated
) {
1399 if (max_visible_order
== -1)
1400 RecalculateVisibleOrder (root_node
);
1401 UpdateScrollBars ();
1405 vbar
.Bounds
= new Rectangle (ClientRectangle
.Width
- vbar
.Width
, 0, vbar
.Width
,
1406 ClientRectangle
.Height
- (hbar
.Visible
? SystemInformation
.HorizontalScrollBarHeight
: 0));
1410 hbar
.Bounds
= new Rectangle (0, ClientRectangle
.Height
- hbar
.Height
,
1411 ClientRectangle
.Width
- (vbar
.Visible
? SystemInformation
.VerticalScrollBarWidth
: 0), hbar
.Height
);
1415 private void VScrollBarValueChanged (object sender
, EventArgs e
)
1417 EndEdit (edit_node
);
1419 SetVScrollPos (vbar
.Value
, null);
1422 private void SetVScrollPos (int pos
, TreeNode new_top
)
1427 if (skipped_nodes
== pos
)
1430 int old_skip
= skipped_nodes
;
1431 skipped_nodes
= pos
;
1432 int diff
= old_skip
- skipped_nodes
;
1434 // Determine the new top node if we have to
1435 if (new_top
== null) {
1436 if (top_node
== null)
1437 top_node
= nodes
[0];
1439 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (TopNode
);
1441 for (int i
= diff
; i
<= 0; i
++)
1443 new_top
= walk
.CurrentNode
;
1445 for (int i
= 0; i
<= diff
; i
++)
1446 walk
.MovePrevious ();
1447 new_top
= walk
.CurrentNode
;
1452 int y_move
= diff
* ActualItemHeight
;
1453 XplatUI
.ScrollWindow (Handle
, ViewportRectangle
, 0, y_move
, false);
1456 private void SetVScrollTop (TreeNode new_top
)
1458 OpenTreeNodeEnumerator walk
= new OpenTreeNodeEnumerator (root_node
);
1461 while (walk
.MoveNext () && walk
.CurrentNode
!= new_top
)
1465 vbar
.Value
= skipped_nodes
;
1468 private void HScrollBarValueChanged(object sender
, EventArgs e
)
1470 EndEdit (edit_node
);
1472 int old_offset
= hbar_offset
;
1473 hbar_offset
= hbar
.Value
;
1475 if (hbar_offset
< 0) {
1479 XplatUI
.ScrollWindow (Handle
, ViewportRectangle
, old_offset
- hbar_offset
, 0, false);
1482 internal void ExpandBelow (TreeNode node
, int count_to_next
)
1484 if (update_stack
> 0) {
1485 update_needed
= true;
1489 Rectangle below
= new Rectangle (0, node
.Bounds
.Bottom
+ 2, ViewportRectangle
.Width
,
1490 ViewportRectangle
.Height
- node
.Bounds
.Bottom
);
1492 int amount
= count_to_next
* ActualItemHeight
;
1495 XplatUI
.ScrollWindow (Handle
, below
, 0, amount
, false);
1497 if (show_plus_minus
) {
1498 //int linesx = node.GetLinesX ();
1499 Invalidate (new Rectangle (0, node
.GetY (), Width
, ActualItemHeight
));
1503 internal void CollapseBelow (TreeNode node
, int count_to_next
)
1505 if (update_stack
> 0) {
1506 update_needed
= true;
1510 Rectangle below
= new Rectangle (0, node
.Bounds
.Bottom
+ 2, ViewportRectangle
.Width
,
1511 ViewportRectangle
.Height
- node
.Bounds
.Bottom
+ 2);
1513 int amount
= count_to_next
* ActualItemHeight
;
1516 XplatUI
.ScrollWindow (Handle
, below
, 0, -amount
, false);
1518 if (show_plus_minus
) {
1519 //int linesx = node.GetLinesX ();
1520 Invalidate (new Rectangle (0, node
.GetY (), Width
, ActualItemHeight
));
1524 private void MouseWheelHandler(object sender
, MouseEventArgs e
) {
1526 if (vbar
== null || !vbar
.Visible
) {
1531 vbar
.Value
= Math
.Min(vbar
.Value
+ SystemInformation
.MouseWheelScrollLines
, vbar
.Maximum
- VisibleCount
+ 1);
1533 vbar
.Value
= Math
.Max(0, vbar
.Value
- SystemInformation
.MouseWheelScrollLines
);
1537 private void FontChangedHandler (object sender
, EventArgs e
)
1539 InvalidateNodeWidthRecursive (root_node
);
1542 private void InvalidateNodeWidthRecursive (TreeNode node
)
1544 node
.InvalidateWidth ();
1545 foreach (TreeNode child
in node
.Nodes
) {
1546 InvalidateNodeWidthRecursive (child
);
1550 private void GotFocusHandler (object sender
, EventArgs e
)
1552 if (selected_node
== null)
1553 SelectedNode
= top_node
;
1555 UpdateNode (selected_node
);
1558 private void LostFocusHandler (object sender
, EventArgs e
)
1560 UpdateNode (SelectedNode
);
1563 private void MouseDownHandler (object sender
, MouseEventArgs e
)
1565 if (e
.Button
== MouseButtons
.Right
)
1568 TreeNode node
= GetNodeAt (e
.Y
);
1572 if (show_plus_minus
&& IsPlusMinusArea (node
, e
.X
)) {
1575 } else if (checkboxes
&& IsCheckboxArea (node
, e
.X
)) {
1576 node
.check_reason
= TreeViewAction
.ByMouse
;
1577 node
.Checked
= !node
.Checked
;
1580 } else if (IsSelectableArea (node
, e
.X
) || full_row_select
) {
1581 TreeNode old_highlighted
= highlighted_node
;
1582 highlighted_node
= node
;
1583 if (label_edit
&& e
.Clicks
== 1 && highlighted_node
== old_highlighted
) {
1585 } else if (highlighted_node
!= focused_node
) {
1586 Size ds
= SystemInformation
.DragSize
;
1587 mouse_rect
.X
= e
.X
- ds
.Width
;
1588 mouse_rect
.Y
= e
.Y
- ds
.Height
;
1589 mouse_rect
.Width
= ds
.Width
* 2;
1590 mouse_rect
.Height
= ds
.Height
* 2;
1592 select_mmove
= true;
1595 Invalidate (highlighted_node
.Bounds
);
1596 if (old_highlighted
!= null)
1597 Invalidate (Bloat (old_highlighted
.Bounds
));
1601 private void MouseUpHandler (object sender
, MouseEventArgs e
) {
1609 if (e
.Button
== MouseButtons
.Right
) {
1610 Invalidate (highlighted_node
.Bounds
);
1611 highlighted_node
= selected_node
;
1612 Invalidate (selected_node
.Bounds
);
1614 select_mmove
= false;
1616 TreeViewCancelEventArgs ce
= new TreeViewCancelEventArgs (highlighted_node
, false, TreeViewAction
.ByMouse
);
1617 OnBeforeSelect (ce
);
1621 if (focused_node
!= null) {
1622 invalid
= Rectangle
.Union (Bloat (focused_node
.Bounds
),
1623 Bloat (highlighted_node
.Bounds
));
1625 invalid
= Bloat (highlighted_node
.Bounds
);
1627 selected_node
= highlighted_node
;
1628 focused_node
= highlighted_node
;
1629 OnAfterSelect (new TreeViewEventArgs (selected_node
, TreeViewAction
.ByMouse
));
1631 Invalidate (invalid
);
1633 highlighted_node
= focused_node
;
1634 selected_node
= focused_node
;
1638 private void MouseMoveHandler (object sender
, MouseEventArgs e
) {
1640 if (e
.Button
== MouseButtons
.Left
|| e
.Button
== MouseButtons
.Right
) {
1641 if (drag_begin_x
== -1 && drag_begin_y
== -1) {
1645 double rise
= Math
.Pow (drag_begin_x
- e
.X
, 2);
1646 double run
= Math
.Pow (drag_begin_y
- e
.Y
, 2);
1647 double move
= Math
.Sqrt (rise
+ run
);
1649 TreeNode drag
= GetNodeAtUseX (e
.X
, e
.Y
);
1652 OnItemDrag (new ItemDragEventArgs (e
.Button
, drag
));
1661 // If there is enough movement before the mouse comes up,
1662 // selection is reverted back to the originally selected node
1663 if (!select_mmove
|| mouse_rect
.Contains (e
.X
, e
.Y
))
1666 Invalidate (highlighted_node
.Bounds
);
1667 Invalidate (selected_node
.Bounds
);
1668 Invalidate (focused_node
.Bounds
);
1670 highlighted_node
= selected_node
;
1671 focused_node
= selected_node
;
1673 select_mmove
= false;
1676 private void DoubleClickHandler (object sender
, MouseEventArgs e
) {
1677 TreeNode node
= GetNodeAtUseX (e
.X
,e
.Y
);
1684 private bool RectsIntersect (Rectangle r
, int left
, int top
, int width
, int height
)
1686 return !((r
.Left
> left
+ width
) || (r
.Right
< left
) ||
1687 (r
.Top
> top
+ height
) || (r
.Bottom
< top
));
1690 #endregion // Internal & Private Methods and Properties
1693 static object ItemDragEvent
= new object ();
1694 static object AfterCheckEvent
= new object ();
1695 static object AfterCollapseEvent
= new object ();
1696 static object AfterExpandEvent
= new object ();
1697 static object AfterLabelEditEvent
= new object ();
1698 static object AfterSelectEvent
= new object ();
1699 static object BeforeCheckEvent
= new object ();
1700 static object BeforeCollapseEvent
= new object ();
1701 static object BeforeExpandEvent
= new object ();
1702 static object BeforeLabelEditEvent
= new object ();
1703 static object BeforeSelectEvent
= new object ();
1705 public event ItemDragEventHandler ItemDrag
{
1706 add { Events.AddHandler (ItemDragEvent, value); }
1707 remove { Events.RemoveHandler (ItemDragEvent, value); }
1710 public event TreeViewEventHandler AfterCheck
{
1711 add { Events.AddHandler (AfterCheckEvent, value); }
1712 remove { Events.RemoveHandler (AfterCheckEvent, value); }
1715 public event TreeViewEventHandler AfterCollapse
{
1716 add { Events.AddHandler (AfterCollapseEvent, value); }
1717 remove { Events.RemoveHandler (AfterCollapseEvent, value); }
1720 public event TreeViewEventHandler AfterExpand
{
1721 add { Events.AddHandler (AfterExpandEvent, value); }
1722 remove { Events.RemoveHandler (AfterExpandEvent, value); }
1725 public event NodeLabelEditEventHandler AfterLabelEdit
{
1726 add { Events.AddHandler (AfterLabelEditEvent, value); }
1727 remove { Events.RemoveHandler (AfterLabelEditEvent, value); }
1730 public event TreeViewEventHandler AfterSelect
{
1731 add { Events.AddHandler (AfterSelectEvent, value); }
1732 remove { Events.RemoveHandler (AfterSelectEvent, value); }
1735 public event TreeViewCancelEventHandler BeforeCheck
{
1736 add { Events.AddHandler (BeforeCheckEvent, value); }
1737 remove { Events.RemoveHandler (BeforeCheckEvent, value); }
1740 public event TreeViewCancelEventHandler BeforeCollapse
{
1741 add { Events.AddHandler (BeforeCollapseEvent, value); }
1742 remove { Events.RemoveHandler (BeforeCollapseEvent, value); }
1745 public event TreeViewCancelEventHandler BeforeExpand
{
1746 add { Events.AddHandler (BeforeExpandEvent, value); }
1747 remove { Events.RemoveHandler (BeforeExpandEvent, value); }
1750 public event NodeLabelEditEventHandler BeforeLabelEdit
{
1751 add { Events.AddHandler (BeforeLabelEditEvent, value); }
1752 remove { Events.RemoveHandler (BeforeLabelEditEvent, value); }
1755 public event TreeViewCancelEventHandler BeforeSelect
{
1756 add { Events.AddHandler (BeforeSelectEvent, value); }
1757 remove { Events.RemoveHandler (BeforeSelectEvent, value); }
1761 [EditorBrowsable (EditorBrowsableState
.Never
)]
1762 public new event EventHandler BackgroundImageChanged
{
1763 add { base.BackgroundImageChanged += value; }
1764 remove { base.BackgroundImageChanged -= value; }
1767 [EditorBrowsable (EditorBrowsableState
.Never
)]
1769 public new event PaintEventHandler Paint
{
1770 add { base.Paint += value; }
1771 remove { base.Paint -= value; }
1774 [EditorBrowsable (EditorBrowsableState
.Never
)]
1776 public new event EventHandler TextChanged
{
1777 add { base.TextChanged += value; }
1778 remove { base.TextChanged -= value; }
1780 #endregion // Events