public void AutoSizeColumn(TreeColumn column)
		{
			if(!Columns.Contains(column))
				throw new ArgumentException("column");

			DrawContext context=new DrawContext();
			context.Graphics=Graphics.FromImage(new Bitmap(1, 1));
			context.Font=this.Font;
			int res=0;
			for(int row=0; row<RowCount; row++)
			{
				if(row<RowMap.Count)
				{
					int w=0;
					TreeNodeAdv node=RowMap[row];
					foreach(NodeControl nc in NodeControls)
					{
						if(nc.ParentColumn==column)
							w+=nc.GetActualSize(node, _measureContext).Width;
					}
					res=Math.Max(res, w);
				}
			}

			if(res>0)
				column.Width=res;
		}
		public AutoRowHeightLayout(TreeViewAdv treeView, int rowHeight)
		{
			_rowCache=new List<Rectangle>();
			_treeView=treeView;
			PreferredRowHeight=rowHeight;
			_measureContext=new DrawContext();
			_measureContext.Graphics=Graphics.FromImage(new Bitmap(1, 1));
		}
		public TreeViewRowDrawEventArgs(Graphics graphics, Rectangle clipRectangle, TreeNodeAdv node, DrawContext context, int row, Rectangle rowRect)
			: base(graphics, clipRectangle)
		{
			_node=node;
			_context=context;
			_row=row;
			_rowRect=rowRect;
		}
		protected override void OnPaint(PaintEventArgs e)
		{
			BeginPerformanceCount();
			PerformanceAnalyzer.Start("OnPaint");

			DrawContext context=new DrawContext();
			context.Graphics=e.Graphics;
			context.Font=this.Font;
			context.Enabled=Enabled;

			int y=0;
			int gridHeight=0;

			if(UseColumns)
			{
				DrawColumnHeaders(e.Graphics);
				y+=ColumnHeaderHeight;
				if(Columns.Count==0||e.ClipRectangle.Height<=y)
					return;
			}

			int firstRowY=_rowLayout.GetRowBounds(FirstVisibleRow).Y;
			y-=firstRowY;

			e.Graphics.ResetTransform();
			e.Graphics.TranslateTransform(-OffsetX, y);
			Rectangle displayRect=DisplayRectangle;
			for(int row=FirstVisibleRow; row<RowCount; row++)
			{
				Rectangle rowRect=_rowLayout.GetRowBounds(row);
				gridHeight+=rowRect.Height;
				if(rowRect.Y+y>displayRect.Bottom)
					break;
				else
					DrawRow(e, ref context, row, rowRect);
			}

			if((GridLineStyle&GridLineStyle.Vertical)==GridLineStyle.Vertical&&UseColumns)
				DrawVerticalGridLines(e.Graphics, firstRowY);

			if(_dropPosition.Node!=null&&DragMode&&HighlightDropPosition)
				DrawDropMark(e.Graphics);

			e.Graphics.ResetTransform();
			DrawScrollBarsBox(e.Graphics);

			if(DragMode&&_dragBitmap!=null)
				e.Graphics.DrawImage(_dragBitmap, PointToClient(MousePosition));

			PerformanceAnalyzer.Finish("OnPaint");
			EndPerformanceCount(e);
		}
		private void CreateDragBitmap(IDataObject data)
		{
			if(UseColumns||!DisplayDraggingNodes)
				return;

			TreeNodeAdv[] nodes=data.GetData(typeof(TreeNodeAdv[])) as TreeNodeAdv[];
			if(nodes!=null&&nodes.Length>0)
			{
				Rectangle rect=DisplayRectangle;
				Bitmap bitmap=new Bitmap(rect.Width, rect.Height);
				using(Graphics gr=Graphics.FromImage(bitmap))
				{
					gr.Clear(BackColor);
					DrawContext context=new DrawContext();
					context.Graphics=gr;
					context.Font=Font;
					context.Enabled=true;
					int y=0;
					int maxWidth=0;
					foreach(TreeNodeAdv node in nodes)
					{
						if(node.Tree==this)
						{
							int x=0;
							int height=_rowLayout.GetRowBounds(node.Row).Height;
							foreach(NodeControl c in NodeControls)
							{
								Size s=c.GetActualSize(node, context);
								if(!s.IsEmpty)
								{
									int width=s.Width;
									rect=new Rectangle(x, y, width, height);
									x+=(width+1);
									context.Bounds=rect;
									c.Draw(node, context);
								}
							}
							y+=height;
							maxWidth=Math.Max(maxWidth, x);
						}
					}

					if(maxWidth>0&&y>0)
					{
						_dragBitmap=new Bitmap(maxWidth, y, PixelFormat.Format32bppArgb);
						using(Graphics tgr=Graphics.FromImage(_dragBitmap))
							tgr.DrawImage(bitmap, Point.Empty);
						BitmapHelper.SetAlphaChanelValue(_dragBitmap, 150);
					}
					else
						_dragBitmap=null;
				}
			}
		}
		public void DrawNode(TreeNodeAdv node, DrawContext context)
		{
			foreach(NodeControlInfo item in GetNodeControls(node))
			{
				if(item.Bounds.Right>=OffsetX&&item.Bounds.X-OffsetX<this.Bounds.Width)// skip invisible nodes
				{
					context.Bounds=item.Bounds;
					context.Graphics.SetClip(context.Bounds);
					item.Control.Draw(node, context);
					context.Graphics.ResetClip();
				}
			}
		}
		private void DrawRow(PaintEventArgs e, ref DrawContext context, int row, Rectangle rowRect)
		{
			TreeNodeAdv node=RowMap[row];
			context.DrawSelection=DrawSelectionMode.None;
			context.CurrentEditorOwner=CurrentEditorOwner;
			if(DragMode)
			{
				if((_dropPosition.Node==node)&&_dropPosition.Position==NodePosition.Inside&&HighlightDropPosition)
					context.DrawSelection=DrawSelectionMode.Active;
			}
			else
			{
				if(node.IsSelected&&Focused)
					context.DrawSelection=DrawSelectionMode.Active;
				else if(node.IsSelected&&!Focused&&!HideSelection)
					context.DrawSelection=DrawSelectionMode.Inactive;
			}
			context.DrawFocus=Focused&&CurrentNode==node;

			OnRowDraw(e, node, context, row, rowRect);

			if(FullRowSelect)
			{
				context.DrawFocus=false;
				if(context.DrawSelection==DrawSelectionMode.Active||context.DrawSelection==DrawSelectionMode.Inactive)
				{
					Rectangle focusRect=new Rectangle(OffsetX, rowRect.Y, ClientRectangle.Width, rowRect.Height);
					if(context.DrawSelection==DrawSelectionMode.Active)
					{
						e.Graphics.FillRectangle(highlightBrush, focusRect);
						context.DrawSelection=DrawSelectionMode.FullRowSelect;
					}
					else
					{
						e.Graphics.FillRectangle(SystemBrushes.InactiveBorder, focusRect);
						context.DrawSelection=DrawSelectionMode.None;
					}
				}
			}

			if((GridLineStyle&GridLineStyle.Horizontal)==GridLineStyle.Horizontal)
				e.Graphics.DrawLine(SystemPens.InactiveBorder, 0, rowRect.Bottom, e.Graphics.ClipBounds.Right, rowRect.Bottom);

			if(ShowLines)
				DrawLines(e.Graphics, node, rowRect);

			DrawNode(node, context);
		}