2 // System.Windows.Forms.TreeView
5 // stubbed out by Jackson Harper (jackson@latitudegeo.com)
6 // Dennis Hayes (dennish@raytek.com)
7 // Aleksey Ryabchuk (ryabchuk@yahoo.com)
9 // (C) 2002 Ximian, Inc
12 using System.ComponentModel;
13 using System.Runtime.InteropServices;
16 namespace System.Windows.Forms {
23 public class TreeView : Control {
25 private int imageIndex;
26 private int selectedImageIndex;
27 private TreeNodeCollection nodes;
29 private BorderStyle borderStyle;
30 private bool checkBoxes;
31 private bool fullRowSelect;
32 private bool hideSelection;
33 private bool hotTracking;
34 private bool showLines;
35 private bool showPlusMinus;
36 private bool showRootLines;
37 private ImageList imageList;
39 private TreeNode selectedNode;
40 private TreeNode dummyNode;
41 private int itemHeight;
42 private bool labelEdit;
43 private bool scrollable;
44 private string pathSeparator;
45 private bool updateLocked;
47 const int DefaultIndent = 19;
48 const int DefaultItemHeight = 16;
50 internal TVINSERTSTRUCT insStruct;
52 // --- Public Constructors
58 selectedImageIndex = 0;
59 SubClassWndProc_ = true;
60 borderStyle = BorderStyle.Fixed3D;
62 fullRowSelect = false;
71 indent = DefaultIndent;
79 SubClassWndProc_ = true;
81 dummyNode = new TreeNode( RootHandle, this );
83 insStruct = new TVINSERTSTRUCT ( );
86 // --- Public Properties
89 public override Color BackColor {
90 get { return base.BackColor; }
92 base.BackColor = value;
94 if ( IsHandleCreated )
99 [EditorBrowsable (EditorBrowsableState.Never)]
100 public override Image BackgroundImage {
101 get { return base.BackgroundImage; }
102 set { base.BackgroundImage = value; }
105 public BorderStyle BorderStyle {
106 get { return borderStyle; }
108 if ( !Enum.IsDefined ( typeof(BorderStyle), value ) )
109 throw new InvalidEnumArgumentException( "BorderStyle",
111 typeof(BorderStyle));
113 if ( borderStyle != value ) {
114 int oldStyle = Win32.getBorderStyle ( borderStyle );
115 int oldExStyle = Win32.getBorderExStyle ( borderStyle );
118 if ( IsHandleCreated ) {
119 Win32.UpdateWindowStyle ( Handle, oldStyle, Win32.getBorderStyle ( borderStyle ) );
120 Win32.UpdateWindowExStyle ( Handle, oldExStyle, Win32.getBorderExStyle ( borderStyle ) );
126 public bool CheckBoxes {
127 get { return checkBoxes; }
134 public override Color ForeColor {
135 get { return base.ForeColor; }
137 base.ForeColor = value;
139 if ( IsHandleCreated )
144 public bool FullRowSelect {
145 get { return fullRowSelect; }
147 if ( fullRowSelect != value ) {
148 int oldStyle = fullRowSelect ? (int)TreeViewStyles.TVS_FULLROWSELECT : 0;
149 fullRowSelect = value;
151 if ( IsHandleCreated ) {
152 int newStyle = fullRowSelect ? (int)TreeViewStyles.TVS_FULLROWSELECT : 0;
153 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
159 public bool HideSelection {
160 get { return hideSelection; }
162 if ( hideSelection != value ) {
163 int oldStyle = hideSelection ? 0 : (int)TreeViewStyles.TVS_SHOWSELALWAYS;
164 hideSelection = value;
166 if ( IsHandleCreated ) {
167 int newStyle = hideSelection ? 0 : (int)TreeViewStyles.TVS_SHOWSELALWAYS;
168 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
174 public bool HotTracking {
175 get { return hotTracking; }
177 if ( hotTracking != value ) {
178 int oldStyle = hotTracking ? (int)TreeViewStyles.TVS_TRACKSELECT : 0;
181 if ( IsHandleCreated ) {
182 int newStyle = hotTracking ? (int)TreeViewStyles.TVS_TRACKSELECT : 0;
183 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
189 public int ImageIndex {
190 get { return imageIndex; }
192 if ( imageIndex != value ) {
199 public ImageList ImageList {
200 get { return imageList; }
202 if ( imageList != value ) {
204 if ( IsHandleCreated )
211 get { return indent; }
214 throw new ArgumentException (
215 string.Format ("'{0}' is not a valid value for 'Indent'. 'Indent' must be greater than or equal to 0.", value), "value");
218 throw new ArgumentException (
219 string.Format ("'{0}' is not a valid value for 'Indent'. 'Indent' must be less than or equal to 32000.", value), "value" );
221 if ( indent != value ) {
224 if ( IsHandleCreated )
230 public int ItemHeight {
232 if ( !IsHandleCreated )
233 if ( itemHeight == -1 ) return DefaultItemHeight;
235 itemHeight = Win32.SendMessage ( Handle, (int)TreeViewMessages.TVM_GETITEMHEIGHT, 0, 0 );
240 throw new ArgumentException (
241 string.Format ("'{0}' is not a valid value for 'ItemHeight'. 'ItemHeight' must be greater than or equal to 1.", value), "value");
243 if ( value > Int16.MaxValue )
244 throw new ArgumentException (
245 string.Format ("'{0}' is not a valid value for 'ItemHeight'. 'ItemHeight' must be less than or equal to {1}.", value, Int16.MaxValue), "value" );
247 if ( itemHeight != value ) {
249 if ( IsHandleCreated )
250 Win32.SendMessage ( Handle, (int)TreeViewMessages.TVM_SETITEMHEIGHT, itemHeight, 0 );
255 public bool LabelEdit {
256 get { return labelEdit; }
258 if ( labelEdit != value ) {
259 int oldStyle = labelEdit ? (int)TreeViewStyles.TVS_EDITLABELS : 0;
262 if ( IsHandleCreated ) {
263 int newStyle = labelEdit ? (int)TreeViewStyles.TVS_EDITLABELS : 0;
264 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
270 public TreeNodeCollection Nodes {
273 nodes = new TreeNodeCollection ( dummyNode );
278 public string PathSeparator {
279 get { return pathSeparator; }
281 pathSeparator = value;
285 public bool Scrollable {
286 get { return scrollable; }
288 if ( scrollable != value ) {
295 public int SelectedImageIndex {
296 get { return selectedImageIndex; }
298 if ( selectedImageIndex != value ) {
299 selectedImageIndex = value;
305 public TreeNode SelectedNode {
307 if ( IsHandleCreated ) {
308 int hitem = Win32.SendMessage ( Handle, (int) TreeViewMessages.TVM_GETNEXTITEM, (int)TreeViewItemSelFlags.TVGN_CARET, 0 );
309 selectedNode = TreeNode.FromHandle ( this, (IntPtr) hitem );
314 selectedNode = value;
315 if ( IsHandleCreated )
316 selectItem ( selectedNode != null ? selectedNode.Handle : IntPtr.Zero );
320 public bool ShowLines {
321 get { return showLines; }
323 if ( showLines != value ) {
324 int oldStyle = showLines ? (int)TreeViewStyles.TVS_HASLINES : 0;
327 if ( IsHandleCreated ) {
328 int newStyle = showLines ? (int)TreeViewStyles.TVS_HASLINES : 0;
329 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
335 public bool ShowPlusMinus {
336 get { return showPlusMinus; }
338 if ( showPlusMinus != value ) {
339 int oldStyle = showPlusMinus ? (int)TreeViewStyles.TVS_HASBUTTONS : 0;
340 showPlusMinus = value;
342 if ( IsHandleCreated ) {
343 int newStyle = showPlusMinus ? (int)TreeViewStyles.TVS_HASBUTTONS : 0;
344 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
350 public bool ShowRootLines {
351 get { return showRootLines; }
353 if ( showRootLines != value ) {
354 int oldStyle = showRootLines ? (int)TreeViewStyles.TVS_LINESATROOT : 0;
355 showRootLines = value;
357 if ( IsHandleCreated ) {
358 int newStyle = showRootLines ? (int)TreeViewStyles.TVS_LINESATROOT : 0;
359 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
366 get { return sorted; }
369 if ( IsHandleCreated && sorted )
374 [EditorBrowsable (EditorBrowsableState.Never)]
375 public override string Text {
376 get { return base.Text; }
377 set { base.Text = value; }
380 public TreeNode TopNode {
382 if ( IsHandleCreated ) {
383 int hitem = Win32.SendMessage ( Handle, (int) TreeViewMessages.TVM_GETNEXTITEM, (int)TreeViewItemSelFlags.TVGN_FIRSTVISIBLE, 0 );
384 return TreeNode.FromHandle ( this, (IntPtr) hitem );
390 public int VisibleCount {
392 if ( IsHandleCreated )
393 return Win32.SendMessage ( Handle, (int) TreeViewMessages.TVM_GETVISIBLECOUNT, 0, 0 );
398 // --- Public Methods
401 public void BeginUpdate()
406 public void CollapseAll()
408 foreach ( TreeNode node in Nodes )
409 node.collapseAllImpl ( this );
412 public void EndUpdate()
414 updateLocked = false;
417 public void ExpandAll()
419 foreach ( TreeNode node in Nodes )
420 node.expandAllImpl ( this );
423 public TreeNode GetNodeAt(Point pt)
425 return GetNodeAt ( pt.X, pt.Y );
428 public TreeNode GetNodeAt(int x, int y)
430 throw new NotImplementedException ();
433 public int GetNodeCount(bool includeSubTrees)
435 throw new NotImplementedException ();
438 public override string ToString()
441 return base.ToString();
446 public event TreeViewEventHandler AfterCheck;
447 public event TreeViewEventHandler AfterCollapse;
448 public event TreeViewEventHandler AfterExpand;
449 public event NodeLabelEditEventHandler AfterLabelEdit;
450 public event TreeViewEventHandler AfterSelect;
451 public event TreeViewCancelEventHandler BeforeCheck;
452 public event TreeViewCancelEventHandler BeforeCollapse;
453 public event TreeViewCancelEventHandler BeforeExpand;
454 public event NodeLabelEditEventHandler BeforeLabelEdit;
455 public event TreeViewCancelEventHandler BeforeSelect;
456 public event ItemDragEventHandler ItemDrag;
457 //public new event PaintEventHandler Paint;
459 // --- Protected Properties
462 protected override CreateParams CreateParams {
464 CreateParams createParams = base.CreateParams;
466 createParams.ClassName = Win32.TREEVIEW_CLASS;
467 createParams.Style |= (int) WindowStyles.WS_CHILD ;
469 createParams.Style |= Win32.getBorderStyle ( BorderStyle );
470 createParams.ExStyle |= Win32.getBorderExStyle ( BorderStyle );
473 createParams.Style |= (int) TreeViewStyles.TVS_CHECKBOXES;
476 createParams.Style |= (int) TreeViewStyles.TVS_FULLROWSELECT;
479 createParams.Style |= (int) TreeViewStyles.TVS_HASLINES;
481 if ( !HideSelection )
482 createParams.Style |= (int) TreeViewStyles.TVS_SHOWSELALWAYS;
485 createParams.Style |= (int) TreeViewStyles.TVS_TRACKSELECT;
488 createParams.Style |= (int) TreeViewStyles.TVS_HASBUTTONS;
491 createParams.Style |= (int) TreeViewStyles.TVS_LINESATROOT;
494 createParams.Style |= (int) TreeViewStyles.TVS_EDITLABELS;
497 createParams.Style |= (int) TreeViewStyles.TVS_NOSCROLL;
503 protected override Size DefaultSize {
504 get { return new Size(121,97); }
507 // --- Protected Methods
510 protected override void CreateHandle()
512 initCommonControlsLibrary ( );
517 protected override void Dispose(bool disposing) {
519 base.Dispose(disposing);
523 protected override bool IsInputKey(Keys keyData)
526 return base.IsInputKey(keyData);
529 protected virtual void OnAfterCheck(TreeViewEventArgs e)
534 protected virtual void OnAfterCollapse(TreeViewEventArgs e)
539 protected virtual void OnAfterExpand( TreeViewEventArgs e )
541 if ( AfterExpand != null )
542 AfterExpand ( this, e );
545 protected virtual void OnAfterLabelEdit(NodeLabelEditEventArgs e)
550 protected virtual void OnAfterSelect(TreeViewEventArgs e)
555 protected virtual void OnBeforeCheck(TreeViewCancelEventArgs e)
560 protected virtual void OnBeforeCollapse(TreeViewCancelEventArgs e)
565 protected virtual void OnBeforeExpand( TreeViewCancelEventArgs e )
567 if ( BeforeExpand != null )
568 BeforeExpand ( this, e );
571 protected virtual void OnBeforeLabelEdit(NodeLabelEditEventArgs e)
576 protected virtual void OnBeforeSelect(TreeViewCancelEventArgs e)
581 protected override void OnHandleCreated(EventArgs e)
584 base.OnHandleCreated(e);
589 if ( itemHeight != -1 )
590 Win32.SendMessage ( Handle, (int)TreeViewMessages.TVM_SETITEMHEIGHT, itemHeight, 0 );
591 if ( BackColor != Control.DefaultBackColor )
593 if ( ForeColor != Control.DefaultForeColor )
595 if ( Indent != DefaultIndent )
597 if ( selectedNode != null )
598 selectItem ( selectedNode.Handle );
601 protected override void OnHandleDestroyed(EventArgs e)
604 base.OnHandleDestroyed(e);
607 protected virtual void OnItemDrag(ItemDragEventArgs e)
612 protected override void OnKeyDown(KeyEventArgs e)
618 protected override void OnKeyPress(KeyPressEventArgs e)
624 protected override void OnKeyUp(KeyEventArgs e)
630 protected override void WndProc(ref Message m)
634 NMTREEVIEW nmhdr = (NMTREEVIEW)Marshal.PtrToStructure ( m.LParam, typeof ( NMTREEVIEW ) );
636 switch ( nmhdr.hdr.code ) {
637 case (int) TreeViewNotifications.TVN_ITEMEXPANDINGA: {
638 TreeNode node = TreeNode.FromHandle ( this, nmhdr.itemNew.hItem );
639 if ( node != null ) {
640 TreeViewCancelEventArgs args = new TreeViewCancelEventArgs ( node, false, Win32.uint2TreeViewAction ( nmhdr.action ) );
641 OnBeforeExpand ( args );
643 m.Result = (IntPtr) 1;
647 case (int) TreeViewNotifications.TVN_ITEMEXPANDEDA: {
648 TreeNode node = TreeNode.FromHandle ( this, nmhdr.itemNew.hItem );
649 if ( node != null ) {
650 TreeViewEventArgs args = new TreeViewEventArgs ( node, Win32.uint2TreeViewAction ( nmhdr.action ) );
651 OnAfterExpand ( args );
656 CallControlWndProc( ref m );
662 CallControlWndProc( ref m );
665 CallControlWndProc ( ref m );
668 private void initCommonControlsLibrary ( ) {
669 if ( !RecreatingHandle ) {
670 INITCOMMONCONTROLSEX initEx = new INITCOMMONCONTROLSEX();
671 initEx.dwICC = CommonControlInitFlags.ICC_TREEVIEW_CLASSES;
672 Win32.InitCommonControlsEx(initEx);
676 internal void makeTree ( )
678 foreach ( TreeNode node in Nodes )
679 node.makeTree ( RootHandle, this );
682 private void setBackColor ( )
684 Win32.SendMessage ( Handle , (int)TreeViewMessages.TVM_SETBKCOLOR, 0, Win32.RGB( BackColor ) ) ;
687 private void setForeColor ( )
689 Win32.SendMessage ( Handle , (int)TreeViewMessages.TVM_SETTEXTCOLOR, 0, Win32.RGB( ForeColor ) ) ;
692 private void setImageList ( )
694 int handle = ( ImageList != null ) ? ImageList.Handle.ToInt32 ( ) : 0 ;
695 Win32.SendMessage ( Handle , (int)TreeViewMessages.TVM_SETIMAGELIST, (int)TreeViewImageListFlags.TVSIL_NORMAL, handle ) ;
698 private void setIndent ( )
700 Win32.SendMessage ( Handle , (int)TreeViewMessages.TVM_SETINDENT, Indent, 0 ) ;
703 private void selectItem ( IntPtr handle )
705 Win32.SendMessage ( Handle , (int)TreeViewMessages.TVM_SELECTITEM, (int)TreeViewItemSelFlags.TVGN_CARET, handle.ToInt32 ( ) ) ;
708 internal static IntPtr RootHandle {
712 rootHandle = (int) TreeViewItemInsertPosition.TVI_ROOT;
714 return ( IntPtr ) rootHandle;
718 private void sortTree ( )
720 int res = Win32.SendMessage ( Handle, (int)TreeViewMessages.TVM_SORTCHILDREN, 0, RootHandle.ToInt32 ( ) );
721 foreach ( TreeNode node in Nodes )