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
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:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
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.
33 using System
.ComponentModel
;
34 using System
.Runtime
.InteropServices
;
37 namespace System
.Windows
.Forms
{
44 public class TreeView
: Control
{
46 private int imageIndex
;
47 private int selectedImageIndex
;
48 private TreeNodeCollection nodes
;
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
;
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
79 selectedImageIndex
= 0;
80 SubClassWndProc_
= true;
81 borderStyle
= BorderStyle
.Fixed3D
;
83 fullRowSelect
= false;
92 indent
= DefaultIndent
;
100 SubClassWndProc_
= true;
102 dummyNode
= new TreeNode( RootHandle
, this );
104 insStruct
= new TVINSERTSTRUCT ( );
107 // --- Public Properties
110 public override Color BackColor
{
111 get { return base.BackColor; }
113 base.BackColor
= value;
115 if ( IsHandleCreated
)
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; }
129 if ( !Enum
.IsDefined ( typeof(BorderStyle
), value ) )
130 throw new InvalidEnumArgumentException( "BorderStyle",
132 typeof(BorderStyle
));
134 if ( borderStyle
!= value ) {
135 int oldStyle
= Win32
.getBorderStyle ( borderStyle
);
136 int oldExStyle
= Win32
.getBorderExStyle ( borderStyle
);
139 if ( IsHandleCreated
) {
140 Win32
.UpdateWindowStyle ( Handle
, oldStyle
, Win32
.getBorderStyle ( borderStyle
) );
141 Win32
.UpdateWindowExStyle ( Handle
, oldExStyle
, Win32
.getBorderExStyle ( borderStyle
) );
147 public bool CheckBoxes
{
148 get { return checkBoxes; }
155 public override Color ForeColor
{
156 get { return base.ForeColor; }
158 base.ForeColor
= value;
160 if ( IsHandleCreated
)
165 public bool FullRowSelect
{
166 get { return fullRowSelect; }
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; }
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; }
198 if ( hotTracking
!= value ) {
199 int oldStyle
= hotTracking
? (int)TreeViewStyles
.TVS_TRACKSELECT
: 0;
202 if ( IsHandleCreated
) {
203 int newStyle
= hotTracking
? (int)TreeViewStyles
.TVS_TRACKSELECT
: 0;
204 Win32
.UpdateWindowStyle ( Handle
, oldStyle
, newStyle
);
210 public int ImageIndex
{
211 get { return imageIndex; }
213 if ( imageIndex
!= value ) {
220 public ImageList ImageList
{
221 get { return imageList; }
223 if ( imageList
!= value ) {
225 if ( IsHandleCreated
)
232 get { return indent; }
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");
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 ) {
245 if ( IsHandleCreated
)
251 public int ItemHeight
{
253 if ( !IsHandleCreated
)
254 if ( itemHeight
== -1 ) return DefaultItemHeight
;
256 itemHeight
= Win32
.SendMessage ( Handle
, (int)TreeViewMessages
.TVM_GETITEMHEIGHT
, 0, 0 );
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 ) {
270 if ( IsHandleCreated
)
271 Win32
.SendMessage ( Handle
, (int)TreeViewMessages
.TVM_SETITEMHEIGHT
, itemHeight
, 0 );
276 public bool LabelEdit
{
277 get { return labelEdit; }
279 if ( labelEdit
!= value ) {
280 int oldStyle
= labelEdit
? (int)TreeViewStyles
.TVS_EDITLABELS
: 0;
283 if ( IsHandleCreated
) {
284 int newStyle
= labelEdit
? (int)TreeViewStyles
.TVS_EDITLABELS
: 0;
285 Win32
.UpdateWindowStyle ( Handle
, oldStyle
, newStyle
);
291 public TreeNodeCollection Nodes
{
294 nodes
= new TreeNodeCollection ( dummyNode
);
299 public string PathSeparator
{
300 get { return pathSeparator; }
302 pathSeparator
= value;
306 public bool Scrollable
{
307 get { return scrollable; }
309 if ( scrollable
!= value ) {
316 public int SelectedImageIndex
{
317 get { return selectedImageIndex; }
319 if ( selectedImageIndex
!= value ) {
320 selectedImageIndex
= value;
326 public TreeNode SelectedNode
{
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
);
335 selectedNode
= value;
336 if ( IsHandleCreated
)
337 selectItem ( selectedNode
!= null ? selectedNode
.Handle
: IntPtr
.Zero
);
341 public bool ShowLines
{
342 get { return showLines; }
344 if ( showLines
!= value ) {
345 int oldStyle
= showLines
? (int)TreeViewStyles
.TVS_HASLINES
: 0;
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; }
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; }
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
);
387 get { return sorted; }
390 if ( IsHandleCreated
&& sorted
)
395 [EditorBrowsable (EditorBrowsableState
.Never
)]
396 public override string Text
{
397 get { return base.Text; }
398 set { base.Text = value; }
401 public TreeNode TopNode
{
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
);
411 public int VisibleCount
{
413 if ( IsHandleCreated
)
414 return Win32
.SendMessage ( Handle
, (int) TreeViewMessages
.TVM_GETVISIBLECOUNT
, 0, 0 );
419 // --- Public Methods
422 public void BeginUpdate()
427 public void CollapseAll()
429 foreach ( TreeNode node
in Nodes
)
430 node
.collapseAllImpl ( this );
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
);
449 public TreeNode
GetNodeAt(int x
, int y
)
451 throw new NotImplementedException ();
454 public int GetNodeCount(bool includeSubTrees
)
456 throw new NotImplementedException ();
459 public override string ToString()
462 return base.ToString();
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
483 protected override CreateParams CreateParams
{
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
);
494 createParams
.Style
|= (int) TreeViewStyles
.TVS_CHECKBOXES
;
497 createParams
.Style
|= (int) TreeViewStyles
.TVS_FULLROWSELECT
;
500 createParams
.Style
|= (int) TreeViewStyles
.TVS_HASLINES
;
502 if ( !HideSelection
)
503 createParams
.Style
|= (int) TreeViewStyles
.TVS_SHOWSELALWAYS
;
506 createParams
.Style
|= (int) TreeViewStyles
.TVS_TRACKSELECT
;
509 createParams
.Style
|= (int) TreeViewStyles
.TVS_HASBUTTONS
;
512 createParams
.Style
|= (int) TreeViewStyles
.TVS_LINESATROOT
;
515 createParams
.Style
|= (int) TreeViewStyles
.TVS_EDITLABELS
;
518 createParams
.Style
|= (int) TreeViewStyles
.TVS_NOSCROLL
;
524 protected override Size DefaultSize
{
525 get { return new Size(121,97); }
528 // --- Protected Methods
531 protected override void CreateHandle()
533 initCommonControlsLibrary ( );
538 protected override void Dispose(bool disposing
) {
540 base.Dispose(disposing
);
544 protected override bool IsInputKey(Keys keyData
)
547 return base.IsInputKey(keyData
);
550 protected virtual void OnAfterCheck(TreeViewEventArgs e
)
555 protected virtual void OnAfterCollapse(TreeViewEventArgs e
)
560 protected virtual void OnAfterExpand( TreeViewEventArgs e
)
562 if ( AfterExpand
!= null )
563 AfterExpand ( this, e
);
566 protected virtual void OnAfterLabelEdit(NodeLabelEditEventArgs e
)
571 protected virtual void OnAfterSelect(TreeViewEventArgs e
)
576 protected virtual void OnBeforeCheck(TreeViewCancelEventArgs e
)
581 protected virtual void OnBeforeCollapse(TreeViewCancelEventArgs e
)
586 protected virtual void OnBeforeExpand( TreeViewCancelEventArgs e
)
588 if ( BeforeExpand
!= null )
589 BeforeExpand ( this, e
);
592 protected virtual void OnBeforeLabelEdit(NodeLabelEditEventArgs e
)
597 protected virtual void OnBeforeSelect(TreeViewCancelEventArgs e
)
602 protected override void OnHandleCreated(EventArgs e
)
605 base.OnHandleCreated(e
);
610 if ( itemHeight
!= -1 )
611 Win32
.SendMessage ( Handle
, (int)TreeViewMessages
.TVM_SETITEMHEIGHT
, itemHeight
, 0 );
612 if ( BackColor
!= Control
.DefaultBackColor
)
614 if ( ForeColor
!= Control
.DefaultForeColor
)
616 if ( Indent
!= DefaultIndent
)
618 if ( selectedNode
!= null )
619 selectItem ( selectedNode
.Handle
);
622 protected override void OnHandleDestroyed(EventArgs e
)
625 base.OnHandleDestroyed(e
);
628 protected virtual void OnItemDrag(ItemDragEventArgs e
)
633 protected override void OnKeyDown(KeyEventArgs e
)
639 protected override void OnKeyPress(KeyPressEventArgs e
)
645 protected override void OnKeyUp(KeyEventArgs e
)
651 protected override void WndProc(ref Message m
)
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 );
664 m.Result = (IntPtr) 1;
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 );
677 CallControlWndProc( ref m );
683 CallControlWndProc( ref m );
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
{
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
)