External/Aga.Controls/Tree/TreeViewAdv.cs
changeset 345 0c551e8818e0
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/External/Aga.Controls/Tree/TreeViewAdv.cs	Sun May 27 15:16:19 2012 +0000
     1.3 @@ -0,0 +1,1196 @@
     1.4 +using System;
     1.5 +using System.Collections.Generic;
     1.6 +using System.Collections.ObjectModel;
     1.7 +using System.ComponentModel;
     1.8 +using System.Drawing;
     1.9 +using System.Security.Permissions;
    1.10 +using System.Threading;
    1.11 +using System.Windows.Forms;
    1.12 +using System.Collections;
    1.13 +
    1.14 +using Aga.Controls.Tree.NodeControls;
    1.15 +using Aga.Controls.Threading;
    1.16 +
    1.17 +
    1.18 +namespace Aga.Controls.Tree
    1.19 +{
    1.20 +	/// <summary>
    1.21 +	/// Extensible advanced <see cref="TreeView"/> implemented in 100% managed C# code.
    1.22 +	/// Features: Model/View architecture. Multiple column per node. Ability to select
    1.23 +	/// multiple tree nodes. Different types of controls for each node column: 
    1.24 +	/// <see cref="CheckBox"/>, Icon, Label... Drag and Drop highlighting. Load on
    1.25 +	/// demand of nodes. Incremental search of nodes.
    1.26 +	/// </summary>
    1.27 +	public partial class TreeViewAdv : Control
    1.28 +	{
    1.29 +		private const int LeftMargin = 7;
    1.30 +		internal const int ItemDragSensivity = 4;
    1.31 +		private readonly int _columnHeaderHeight;
    1.32 +		private const int DividerWidth = 9;
    1.33 +		private const int DividerCorrectionGap = -2;
    1.34 +
    1.35 +		private Pen _linePen;
    1.36 +		private Pen _markPen;
    1.37 +		private bool _suspendUpdate;
    1.38 +		private bool _needFullUpdate;
    1.39 +		private bool _fireSelectionEvent;
    1.40 +		private NodePlusMinus _plusMinus;
    1.41 +		private ToolTip _toolTip;
    1.42 +		private DrawContext _measureContext;
    1.43 +		private TreeColumn _hotColumn;
    1.44 +		private IncrementalSearch _search;
    1.45 +		private List<TreeNodeAdv> _expandingNodes = new List<TreeNodeAdv>();
    1.46 +		private AbortableThreadPool _threadPool = new AbortableThreadPool();
    1.47 +
    1.48 +		#region Public Events
    1.49 +
    1.50 +		[Category("Action")]
    1.51 +		public event ItemDragEventHandler ItemDrag;
    1.52 +		private void OnItemDrag(MouseButtons buttons, object item)
    1.53 +		{
    1.54 +			if (ItemDrag != null)
    1.55 +				ItemDrag(this, new ItemDragEventArgs(buttons, item));
    1.56 +		}
    1.57 +
    1.58 +		[Category("Behavior")]
    1.59 +		public event EventHandler<TreeNodeAdvMouseEventArgs> NodeMouseClick;
    1.60 +		private void OnNodeMouseClick(TreeNodeAdvMouseEventArgs args)
    1.61 +		{
    1.62 +			if (NodeMouseClick != null)
    1.63 +				NodeMouseClick(this, args);
    1.64 +		}
    1.65 +
    1.66 +		[Category("Behavior")]
    1.67 +		public event EventHandler<TreeNodeAdvMouseEventArgs> NodeMouseDoubleClick;
    1.68 +		private void OnNodeMouseDoubleClick(TreeNodeAdvMouseEventArgs args)
    1.69 +		{
    1.70 +			if (NodeMouseDoubleClick != null)
    1.71 +				NodeMouseDoubleClick(this, args);
    1.72 +		}
    1.73 +
    1.74 +		[Category("Behavior")]
    1.75 +		public event EventHandler<TreeColumnEventArgs> ColumnWidthChanged;
    1.76 +		internal void OnColumnWidthChanged(TreeColumn column)
    1.77 +		{
    1.78 +			if (ColumnWidthChanged != null)
    1.79 +				ColumnWidthChanged(this, new TreeColumnEventArgs(column));
    1.80 +		}
    1.81 +
    1.82 +		[Category("Behavior")]
    1.83 +		public event EventHandler<TreeColumnEventArgs> ColumnReordered;
    1.84 +		internal void OnColumnReordered(TreeColumn column)
    1.85 +		{
    1.86 +			if (ColumnReordered != null)
    1.87 +				ColumnReordered(this, new TreeColumnEventArgs(column));
    1.88 +		}
    1.89 +
    1.90 +		[Category("Behavior")]
    1.91 +		public event EventHandler<TreeColumnEventArgs> ColumnClicked;
    1.92 +		internal void OnColumnClicked(TreeColumn column)
    1.93 +		{
    1.94 +			if (ColumnClicked != null)
    1.95 +				ColumnClicked(this, new TreeColumnEventArgs(column));
    1.96 +		}
    1.97 +
    1.98 +		[Category("Behavior")]
    1.99 +		public event EventHandler SelectionChanged;
   1.100 +		internal void OnSelectionChanged()
   1.101 +		{
   1.102 +			if (SuspendSelectionEvent)
   1.103 +				_fireSelectionEvent = true;
   1.104 +			else
   1.105 +			{
   1.106 +				_fireSelectionEvent = false;
   1.107 +				if (SelectionChanged != null)
   1.108 +					SelectionChanged(this, EventArgs.Empty);
   1.109 +			}
   1.110 +		}
   1.111 +
   1.112 +		[Category("Behavior")]
   1.113 +		public event EventHandler<TreeViewAdvEventArgs> Collapsing;
   1.114 +		private void OnCollapsing(TreeNodeAdv node)
   1.115 +		{
   1.116 +			if (Collapsing != null)
   1.117 +				Collapsing(this, new TreeViewAdvEventArgs(node));
   1.118 +		}
   1.119 +
   1.120 +		[Category("Behavior")]
   1.121 +		public event EventHandler<TreeViewAdvEventArgs> Collapsed;
   1.122 +		private void OnCollapsed(TreeNodeAdv node)
   1.123 +		{
   1.124 +			if (Collapsed != null)
   1.125 +				Collapsed(this, new TreeViewAdvEventArgs(node));
   1.126 +		}
   1.127 +
   1.128 +		[Category("Behavior")]
   1.129 +		public event EventHandler<TreeViewAdvEventArgs> Expanding;
   1.130 +		private void OnExpanding(TreeNodeAdv node)
   1.131 +		{
   1.132 +			if (Expanding != null)
   1.133 +				Expanding(this, new TreeViewAdvEventArgs(node));
   1.134 +		}
   1.135 +
   1.136 +		[Category("Behavior")]
   1.137 +		public event EventHandler<TreeViewAdvEventArgs> Expanded;
   1.138 +		private void OnExpanded(TreeNodeAdv node)
   1.139 +		{
   1.140 +			if (Expanded != null)
   1.141 +				Expanded(this, new TreeViewAdvEventArgs(node));
   1.142 +		}
   1.143 +
   1.144 +		[Category("Behavior")]
   1.145 +		public event EventHandler GridLineStyleChanged;
   1.146 +		private void OnGridLineStyleChanged()
   1.147 +		{
   1.148 +			if (GridLineStyleChanged != null)
   1.149 +				GridLineStyleChanged(this, EventArgs.Empty);
   1.150 +		}
   1.151 +
   1.152 +		[Category("Behavior")]
   1.153 +		public event ScrollEventHandler Scroll;
   1.154 +		protected virtual void OnScroll(ScrollEventArgs e)
   1.155 +		{
   1.156 +			if (Scroll != null)
   1.157 +				Scroll(this, e);
   1.158 +		}
   1.159 +
   1.160 +		[Category("Behavior")]
   1.161 +		public event EventHandler<TreeViewRowDrawEventArgs> RowDraw;
   1.162 +		protected virtual void OnRowDraw(PaintEventArgs e, TreeNodeAdv node, DrawContext context, int row, Rectangle rowRect)
   1.163 +		{
   1.164 +			if (RowDraw != null)
   1.165 +			{
   1.166 +				TreeViewRowDrawEventArgs args = new TreeViewRowDrawEventArgs(e.Graphics, e.ClipRectangle, node, context, row, rowRect);
   1.167 +				RowDraw(this, args);
   1.168 +			}
   1.169 +		}
   1.170 +
   1.171 +		/// <summary>
   1.172 +		/// Fires when control is going to draw. Can be used to change text or back color
   1.173 +		/// </summary>
   1.174 +		[Category("Behavior")]
   1.175 +		public event EventHandler<DrawEventArgs> DrawControl;
   1.176 +
   1.177 +		internal bool DrawControlMustBeFired()
   1.178 +		{
   1.179 +			return DrawControl != null;
   1.180 +		}
   1.181 +
   1.182 +		internal void FireDrawControl(DrawEventArgs args)
   1.183 +		{
   1.184 +			OnDrawControl(args);
   1.185 +		}
   1.186 +
   1.187 +		protected virtual void OnDrawControl(DrawEventArgs args)
   1.188 +		{
   1.189 +			if (DrawControl != null)
   1.190 +				DrawControl(this, args);
   1.191 +		}
   1.192 +
   1.193 +
   1.194 +		[Category("Drag Drop")]
   1.195 +		public event EventHandler<DropNodeValidatingEventArgs> DropNodeValidating;
   1.196 +		protected virtual void OnDropNodeValidating(Point point, ref TreeNodeAdv node)
   1.197 +		{
   1.198 +			if (DropNodeValidating != null)
   1.199 +			{
   1.200 +				DropNodeValidatingEventArgs args = new DropNodeValidatingEventArgs(point, node);
   1.201 +				DropNodeValidating(this, args);
   1.202 +				node = args.Node;
   1.203 +			}
   1.204 +		}
   1.205 +		#endregion
   1.206 +
   1.207 +		public TreeViewAdv()
   1.208 +		{
   1.209 +			InitializeComponent();
   1.210 +			SetStyle(ControlStyles.AllPaintingInWmPaint
   1.211 +				| ControlStyles.UserPaint
   1.212 +				| ControlStyles.OptimizedDoubleBuffer
   1.213 +				| ControlStyles.ResizeRedraw
   1.214 +				| ControlStyles.Selectable
   1.215 +				, true);
   1.216 +
   1.217 +
   1.218 +			if (Application.RenderWithVisualStyles)
   1.219 +				_columnHeaderHeight = 20;
   1.220 +			else
   1.221 +				_columnHeaderHeight = 17;
   1.222 +
   1.223 +			//BorderStyle = BorderStyle.Fixed3D;
   1.224 +			_hScrollBar.Height = SystemInformation.HorizontalScrollBarHeight;
   1.225 +			_vScrollBar.Width = SystemInformation.VerticalScrollBarWidth;
   1.226 +			_rowLayout = new FixedRowHeightLayout(this, RowHeight);
   1.227 +			_rowMap = new List<TreeNodeAdv>();
   1.228 +			_selection = new List<TreeNodeAdv>();
   1.229 +			_readonlySelection = new ReadOnlyCollection<TreeNodeAdv>(_selection);
   1.230 +			_columns = new TreeColumnCollection(this);
   1.231 +			_toolTip = new ToolTip();
   1.232 +
   1.233 +			_measureContext = new DrawContext();
   1.234 +			_measureContext.Font = Font;
   1.235 +			_measureContext.Graphics = Graphics.FromImage(new Bitmap(1, 1));
   1.236 +
   1.237 +			Input = new NormalInputState(this);
   1.238 +			_search = new IncrementalSearch(this);
   1.239 +			CreateNodes();
   1.240 +			CreatePens();
   1.241 +
   1.242 +			ArrangeControls();
   1.243 +
   1.244 +			_plusMinus = new NodePlusMinus();
   1.245 +			_controls = new NodeControlsCollection(this);
   1.246 +
   1.247 +			Font = _font;
   1.248 +			ExpandingIcon.IconChanged += ExpandingIconChanged;
   1.249 +		}
   1.250 +
   1.251 +		void ExpandingIconChanged(object sender, EventArgs e)
   1.252 +		{
   1.253 +			if (IsHandleCreated && !IsDisposed)
   1.254 +				BeginInvoke(new MethodInvoker(DrawIcons));
   1.255 +		}
   1.256 +
   1.257 +		private void DrawIcons()
   1.258 +		{
   1.259 +			using (Graphics gr = Graphics.FromHwnd(this.Handle))
   1.260 +			{
   1.261 +				//Apply the same Graphics Transform logic as used in OnPaint.
   1.262 +				int y = 0;
   1.263 +				if (UseColumns)
   1.264 +				{
   1.265 +					y += ColumnHeaderHeight;
   1.266 +					if (Columns.Count == 0)
   1.267 +						return;
   1.268 +				}
   1.269 +				int firstRowY = _rowLayout.GetRowBounds(FirstVisibleRow).Y;
   1.270 +				y -= firstRowY;
   1.271 +				gr.ResetTransform();
   1.272 +				gr.TranslateTransform(-OffsetX, y);
   1.273 +
   1.274 +				DrawContext context = new DrawContext();
   1.275 +				context.Graphics = gr;
   1.276 +				for (int i = 0; i < _expandingNodes.Count; i++)
   1.277 +				{
   1.278 +					foreach (NodeControlInfo item in GetNodeControls(_expandingNodes[i]))
   1.279 +					{
   1.280 +						if (item.Control is ExpandingIcon)
   1.281 +						{
   1.282 +							Rectangle bounds = item.Bounds;
   1.283 +							if (item.Node.Parent == null && UseColumns)
   1.284 +								bounds.Location = Point.Empty; // display root expanding icon at 0,0
   1.285 +
   1.286 +							context.Bounds = bounds;
   1.287 +							item.Control.Draw(item.Node, context);
   1.288 +						}
   1.289 +					}
   1.290 +				}
   1.291 +			}
   1.292 +		}
   1.293 +
   1.294 +		#region Public Methods
   1.295 +
   1.296 +		public TreePath GetPath(TreeNodeAdv node)
   1.297 +		{
   1.298 +			if (node == _root)
   1.299 +				return TreePath.Empty;
   1.300 +			else
   1.301 +			{
   1.302 +				Stack<object> stack = new Stack<object>();
   1.303 +				while (node != _root && node != null)
   1.304 +				{
   1.305 +					stack.Push(node.Tag);
   1.306 +					node = node.Parent;
   1.307 +				}
   1.308 +				return new TreePath(stack.ToArray());
   1.309 +			}
   1.310 +		}
   1.311 +
   1.312 +		public TreeNodeAdv GetNodeAt(Point point)
   1.313 +		{
   1.314 +			NodeControlInfo info = GetNodeControlInfoAt(point);
   1.315 +			return info.Node;
   1.316 +		}
   1.317 +
   1.318 +		public NodeControlInfo GetNodeControlInfoAt(Point point)
   1.319 +		{
   1.320 +			if (point.X < 0 || point.Y < 0)
   1.321 +				return NodeControlInfo.Empty;
   1.322 +
   1.323 +			int row = _rowLayout.GetRowAt(point);
   1.324 +			if (row < RowCount && row >= 0)
   1.325 +				return GetNodeControlInfoAt(RowMap[row], point);
   1.326 +			else
   1.327 +				return NodeControlInfo.Empty;
   1.328 +		}
   1.329 +
   1.330 +		private NodeControlInfo GetNodeControlInfoAt(TreeNodeAdv node, Point point)
   1.331 +		{
   1.332 +			Rectangle rect = _rowLayout.GetRowBounds(FirstVisibleRow);
   1.333 +			point.Y += (rect.Y - ColumnHeaderHeight);
   1.334 +			point.X += OffsetX;
   1.335 +			foreach (NodeControlInfo info in GetNodeControls(node))
   1.336 +				if (info.Bounds.Contains(point))
   1.337 +					return info;
   1.338 +
   1.339 +			if (FullRowSelect)
   1.340 +				return new NodeControlInfo(null, Rectangle.Empty, node);
   1.341 +			else
   1.342 +				return NodeControlInfo.Empty;
   1.343 +		}
   1.344 +
   1.345 +		public void BeginUpdate()
   1.346 +		{
   1.347 +			_suspendUpdate = true;
   1.348 +			SuspendSelectionEvent = true;
   1.349 +		}
   1.350 +
   1.351 +		public void EndUpdate()
   1.352 +		{
   1.353 +			_suspendUpdate = false;
   1.354 +			if (_needFullUpdate)
   1.355 +				FullUpdate();
   1.356 +			else
   1.357 +				UpdateView();
   1.358 +			SuspendSelectionEvent = false;
   1.359 +		}
   1.360 +
   1.361 +		public void ExpandAll()
   1.362 +		{
   1.363 +			_root.ExpandAll();
   1.364 +		}
   1.365 +
   1.366 +		public void CollapseAll()
   1.367 +		{
   1.368 +			_root.CollapseAll();
   1.369 +		}
   1.370 +
   1.371 +		/// <summary>
   1.372 +		/// Expand all parent nodes, andd scroll to the specified node
   1.373 +		/// </summary>
   1.374 +		public void EnsureVisible(TreeNodeAdv node)
   1.375 +		{
   1.376 +			if (node == null)
   1.377 +				throw new ArgumentNullException("node");
   1.378 +
   1.379 +			if (!IsMyNode(node))
   1.380 +				throw new ArgumentException();
   1.381 +
   1.382 +			TreeNodeAdv parent = node.Parent;
   1.383 +			while (parent != _root)
   1.384 +			{
   1.385 +				parent.IsExpanded = true;
   1.386 +				parent = parent.Parent;
   1.387 +			}
   1.388 +			ScrollTo(node);
   1.389 +		}
   1.390 +
   1.391 +		/// <summary>
   1.392 +		/// Make node visible, scroll if needed. All parent nodes of the specified node must be expanded
   1.393 +		/// </summary>
   1.394 +		/// <param name="node"></param>
   1.395 +		public void ScrollTo(TreeNodeAdv node)
   1.396 +		{
   1.397 +			if (node == null)
   1.398 +				throw new ArgumentNullException("node");
   1.399 +
   1.400 +			if (!IsMyNode(node))
   1.401 +				throw new ArgumentException();
   1.402 +
   1.403 +			if (node.Row < 0)
   1.404 +				CreateRowMap();
   1.405 +
   1.406 +			int row = -1;
   1.407 +
   1.408 +			if (node.Row < FirstVisibleRow)
   1.409 +				row = node.Row;
   1.410 +			else
   1.411 +			{
   1.412 +				int pageStart = _rowLayout.GetRowBounds(FirstVisibleRow).Top;
   1.413 +				int rowBottom = _rowLayout.GetRowBounds(node.Row).Bottom;
   1.414 +				if (rowBottom > pageStart + DisplayRectangle.Height - ColumnHeaderHeight)
   1.415 +					row = _rowLayout.GetFirstRow(node.Row);
   1.416 +			}
   1.417 +
   1.418 +			if (row >= _vScrollBar.Minimum && row <= _vScrollBar.Maximum)
   1.419 +				_vScrollBar.Value = row;
   1.420 +		}
   1.421 +
   1.422 +		public void ClearSelection()
   1.423 +		{
   1.424 +			BeginUpdate();
   1.425 +			try
   1.426 +			{
   1.427 +				ClearSelectionInternal();
   1.428 +			}
   1.429 +			finally
   1.430 +			{
   1.431 +				EndUpdate();
   1.432 +			}
   1.433 +		}
   1.434 +
   1.435 +		internal void ClearSelectionInternal()
   1.436 +		{
   1.437 +			while (Selection.Count > 0)
   1.438 +			{
   1.439 +				var t = Selection[0];
   1.440 +				t.IsSelected = false;
   1.441 +				Selection.Remove(t); //hack
   1.442 +			}
   1.443 +		}
   1.444 +
   1.445 +		#endregion
   1.446 +
   1.447 +		protected override void OnSizeChanged(EventArgs e)
   1.448 +		{
   1.449 +			ArrangeControls();
   1.450 +			SafeUpdateScrollBars();
   1.451 +			base.OnSizeChanged(e);
   1.452 +		}
   1.453 +
   1.454 +		private void ArrangeControls()
   1.455 +		{
   1.456 +			int hBarSize = _hScrollBar.Height;
   1.457 +			int vBarSize = _vScrollBar.Width;
   1.458 +			Rectangle clientRect = ClientRectangle;
   1.459 +
   1.460 +			_hScrollBar.SetBounds(clientRect.X, clientRect.Bottom - hBarSize,
   1.461 +				clientRect.Width - vBarSize, hBarSize);
   1.462 +
   1.463 +			_vScrollBar.SetBounds(clientRect.Right - vBarSize, clientRect.Y,
   1.464 +				vBarSize, clientRect.Height - hBarSize);
   1.465 +		}
   1.466 +
   1.467 +		private void SafeUpdateScrollBars()
   1.468 +		{
   1.469 +			if (InvokeRequired)
   1.470 +				BeginInvoke(new MethodInvoker(UpdateScrollBars));
   1.471 +			else
   1.472 +				UpdateScrollBars();
   1.473 +		}
   1.474 +
   1.475 +		private void UpdateScrollBars()
   1.476 +		{
   1.477 +			UpdateVScrollBar();
   1.478 +			UpdateHScrollBar();
   1.479 +			UpdateVScrollBar();
   1.480 +			UpdateHScrollBar();
   1.481 +			_hScrollBar.Width = DisplayRectangle.Width;
   1.482 +			_vScrollBar.Height = DisplayRectangle.Height;
   1.483 +		}
   1.484 +
   1.485 +		private void UpdateHScrollBar()
   1.486 +		{
   1.487 +			_hScrollBar.Maximum = ContentWidth;
   1.488 +			_hScrollBar.LargeChange = Math.Max(DisplayRectangle.Width, 0);
   1.489 +			_hScrollBar.SmallChange = 5;
   1.490 +			_hScrollBar.Visible = _hScrollBar.LargeChange < _hScrollBar.Maximum;
   1.491 +			_hScrollBar.Value = Math.Min(_hScrollBar.Value, _hScrollBar.Maximum - _hScrollBar.LargeChange + 1);
   1.492 +		}
   1.493 +
   1.494 +		private void UpdateVScrollBar()
   1.495 +		{
   1.496 +			_vScrollBar.Maximum = Math.Max(RowCount - 1, 0);
   1.497 +			_vScrollBar.LargeChange = _rowLayout.PageRowCount;
   1.498 +			_vScrollBar.Visible = (RowCount > 0) && (_vScrollBar.LargeChange <= _vScrollBar.Maximum);
   1.499 +			_vScrollBar.Value = Math.Min(_vScrollBar.Value, _vScrollBar.Maximum - _vScrollBar.LargeChange + 1);
   1.500 +		}
   1.501 +
   1.502 +		protected override CreateParams CreateParams
   1.503 +		{
   1.504 +			[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
   1.505 +			get
   1.506 +			{
   1.507 +				CreateParams res = base.CreateParams;
   1.508 +				switch (BorderStyle)
   1.509 +				{
   1.510 +					case BorderStyle.FixedSingle:
   1.511 +						res.Style |= 0x800000;
   1.512 +						break;
   1.513 +					case BorderStyle.Fixed3D:
   1.514 +						res.ExStyle |= 0x200;
   1.515 +						break;
   1.516 +				}
   1.517 +				return res;
   1.518 +			}
   1.519 +		}
   1.520 +
   1.521 +		protected override void OnGotFocus(EventArgs e)
   1.522 +		{
   1.523 +			UpdateView();
   1.524 +			ChangeInput();
   1.525 +			base.OnGotFocus(e);
   1.526 +		}
   1.527 +
   1.528 +		protected override void OnFontChanged(EventArgs e)
   1.529 +		{
   1.530 +			base.OnFontChanged(e);
   1.531 +			_measureContext.Font = Font;
   1.532 +			FullUpdate();
   1.533 +		}
   1.534 +
   1.535 +		internal IEnumerable<NodeControlInfo> GetNodeControls(TreeNodeAdv node)
   1.536 +		{
   1.537 +			if (node == null)
   1.538 +				yield break;
   1.539 +			Rectangle rowRect = _rowLayout.GetRowBounds(node.Row);
   1.540 +			foreach (NodeControlInfo n in GetNodeControls(node, rowRect))
   1.541 +				yield return n;
   1.542 +		}
   1.543 +
   1.544 +		internal IEnumerable<NodeControlInfo> GetNodeControls(TreeNodeAdv node, Rectangle rowRect)
   1.545 +		{
   1.546 +			if (node == null)
   1.547 +				yield break;
   1.548 +
   1.549 +			int y = rowRect.Y;
   1.550 +			int x = (node.Level - 1) * _indent + LeftMargin;
   1.551 +			int width = 0;
   1.552 +			if (node.Row == 0 && ShiftFirstNode)
   1.553 +				x -= _indent;
   1.554 +			Rectangle rect = Rectangle.Empty;
   1.555 +
   1.556 +			if (ShowPlusMinus)
   1.557 +			{
   1.558 +				width = _plusMinus.GetActualSize(node, _measureContext).Width;
   1.559 +				rect = new Rectangle(x, y, width, rowRect.Height);
   1.560 +				if (UseColumns && Columns.Count > 0 && Columns[0].Width < rect.Right)
   1.561 +					rect.Width = Columns[0].Width - x;
   1.562 +
   1.563 +				yield return new NodeControlInfo(_plusMinus, rect, node);
   1.564 +				x += width;
   1.565 +			}
   1.566 +
   1.567 +			if (!UseColumns)
   1.568 +			{
   1.569 +				foreach (NodeControl c in NodeControls)
   1.570 +				{
   1.571 +					Size s = c.GetActualSize(node, _measureContext);
   1.572 +					if (!s.IsEmpty)
   1.573 +					{
   1.574 +						width = s.Width;
   1.575 +						rect = new Rectangle(x, y, width, rowRect.Height);
   1.576 +						x += rect.Width;
   1.577 +						yield return new NodeControlInfo(c, rect, node);
   1.578 +					}
   1.579 +				}
   1.580 +			}
   1.581 +			else
   1.582 +			{
   1.583 +				int right = 0;
   1.584 +				foreach (TreeColumn col in Columns)
   1.585 +				{
   1.586 +					if (col.IsVisible && col.Width > 0)
   1.587 +					{
   1.588 +						right += col.Width;
   1.589 +						for (int i = 0; i < NodeControls.Count; i++)
   1.590 +						{
   1.591 +							NodeControl nc = NodeControls[i];
   1.592 +							if (nc.ParentColumn == col)
   1.593 +							{
   1.594 +								Size s = nc.GetActualSize(node, _measureContext);
   1.595 +								if (!s.IsEmpty)
   1.596 +								{
   1.597 +									bool isLastControl = true;
   1.598 +									for (int k = i + 1; k < NodeControls.Count; k++)
   1.599 +										if (NodeControls[k].ParentColumn == col)
   1.600 +										{
   1.601 +											isLastControl = false;
   1.602 +											break;
   1.603 +										}
   1.604 +
   1.605 +									width = right - x;
   1.606 +									if (!isLastControl)
   1.607 +										width = s.Width;
   1.608 +									int maxWidth = Math.Max(0, right - x);
   1.609 +									rect = new Rectangle(x, y, Math.Min(maxWidth, width), rowRect.Height);
   1.610 +									x += width;
   1.611 +									yield return new NodeControlInfo(nc, rect, node);
   1.612 +								}
   1.613 +							}
   1.614 +						}
   1.615 +						x = right;
   1.616 +					}
   1.617 +				}
   1.618 +			}
   1.619 +		}
   1.620 +
   1.621 +		internal static double Dist(Point p1, Point p2)
   1.622 +		{
   1.623 +			return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));
   1.624 +		}
   1.625 +
   1.626 +		public void FullUpdate()
   1.627 +		{
   1.628 +			HideEditor();
   1.629 +			if (InvokeRequired)
   1.630 +				BeginInvoke(new MethodInvoker(UnsafeFullUpdate));
   1.631 +			else
   1.632 +				UnsafeFullUpdate();
   1.633 +		}
   1.634 +
   1.635 +		private void UnsafeFullUpdate()
   1.636 +		{
   1.637 +			_rowLayout.ClearCache();
   1.638 +			CreateRowMap();
   1.639 +			SafeUpdateScrollBars();
   1.640 +			UpdateView();
   1.641 +			_needFullUpdate = false;
   1.642 +		}
   1.643 +
   1.644 +		internal void UpdateView()
   1.645 +		{
   1.646 +			if (!_suspendUpdate)
   1.647 +				Invalidate(false);
   1.648 +		}
   1.649 +
   1.650 +		internal void UpdateHeaders()
   1.651 +		{
   1.652 +			Invalidate(new Rectangle(0, 0, Width, ColumnHeaderHeight));
   1.653 +		}
   1.654 +
   1.655 +		internal void UpdateColumns()
   1.656 +		{
   1.657 +			FullUpdate();
   1.658 +		}
   1.659 +
   1.660 +		private void CreateNodes()
   1.661 +		{
   1.662 +			Selection.Clear();
   1.663 +			SelectionStart = null;
   1.664 +			_root = new TreeNodeAdv(this, null);
   1.665 +			_root.IsExpanded = true;
   1.666 +			if (_root.Nodes.Count > 0)
   1.667 +				CurrentNode = _root.Nodes[0];
   1.668 +			else
   1.669 +				CurrentNode = null;
   1.670 +		}
   1.671 +
   1.672 +		internal void ReadChilds(TreeNodeAdv parentNode)
   1.673 +		{
   1.674 +			ReadChilds(parentNode, false);
   1.675 +		}
   1.676 +
   1.677 +		internal void ReadChilds(TreeNodeAdv parentNode, bool performFullUpdate)
   1.678 +		{
   1.679 +			if (!parentNode.IsLeaf)
   1.680 +			{
   1.681 +				parentNode.IsExpandedOnce = true;
   1.682 +				parentNode.Nodes.Clear();
   1.683 +
   1.684 +				if (Model != null)
   1.685 +				{
   1.686 +					IEnumerable items = Model.GetChildren(GetPath(parentNode));
   1.687 +					if (items != null)
   1.688 +						foreach (object obj in items)
   1.689 +						{
   1.690 +							AddNewNode(parentNode, obj, -1);
   1.691 +							if (performFullUpdate)
   1.692 +								FullUpdate();
   1.693 +						}
   1.694 +				}
   1.695 +
   1.696 +				if (parentNode.AutoExpandOnStructureChanged)
   1.697 +					parentNode.ExpandAll();
   1.698 +			}
   1.699 +		}
   1.700 +
   1.701 +		private void AddNewNode(TreeNodeAdv parent, object tag, int index)
   1.702 +		{
   1.703 +			TreeNodeAdv node = new TreeNodeAdv(this, tag);
   1.704 +			AddNode(parent, index, node);
   1.705 +		}
   1.706 +
   1.707 +		private void AddNode(TreeNodeAdv parent, int index, TreeNodeAdv node)
   1.708 +		{
   1.709 +			if (index >= 0 && index < parent.Nodes.Count)
   1.710 +				parent.Nodes.Insert(index, node);
   1.711 +			else
   1.712 +				parent.Nodes.Add(node);
   1.713 +
   1.714 +			node.IsLeaf = Model.IsLeaf(GetPath(node));
   1.715 +			if (node.IsLeaf)
   1.716 +				node.Nodes.Clear();
   1.717 +			if (!LoadOnDemand || node.IsExpandedOnce)
   1.718 +				ReadChilds(node);
   1.719 +		}
   1.720 +
   1.721 +		private struct ExpandArgs
   1.722 +		{
   1.723 +			public TreeNodeAdv Node;
   1.724 +			public bool Value;
   1.725 +			public bool IgnoreChildren;
   1.726 +		}
   1.727 +
   1.728 +		public void AbortBackgroundExpandingThreads()
   1.729 +		{
   1.730 +			_threadPool.CancelAll(true);
   1.731 +			for (int i = 0; i < _expandingNodes.Count; i++)
   1.732 +				_expandingNodes[i].IsExpandingNow = false;
   1.733 +			_expandingNodes.Clear();
   1.734 +			Invalidate();
   1.735 +		}
   1.736 +
   1.737 +		internal void SetIsExpanded(TreeNodeAdv node, bool value, bool ignoreChildren)
   1.738 +		{
   1.739 +			ExpandArgs eargs = new ExpandArgs();
   1.740 +			eargs.Node = node;
   1.741 +			eargs.Value = value;
   1.742 +			eargs.IgnoreChildren = ignoreChildren;
   1.743 +
   1.744 +			if (AsyncExpanding && LoadOnDemand && !_threadPool.IsMyThread(Thread.CurrentThread))
   1.745 +			{
   1.746 +				WaitCallback wc = delegate(object argument) { SetIsExpanded((ExpandArgs)argument); };
   1.747 +				_threadPool.QueueUserWorkItem(wc, eargs);
   1.748 +			}
   1.749 +			else
   1.750 +				SetIsExpanded(eargs);
   1.751 +		}
   1.752 +
   1.753 +		private void SetIsExpanded(ExpandArgs eargs)
   1.754 +		{
   1.755 +			bool update = !eargs.IgnoreChildren && !AsyncExpanding;
   1.756 +			if (update)
   1.757 +				BeginUpdate();
   1.758 +			try
   1.759 +			{
   1.760 +				if (IsMyNode(eargs.Node) && eargs.Node.IsExpanded != eargs.Value)
   1.761 +					SetIsExpanded(eargs.Node, eargs.Value);
   1.762 +
   1.763 +				if (!eargs.IgnoreChildren)
   1.764 +					SetIsExpandedRecursive(eargs.Node, eargs.Value);
   1.765 +			}
   1.766 +			finally
   1.767 +			{
   1.768 +				if (update)
   1.769 +					EndUpdate();
   1.770 +			}
   1.771 +		}
   1.772 +
   1.773 +		internal void SetIsExpanded(TreeNodeAdv node, bool value)
   1.774 +		{
   1.775 +			if (Root == node && !value)
   1.776 +				return; //Can't collapse root node
   1.777 +
   1.778 +			if (value)
   1.779 +			{
   1.780 +				OnExpanding(node);
   1.781 +				node.OnExpanding();
   1.782 +			}
   1.783 +			else
   1.784 +			{
   1.785 +				OnCollapsing(node);
   1.786 +				node.OnCollapsing();
   1.787 +			}
   1.788 +
   1.789 +			if (value && !node.IsExpandedOnce)
   1.790 +			{
   1.791 +				if (AsyncExpanding && LoadOnDemand)
   1.792 +				{
   1.793 +					AddExpandingNode(node);
   1.794 +					node.AssignIsExpanded(true);
   1.795 +					Invalidate();
   1.796 +				}
   1.797 +				ReadChilds(node, AsyncExpanding);
   1.798 +				RemoveExpandingNode(node);
   1.799 +			}
   1.800 +			node.AssignIsExpanded(value);
   1.801 +			SmartFullUpdate();
   1.802 +
   1.803 +			if (value)
   1.804 +			{
   1.805 +				OnExpanded(node);
   1.806 +				node.OnExpanded();
   1.807 +			}
   1.808 +			else
   1.809 +			{
   1.810 +				OnCollapsed(node);
   1.811 +				node.OnCollapsed();
   1.812 +			}
   1.813 +		}
   1.814 +
   1.815 +		private void RemoveExpandingNode(TreeNodeAdv node)
   1.816 +		{
   1.817 +			node.IsExpandingNow = false;
   1.818 +			_expandingNodes.Remove(node);
   1.819 +			if (_expandingNodes.Count <= 0)
   1.820 +				ExpandingIcon.Stop();
   1.821 +		}
   1.822 +
   1.823 +		private void AddExpandingNode(TreeNodeAdv node)
   1.824 +		{
   1.825 +			node.IsExpandingNow = true;
   1.826 +			_expandingNodes.Add(node);
   1.827 +			ExpandingIcon.Start();
   1.828 +		}
   1.829 +
   1.830 +		internal void SetIsExpandedRecursive(TreeNodeAdv root, bool value)
   1.831 +		{
   1.832 +			for (int i = 0; i < root.Nodes.Count; i++)
   1.833 +			{
   1.834 +				TreeNodeAdv node = root.Nodes[i];
   1.835 +				node.IsExpanded = value;
   1.836 +				SetIsExpandedRecursive(node, value);
   1.837 +			}
   1.838 +		}
   1.839 +
   1.840 +		private void CreateRowMap()
   1.841 +		{
   1.842 +			RowMap.Clear();
   1.843 +			int row = 0;
   1.844 +			_contentWidth = 0;
   1.845 +			foreach (TreeNodeAdv node in VisibleNodes)
   1.846 +			{
   1.847 +				node.Row = row;
   1.848 +				RowMap.Add(node);
   1.849 +				if (!UseColumns)
   1.850 +				{
   1.851 +					_contentWidth = Math.Max(_contentWidth, GetNodeWidth(node));
   1.852 +				}
   1.853 +				row++;
   1.854 +			}
   1.855 +			if (UseColumns)
   1.856 +			{
   1.857 +				_contentWidth = 0;
   1.858 +				foreach (TreeColumn col in _columns)
   1.859 +					if (col.IsVisible)
   1.860 +						_contentWidth += col.Width;
   1.861 +			}
   1.862 +		}
   1.863 +
   1.864 +		private int GetNodeWidth(TreeNodeAdv node)
   1.865 +		{
   1.866 +			if (node.RightBounds == null)
   1.867 +			{
   1.868 +				Rectangle res = GetNodeBounds(GetNodeControls(node, Rectangle.Empty));
   1.869 +				node.RightBounds = res.Right;
   1.870 +			}
   1.871 +			return node.RightBounds.Value;
   1.872 +		}
   1.873 +
   1.874 +		internal Rectangle GetNodeBounds(TreeNodeAdv node)
   1.875 +		{
   1.876 +			return GetNodeBounds(GetNodeControls(node));
   1.877 +		}
   1.878 +
   1.879 +		private Rectangle GetNodeBounds(IEnumerable<NodeControlInfo> nodeControls)
   1.880 +		{
   1.881 +			Rectangle res = Rectangle.Empty;
   1.882 +			foreach (NodeControlInfo info in nodeControls)
   1.883 +			{
   1.884 +				if (res == Rectangle.Empty)
   1.885 +					res = info.Bounds;
   1.886 +				else
   1.887 +					res = Rectangle.Union(res, info.Bounds);
   1.888 +			}
   1.889 +			return res;
   1.890 +		}
   1.891 +
   1.892 +		private void _vScrollBar_ValueChanged(object sender, EventArgs e)
   1.893 +		{
   1.894 +			FirstVisibleRow = _vScrollBar.Value;
   1.895 +		}
   1.896 +
   1.897 +		private void _hScrollBar_ValueChanged(object sender, EventArgs e)
   1.898 +		{
   1.899 +			OffsetX = _hScrollBar.Value;
   1.900 +		}
   1.901 +
   1.902 +		private void _vScrollBar_Scroll(object sender, ScrollEventArgs e)
   1.903 +		{
   1.904 +			OnScroll(e);
   1.905 +		}
   1.906 +
   1.907 +		private void _hScrollBar_Scroll(object sender, ScrollEventArgs e)
   1.908 +		{
   1.909 +			OnScroll(e);
   1.910 +		}
   1.911 +
   1.912 +		internal void SmartFullUpdate()
   1.913 +		{
   1.914 +			if (_suspendUpdate)
   1.915 +				_needFullUpdate = true;
   1.916 +			else
   1.917 +				FullUpdate();
   1.918 +		}
   1.919 +
   1.920 +		internal bool IsMyNode(TreeNodeAdv node)
   1.921 +		{
   1.922 +			if (node == null)
   1.923 +				return false;
   1.924 +
   1.925 +			if (node.Tree != this)
   1.926 +				return false;
   1.927 +
   1.928 +			while (node.Parent != null)
   1.929 +				node = node.Parent;
   1.930 +
   1.931 +			return node == _root;
   1.932 +		}
   1.933 +
   1.934 +		internal void UpdateSelection()
   1.935 +		{
   1.936 +			bool flag = false;
   1.937 +
   1.938 +			if (!IsMyNode(CurrentNode))
   1.939 +				CurrentNode = null;
   1.940 +			if (!IsMyNode(_selectionStart))
   1.941 +				_selectionStart = null;
   1.942 +
   1.943 +			for (int i = Selection.Count - 1; i >= 0; i--)
   1.944 +				if (!IsMyNode(Selection[i]))
   1.945 +				{
   1.946 +					flag = true;
   1.947 +					Selection.RemoveAt(i);
   1.948 +				}
   1.949 +
   1.950 +			if (flag)
   1.951 +				OnSelectionChanged();
   1.952 +		}
   1.953 +
   1.954 +		internal void ChangeColumnWidth(TreeColumn column)
   1.955 +		{
   1.956 +			if (!(_input is ResizeColumnState))
   1.957 +			{
   1.958 +				FullUpdate();
   1.959 +				OnColumnWidthChanged(column);
   1.960 +			}
   1.961 +		}
   1.962 +
   1.963 +		public TreeNodeAdv FindNode(TreePath path)
   1.964 +		{
   1.965 +			return FindNode(path, false);
   1.966 +		}
   1.967 +
   1.968 +		public TreeNodeAdv FindNode(TreePath path, bool readChilds)
   1.969 +		{
   1.970 +			if (path.IsEmpty())
   1.971 +				return _root;
   1.972 +			else
   1.973 +				return FindNode(_root, path, 0, readChilds);
   1.974 +		}
   1.975 +
   1.976 +		private TreeNodeAdv FindNode(TreeNodeAdv root, TreePath path, int level, bool readChilds)
   1.977 +		{
   1.978 +			if (!root.IsExpandedOnce && readChilds)
   1.979 +				ReadChilds(root);
   1.980 +
   1.981 +			for (int i = 0; i < root.Nodes.Count; i++)
   1.982 +			{
   1.983 +				TreeNodeAdv node = root.Nodes[i];
   1.984 +				if (node.Tag == path.FullPath[level])
   1.985 +				{
   1.986 +					if (level == path.FullPath.Length - 1)
   1.987 +						return node;
   1.988 +					else
   1.989 +						return FindNode(node, path, level + 1, readChilds);
   1.990 +				}
   1.991 +			}
   1.992 +			return null;
   1.993 +		}
   1.994 +
   1.995 +		public TreeNodeAdv FindNodeByTag(object tag)
   1.996 +		{
   1.997 +			return FindNodeByTag(_root, tag);
   1.998 +		}
   1.999 +
  1.1000 +		private TreeNodeAdv FindNodeByTag(TreeNodeAdv root, object tag)
  1.1001 +		{
  1.1002 +			foreach (TreeNodeAdv node in root.Nodes)
  1.1003 +			{
  1.1004 +				if (node.Tag == tag)
  1.1005 +					return node;
  1.1006 +				TreeNodeAdv res = FindNodeByTag(node, tag);
  1.1007 +				if (res != null)
  1.1008 +					return res;
  1.1009 +			}
  1.1010 +			return null;
  1.1011 +		}
  1.1012 +
  1.1013 +		public void SelectAllNodes()
  1.1014 +		{
  1.1015 +			SuspendSelectionEvent = true;
  1.1016 +			try
  1.1017 +			{
  1.1018 +				if (SelectionMode == TreeSelectionMode.MultiSameParent)
  1.1019 +				{
  1.1020 +					if (CurrentNode != null)
  1.1021 +					{
  1.1022 +						foreach (TreeNodeAdv n in CurrentNode.Parent.Nodes)
  1.1023 +							n.IsSelected = true;
  1.1024 +					}
  1.1025 +				}
  1.1026 +				else if (SelectionMode == TreeSelectionMode.Multi)
  1.1027 +				{
  1.1028 +					SelectNodes(Root.Nodes);
  1.1029 +				}
  1.1030 +			}
  1.1031 +			finally
  1.1032 +			{
  1.1033 +				SuspendSelectionEvent = false;
  1.1034 +			}
  1.1035 +		}
  1.1036 +
  1.1037 +		private void SelectNodes(Collection<TreeNodeAdv> nodes)
  1.1038 +		{
  1.1039 +			foreach (TreeNodeAdv n in nodes)
  1.1040 +			{
  1.1041 +				n.IsSelected = true;
  1.1042 +				if (n.IsExpanded)
  1.1043 +					SelectNodes(n.Nodes);
  1.1044 +			}
  1.1045 +		}
  1.1046 +
  1.1047 +		#region ModelEvents
  1.1048 +		private void BindModelEvents()
  1.1049 +		{
  1.1050 +			_model.NodesChanged += new EventHandler<TreeModelEventArgs>(_model_NodesChanged);
  1.1051 +			_model.NodesInserted += new EventHandler<TreeModelEventArgs>(_model_NodesInserted);
  1.1052 +			_model.NodesRemoved += new EventHandler<TreeModelEventArgs>(_model_NodesRemoved);
  1.1053 +			_model.StructureChanged += new EventHandler<TreePathEventArgs>(_model_StructureChanged);
  1.1054 +		}
  1.1055 +
  1.1056 +		private void UnbindModelEvents()
  1.1057 +		{
  1.1058 +			_model.NodesChanged -= new EventHandler<TreeModelEventArgs>(_model_NodesChanged);
  1.1059 +			_model.NodesInserted -= new EventHandler<TreeModelEventArgs>(_model_NodesInserted);
  1.1060 +			_model.NodesRemoved -= new EventHandler<TreeModelEventArgs>(_model_NodesRemoved);
  1.1061 +			_model.StructureChanged -= new EventHandler<TreePathEventArgs>(_model_StructureChanged);
  1.1062 +		}
  1.1063 +
  1.1064 +		private void _model_StructureChanged(object sender, TreePathEventArgs e)
  1.1065 +		{
  1.1066 +			if (e.Path == null)
  1.1067 +				throw new ArgumentNullException();
  1.1068 +
  1.1069 +			TreeNodeAdv node = FindNode(e.Path);
  1.1070 +			if (node != null)
  1.1071 +			{
  1.1072 +				if (node != Root)
  1.1073 +					node.IsLeaf = Model.IsLeaf(GetPath(node));
  1.1074 +
  1.1075 +				var list = new Dictionary<object, object>();
  1.1076 +				SaveExpandedNodes(node, list);
  1.1077 +				ReadChilds(node);
  1.1078 +				RestoreExpandedNodes(node, list);
  1.1079 +
  1.1080 +				UpdateSelection();
  1.1081 +				SmartFullUpdate();
  1.1082 +			}
  1.1083 +			//else 
  1.1084 +			//	throw new ArgumentException("Path not found");
  1.1085 +		}
  1.1086 +
  1.1087 +		private void RestoreExpandedNodes(TreeNodeAdv node, Dictionary<object, object> list)
  1.1088 +		{
  1.1089 +			if (node.Tag != null && list.ContainsKey(node.Tag))
  1.1090 +			{
  1.1091 +				node.IsExpanded = true;
  1.1092 +				foreach (var child in node.Children)
  1.1093 +					RestoreExpandedNodes(child, list);
  1.1094 +			}
  1.1095 +		}
  1.1096 +
  1.1097 +		private void SaveExpandedNodes(TreeNodeAdv node, Dictionary<object, object> list)
  1.1098 +		{
  1.1099 +			if (node.IsExpanded && node.Tag != null)
  1.1100 +			{
  1.1101 +				list.Add(node.Tag, null);
  1.1102 +				foreach (var child in node.Children)
  1.1103 +					SaveExpandedNodes(child, list);
  1.1104 +			}
  1.1105 +		}
  1.1106 +
  1.1107 +		private void _model_NodesRemoved(object sender, TreeModelEventArgs e)
  1.1108 +		{
  1.1109 +			TreeNodeAdv parent = FindNode(e.Path);
  1.1110 +			if (parent != null)
  1.1111 +			{
  1.1112 +				if (e.Indices != null)
  1.1113 +				{
  1.1114 +					List<int> list = new List<int>(e.Indices);
  1.1115 +					list.Sort();
  1.1116 +					for (int n = list.Count - 1; n >= 0; n--)
  1.1117 +					{
  1.1118 +						int index = list[n];
  1.1119 +						if (index >= 0 && index <= parent.Nodes.Count)
  1.1120 +							parent.Nodes.RemoveAt(index);
  1.1121 +						else
  1.1122 +							throw new ArgumentOutOfRangeException("Index out of range");
  1.1123 +					}
  1.1124 +				}
  1.1125 +				else
  1.1126 +				{
  1.1127 +					for (int i = parent.Nodes.Count - 1; i >= 0; i--)
  1.1128 +					{
  1.1129 +						for (int n = 0; n < e.Children.Length; n++)
  1.1130 +							if (parent.Nodes[i].Tag == e.Children[n])
  1.1131 +							{
  1.1132 +								parent.Nodes.RemoveAt(i);
  1.1133 +								break;
  1.1134 +							}
  1.1135 +					}
  1.1136 +				}
  1.1137 +			}
  1.1138 +			UpdateSelection();
  1.1139 +			SmartFullUpdate();
  1.1140 +		}
  1.1141 +
  1.1142 +		private void _model_NodesInserted(object sender, TreeModelEventArgs e)
  1.1143 +		{
  1.1144 +			if (e.Indices == null)
  1.1145 +				throw new ArgumentNullException("Indices");
  1.1146 +
  1.1147 +			TreeNodeAdv parent = FindNode(e.Path);
  1.1148 +			if (parent != null)
  1.1149 +			{
  1.1150 +				for (int i = 0; i < e.Children.Length; i++)
  1.1151 +					AddNewNode(parent, e.Children[i], e.Indices[i]);
  1.1152 +			}
  1.1153 +			SmartFullUpdate();
  1.1154 +		}
  1.1155 +
  1.1156 +		private void _model_NodesChanged(object sender, TreeModelEventArgs e)
  1.1157 +		{
  1.1158 +			TreeNodeAdv parent = FindNode(e.Path);
  1.1159 +			if (parent != null && parent.IsVisible && parent.IsExpanded)
  1.1160 +			{
  1.1161 +				if (InvokeRequired)
  1.1162 +					BeginInvoke(new UpdateContentWidthDelegate(ClearNodesSize), e, parent);
  1.1163 +				else
  1.1164 +					ClearNodesSize(e, parent);
  1.1165 +				SmartFullUpdate();
  1.1166 +			}
  1.1167 +		}
  1.1168 +
  1.1169 +		private delegate void UpdateContentWidthDelegate(TreeModelEventArgs e, TreeNodeAdv parent);
  1.1170 +		private void ClearNodesSize(TreeModelEventArgs e, TreeNodeAdv parent)
  1.1171 +		{
  1.1172 +			if (e.Indices != null)
  1.1173 +			{
  1.1174 +				foreach (int index in e.Indices)
  1.1175 +				{
  1.1176 +					if (index >= 0 && index < parent.Nodes.Count)
  1.1177 +					{
  1.1178 +						TreeNodeAdv node = parent.Nodes[index];
  1.1179 +						node.Height = node.RightBounds = null;
  1.1180 +					}
  1.1181 +					else
  1.1182 +						throw new ArgumentOutOfRangeException("Index out of range");
  1.1183 +				}
  1.1184 +			}
  1.1185 +			else
  1.1186 +			{
  1.1187 +				foreach (TreeNodeAdv node in parent.Nodes)
  1.1188 +				{
  1.1189 +					foreach (object obj in e.Children)
  1.1190 +						if (node.Tag == obj)
  1.1191 +						{
  1.1192 +							node.Height = node.RightBounds = null;
  1.1193 +						}
  1.1194 +				}
  1.1195 +			}
  1.1196 +		}
  1.1197 +		#endregion
  1.1198 +	}
  1.1199 +}