**** Merged from MCS ****
[mono-project.git] / mcs / class / System.Windows.Forms / System.Windows.Forms / TreeView.cs
blob9e0df3aad7bb2a2db0fc19ed63b9b83dfbb21d49
1 //
2 // System.Windows.Forms.TreeView
3 //
4 // Author:
5 // stubbed out by Jackson Harper (jackson@latitudegeo.com)
6 // Dennis Hayes (dennish@raytek.com)
7 // Aleksey Ryabchuk (ryabchuk@yahoo.com)
8 //
9 // (C) 2002 Ximian, Inc
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Drawing;
33 using System.ComponentModel;
34 using System.Runtime.InteropServices;
37 namespace System.Windows.Forms {
39 // <summary>
42 // </summary>
44 public class TreeView : Control {
46 private int imageIndex;
47 private int selectedImageIndex;
48 private TreeNodeCollection nodes;
49 private int indent;
50 private BorderStyle borderStyle;
51 private bool checkBoxes;
52 private bool fullRowSelect;
53 private bool hideSelection;
54 private bool hotTracking;
55 private bool showLines;
56 private bool showPlusMinus;
57 private bool showRootLines;
58 private ImageList imageList;
59 private bool sorted;
60 private TreeNode selectedNode;
61 private TreeNode dummyNode;
62 private int itemHeight;
63 private bool labelEdit;
64 private bool scrollable;
65 private string pathSeparator;
66 private bool updateLocked;
68 const int DefaultIndent = 19;
69 const int DefaultItemHeight = 16;
71 internal TVINSERTSTRUCT insStruct;
73 // --- Public Constructors
75 [MonoTODO]
76 public TreeView()
78 imageIndex = 0;
79 selectedImageIndex = 0;
80 SubClassWndProc_ = true;
81 borderStyle = BorderStyle.Fixed3D;
82 checkBoxes = false;
83 fullRowSelect = false;
84 hideSelection = true;
85 hotTracking = false;
86 showLines = true;
87 showPlusMinus = true;
88 showRootLines = true;
89 sorted = false;
90 imageIndex = 0;
91 imageList = null;
92 indent = DefaultIndent;
93 selectedNode = null;
94 itemHeight = -1;
95 labelEdit = false;
96 scrollable = true;
97 pathSeparator = @"\";
98 updateLocked = false;
100 SubClassWndProc_ = true;
102 dummyNode = new TreeNode( RootHandle, this );
104 insStruct = new TVINSERTSTRUCT ( );
107 // --- Public Properties
109 [MonoTODO]
110 public override Color BackColor {
111 get { return base.BackColor; }
112 set {
113 base.BackColor = value;
115 if ( IsHandleCreated )
116 setBackColor ( );
120 [EditorBrowsable (EditorBrowsableState.Never)]
121 public override Image BackgroundImage {
122 get { return base.BackgroundImage; }
123 set { base.BackgroundImage = value; }
126 public BorderStyle BorderStyle {
127 get { return borderStyle; }
128 set {
129 if ( !Enum.IsDefined ( typeof(BorderStyle), value ) )
130 throw new InvalidEnumArgumentException( "BorderStyle",
131 (int)value,
132 typeof(BorderStyle));
134 if ( borderStyle != value ) {
135 int oldStyle = Win32.getBorderStyle ( borderStyle );
136 int oldExStyle = Win32.getBorderExStyle ( borderStyle );
137 borderStyle = value;
139 if ( IsHandleCreated ) {
140 Win32.UpdateWindowStyle ( Handle, oldStyle, Win32.getBorderStyle ( borderStyle ) );
141 Win32.UpdateWindowExStyle ( Handle, oldExStyle, Win32.getBorderExStyle ( borderStyle ) );
146 [MonoTODO]
147 public bool CheckBoxes {
148 get { return checkBoxes; }
149 set {
150 checkBoxes = value;
151 RecreateHandle ( );
155 public override Color ForeColor {
156 get { return base.ForeColor; }
157 set {
158 base.ForeColor = value;
160 if ( IsHandleCreated )
161 setForeColor ( );
165 public bool FullRowSelect {
166 get { return fullRowSelect; }
167 set {
168 if ( fullRowSelect != value ) {
169 int oldStyle = fullRowSelect ? (int)TreeViewStyles.TVS_FULLROWSELECT : 0;
170 fullRowSelect = value;
172 if ( IsHandleCreated ) {
173 int newStyle = fullRowSelect ? (int)TreeViewStyles.TVS_FULLROWSELECT : 0;
174 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
180 public bool HideSelection {
181 get { return hideSelection; }
182 set {
183 if ( hideSelection != value ) {
184 int oldStyle = hideSelection ? 0 : (int)TreeViewStyles.TVS_SHOWSELALWAYS;
185 hideSelection = value;
187 if ( IsHandleCreated ) {
188 int newStyle = hideSelection ? 0 : (int)TreeViewStyles.TVS_SHOWSELALWAYS;
189 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
195 public bool HotTracking {
196 get { return hotTracking; }
197 set {
198 if ( hotTracking != value ) {
199 int oldStyle = hotTracking ? (int)TreeViewStyles.TVS_TRACKSELECT : 0;
200 hotTracking = value;
202 if ( IsHandleCreated ) {
203 int newStyle = hotTracking ? (int)TreeViewStyles.TVS_TRACKSELECT : 0;
204 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
209 [MonoTODO]
210 public int ImageIndex {
211 get { return imageIndex; }
212 set {
213 if ( imageIndex != value ) {
214 imageIndex = value;
215 RecreateHandle ( );
219 [MonoTODO]
220 public ImageList ImageList {
221 get { return imageList; }
222 set {
223 if ( imageList != value ) {
224 imageList = value;
225 if ( IsHandleCreated )
226 setImageList ( );
231 public int Indent {
232 get { return indent; }
233 set {
234 if ( value < 0 )
235 throw new ArgumentException (
236 string.Format ("'{0}' is not a valid value for 'Indent'. 'Indent' must be greater than or equal to 0.", value), "value");
238 if ( value > 32000 )
239 throw new ArgumentException (
240 string.Format ("'{0}' is not a valid value for 'Indent'. 'Indent' must be less than or equal to 32000.", value), "value" );
242 if ( indent != value ) {
243 indent = value;
245 if ( IsHandleCreated )
246 setIndent ( );
251 public int ItemHeight {
252 get {
253 if ( !IsHandleCreated )
254 if ( itemHeight == -1 ) return DefaultItemHeight;
255 else
256 itemHeight = Win32.SendMessage ( Handle, (int)TreeViewMessages.TVM_GETITEMHEIGHT, 0, 0 );
257 return itemHeight;
259 set {
260 if ( value < 1 )
261 throw new ArgumentException (
262 string.Format ("'{0}' is not a valid value for 'ItemHeight'. 'ItemHeight' must be greater than or equal to 1.", value), "value");
264 if ( value > Int16.MaxValue )
265 throw new ArgumentException (
266 string.Format ("'{0}' is not a valid value for 'ItemHeight'. 'ItemHeight' must be less than or equal to {1}.", value, Int16.MaxValue), "value" );
268 if ( itemHeight != value ) {
269 itemHeight = value;
270 if ( IsHandleCreated )
271 Win32.SendMessage ( Handle, (int)TreeViewMessages.TVM_SETITEMHEIGHT, itemHeight, 0 );
276 public bool LabelEdit {
277 get { return labelEdit; }
278 set {
279 if ( labelEdit != value ) {
280 int oldStyle = labelEdit ? (int)TreeViewStyles.TVS_EDITLABELS : 0;
281 labelEdit = value;
283 if ( IsHandleCreated ) {
284 int newStyle = labelEdit ? (int)TreeViewStyles.TVS_EDITLABELS : 0;
285 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
291 public TreeNodeCollection Nodes {
292 get {
293 if ( nodes == null )
294 nodes = new TreeNodeCollection ( dummyNode );
295 return nodes;
299 public string PathSeparator {
300 get { return pathSeparator; }
301 set {
302 pathSeparator = value;
305 [MonoTODO]
306 public bool Scrollable {
307 get { return scrollable; }
308 set {
309 if ( scrollable != value ) {
310 scrollable = value;
311 RecreateHandle ( );
315 [MonoTODO]
316 public int SelectedImageIndex {
317 get { return selectedImageIndex; }
318 set {
319 if ( selectedImageIndex != value ) {
320 selectedImageIndex = value;
321 RecreateHandle ( );
325 [MonoTODO]
326 public TreeNode SelectedNode {
327 get {
328 if ( IsHandleCreated ) {
329 int hitem = Win32.SendMessage ( Handle, (int) TreeViewMessages.TVM_GETNEXTITEM, (int)TreeViewItemSelFlags.TVGN_CARET, 0 );
330 selectedNode = TreeNode.FromHandle ( this, (IntPtr) hitem );
332 return selectedNode;
334 set {
335 selectedNode = value;
336 if ( IsHandleCreated )
337 selectItem ( selectedNode != null ? selectedNode.Handle : IntPtr.Zero );
341 public bool ShowLines {
342 get { return showLines; }
343 set {
344 if ( showLines != value ) {
345 int oldStyle = showLines ? (int)TreeViewStyles.TVS_HASLINES : 0;
346 showLines = value;
348 if ( IsHandleCreated ) {
349 int newStyle = showLines ? (int)TreeViewStyles.TVS_HASLINES : 0;
350 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
356 public bool ShowPlusMinus {
357 get { return showPlusMinus; }
358 set {
359 if ( showPlusMinus != value ) {
360 int oldStyle = showPlusMinus ? (int)TreeViewStyles.TVS_HASBUTTONS : 0;
361 showPlusMinus = value;
363 if ( IsHandleCreated ) {
364 int newStyle = showPlusMinus ? (int)TreeViewStyles.TVS_HASBUTTONS : 0;
365 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
371 public bool ShowRootLines {
372 get { return showRootLines; }
373 set {
374 if ( showRootLines != value ) {
375 int oldStyle = showRootLines ? (int)TreeViewStyles.TVS_LINESATROOT : 0;
376 showRootLines = value;
378 if ( IsHandleCreated ) {
379 int newStyle = showRootLines ? (int)TreeViewStyles.TVS_LINESATROOT : 0;
380 Win32.UpdateWindowStyle ( Handle, oldStyle, newStyle );
385 [MonoTODO]
386 public bool Sorted {
387 get { return sorted; }
388 set {
389 sorted = value;
390 if ( IsHandleCreated && sorted )
391 sortTree ( );
395 [EditorBrowsable (EditorBrowsableState.Never)]
396 public override string Text {
397 get { return base.Text; }
398 set { base.Text = value; }
401 public TreeNode TopNode {
402 get {
403 if ( IsHandleCreated ) {
404 int hitem = Win32.SendMessage ( Handle, (int) TreeViewMessages.TVM_GETNEXTITEM, (int)TreeViewItemSelFlags.TVGN_FIRSTVISIBLE, 0 );
405 return TreeNode.FromHandle ( this, (IntPtr) hitem );
407 return null;
411 public int VisibleCount {
412 get {
413 if ( IsHandleCreated )
414 return Win32.SendMessage ( Handle, (int) TreeViewMessages.TVM_GETVISIBLECOUNT, 0, 0 );
415 return 0;
419 // --- Public Methods
421 [MonoTODO]
422 public void BeginUpdate()
424 updateLocked = true;
427 public void CollapseAll()
429 foreach ( TreeNode node in Nodes )
430 node.collapseAllImpl ( this );
432 [MonoTODO]
433 public void EndUpdate()
435 updateLocked = false;
438 public void ExpandAll()
440 foreach ( TreeNode node in Nodes )
441 node.expandAllImpl ( this );
444 public TreeNode GetNodeAt(Point pt)
446 return GetNodeAt ( pt.X, pt.Y );
448 [MonoTODO]
449 public TreeNode GetNodeAt(int x, int y)
451 throw new NotImplementedException ();
453 [MonoTODO]
454 public int GetNodeCount(bool includeSubTrees)
456 throw new NotImplementedException ();
458 [MonoTODO]
459 public override string ToString()
461 //FIXME:
462 return base.ToString();
465 // --- Public Events
467 public event TreeViewEventHandler AfterCheck;
468 public event TreeViewEventHandler AfterCollapse;
469 public event TreeViewEventHandler AfterExpand;
470 public event NodeLabelEditEventHandler AfterLabelEdit;
471 public event TreeViewEventHandler AfterSelect;
472 public event TreeViewCancelEventHandler BeforeCheck;
473 public event TreeViewCancelEventHandler BeforeCollapse;
474 public event TreeViewCancelEventHandler BeforeExpand;
475 public event NodeLabelEditEventHandler BeforeLabelEdit;
476 public event TreeViewCancelEventHandler BeforeSelect;
477 public event ItemDragEventHandler ItemDrag;
478 //public new event PaintEventHandler Paint;
480 // --- Protected Properties
482 [MonoTODO]
483 protected override CreateParams CreateParams {
484 get {
485 CreateParams createParams = base.CreateParams;
487 createParams.ClassName = Win32.TREEVIEW_CLASS;
488 createParams.Style |= (int) WindowStyles.WS_CHILD ;
490 createParams.Style |= Win32.getBorderStyle ( BorderStyle );
491 createParams.ExStyle |= Win32.getBorderExStyle ( BorderStyle );
493 if ( CheckBoxes )
494 createParams.Style |= (int) TreeViewStyles.TVS_CHECKBOXES;
496 if ( FullRowSelect )
497 createParams.Style |= (int) TreeViewStyles.TVS_FULLROWSELECT;
499 if ( ShowLines )
500 createParams.Style |= (int) TreeViewStyles.TVS_HASLINES;
502 if ( !HideSelection )
503 createParams.Style |= (int) TreeViewStyles.TVS_SHOWSELALWAYS;
505 if ( HotTracking )
506 createParams.Style |= (int) TreeViewStyles.TVS_TRACKSELECT;
508 if ( ShowPlusMinus )
509 createParams.Style |= (int) TreeViewStyles.TVS_HASBUTTONS;
511 if ( ShowRootLines )
512 createParams.Style |= (int) TreeViewStyles.TVS_LINESATROOT;
514 if ( LabelEdit )
515 createParams.Style |= (int) TreeViewStyles.TVS_EDITLABELS;
517 if ( !Scrollable )
518 createParams.Style |= (int) TreeViewStyles.TVS_NOSCROLL;
520 return createParams;
524 protected override Size DefaultSize {
525 get { return new Size(121,97); }
528 // --- Protected Methods
530 [MonoTODO]
531 protected override void CreateHandle()
533 initCommonControlsLibrary ( );
534 base.CreateHandle();
537 [MonoTODO]
538 protected override void Dispose(bool disposing) {
539 // FIXME:
540 base.Dispose(disposing);
543 [MonoTODO]
544 protected override bool IsInputKey(Keys keyData)
546 //FIXME:
547 return base.IsInputKey(keyData);
549 [MonoTODO]
550 protected virtual void OnAfterCheck(TreeViewEventArgs e)
552 //FIXME:
554 [MonoTODO]
555 protected virtual void OnAfterCollapse(TreeViewEventArgs e)
557 //FIXME:
559 [MonoTODO]
560 protected virtual void OnAfterExpand( TreeViewEventArgs e )
562 if ( AfterExpand != null )
563 AfterExpand ( this, e );
565 [MonoTODO]
566 protected virtual void OnAfterLabelEdit(NodeLabelEditEventArgs e)
568 //FIXME:
570 [MonoTODO]
571 protected virtual void OnAfterSelect(TreeViewEventArgs e)
573 //FIXME:
575 [MonoTODO]
576 protected virtual void OnBeforeCheck(TreeViewCancelEventArgs e)
578 //FIXME:
580 [MonoTODO]
581 protected virtual void OnBeforeCollapse(TreeViewCancelEventArgs e)
583 //FIXME:
585 [MonoTODO]
586 protected virtual void OnBeforeExpand( TreeViewCancelEventArgs e )
588 if ( BeforeExpand != null )
589 BeforeExpand ( this, e );
591 [MonoTODO]
592 protected virtual void OnBeforeLabelEdit(NodeLabelEditEventArgs e)
594 //FIXME:
596 [MonoTODO]
597 protected virtual void OnBeforeSelect(TreeViewCancelEventArgs e)
599 //FIXME:
601 [MonoTODO]
602 protected override void OnHandleCreated(EventArgs e)
604 //FIXME:
605 base.OnHandleCreated(e);
607 makeTree ( );
609 setImageList ( );
610 if ( itemHeight != -1 )
611 Win32.SendMessage ( Handle, (int)TreeViewMessages.TVM_SETITEMHEIGHT, itemHeight, 0 );
612 if ( BackColor != Control.DefaultBackColor )
613 setBackColor ( );
614 if ( ForeColor != Control.DefaultForeColor )
615 setForeColor ( );
616 if ( Indent != DefaultIndent )
617 setIndent ( );
618 if ( selectedNode != null )
619 selectItem ( selectedNode.Handle );
621 [MonoTODO]
622 protected override void OnHandleDestroyed(EventArgs e)
624 //FIXME:
625 base.OnHandleDestroyed(e);
627 [MonoTODO]
628 protected virtual void OnItemDrag(ItemDragEventArgs e)
630 //FIXME:
632 [MonoTODO]
633 protected override void OnKeyDown(KeyEventArgs e)
635 //FIXME:
636 base.OnKeyDown(e);
638 [MonoTODO]
639 protected override void OnKeyPress(KeyPressEventArgs e)
641 //FIXME:
642 base.OnKeyPress(e);
644 [MonoTODO]
645 protected override void OnKeyUp(KeyEventArgs e)
647 //FIXME:
648 base.OnKeyUp(e);
650 [MonoTODO]
651 protected override void WndProc(ref Message m)
653 switch ( m.Msg ) {
654 case Msg.WM_NOTIFY:
655 NMTREEVIEW nmhdr = (NMTREEVIEW)Marshal.PtrToStructure ( m.LParam, typeof ( NMTREEVIEW ) );
657 switch ( nmhdr.hdr.code ) {
658 case (int) TreeViewNotifications.TVN_ITEMEXPANDINGA: {
659 TreeNode node = TreeNode.FromHandle ( this, nmhdr.itemNew.hItem );
660 if ( node != null ) {
661 TreeViewCancelEventArgs args = new TreeViewCancelEventArgs ( node, false, Win32.uint2TreeViewAction ( nmhdr.action ) );
662 OnBeforeExpand ( args );
663 if ( args.Cancel )
664 m.Result = (IntPtr) 1;
667 break;
668 case (int) TreeViewNotifications.TVN_ITEMEXPANDEDA: {
669 TreeNode node = TreeNode.FromHandle ( this, nmhdr.itemNew.hItem );
670 if ( node != null ) {
671 TreeViewEventArgs args = new TreeViewEventArgs ( node, Win32.uint2TreeViewAction ( nmhdr.action ) );
672 OnAfterExpand ( args );
675 break;
676 default:
677 CallControlWndProc( ref m );
678 break;
681 break;
682 default:
683 CallControlWndProc( ref m );
684 break;
686 CallControlWndProc ( ref m );
689 private void initCommonControlsLibrary ( ) {
690 if ( !RecreatingHandle ) {
691 INITCOMMONCONTROLSEX initEx = new INITCOMMONCONTROLSEX();
692 initEx.dwICC = CommonControlInitFlags.ICC_TREEVIEW_CLASSES;
693 Win32.InitCommonControlsEx(initEx);
697 internal void makeTree ( )
699 foreach ( TreeNode node in Nodes )
700 node.makeTree ( RootHandle, this );
703 private void setBackColor ( )
705 Win32.SendMessage ( Handle , (int)TreeViewMessages.TVM_SETBKCOLOR, 0, Win32.RGB( BackColor ) ) ;
708 private void setForeColor ( )
710 Win32.SendMessage ( Handle , (int)TreeViewMessages.TVM_SETTEXTCOLOR, 0, Win32.RGB( ForeColor ) ) ;
713 private void setImageList ( )
715 int handle = ( ImageList != null ) ? ImageList.Handle.ToInt32 ( ) : 0 ;
716 Win32.SendMessage ( Handle , (int)TreeViewMessages.TVM_SETIMAGELIST, (int)TreeViewImageListFlags.TVSIL_NORMAL, handle ) ;
719 private void setIndent ( )
721 Win32.SendMessage ( Handle , (int)TreeViewMessages.TVM_SETINDENT, Indent, 0 ) ;
724 private void selectItem ( IntPtr handle )
726 Win32.SendMessage ( Handle , (int)TreeViewMessages.TVM_SELECTITEM, (int)TreeViewItemSelFlags.TVGN_CARET, handle.ToInt32 ( ) ) ;
729 internal static IntPtr RootHandle {
730 get {
731 int rootHandle = 0;
732 unchecked {
733 rootHandle = (int) TreeViewItemInsertPosition.TVI_ROOT;
735 return ( IntPtr ) rootHandle;
739 private void sortTree ( )
741 int res = Win32.SendMessage ( Handle, (int)TreeViewMessages.TVM_SORTCHILDREN, 0, RootHandle.ToInt32 ( ) );
742 foreach ( TreeNode node in Nodes )
743 node.sortNode ( );