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 TreeViewRowDrawEventArgs(Graphics graphics, Rectangle clipRectangle, TreeNodeAdv node, DrawContext context, int row, Rectangle rowRect)
     : base(graphics, clipRectangle)
 {
     _node = node;
     _context = context;
     _row = row;
     _rowRect = rowRect;
 }
 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));
 }
        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);
        }
		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(SystemBrushes.Highlight, 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);
		}
        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 DrawIcons()
        {
            using (Graphics gr = Graphics.FromHwnd(this.Handle))
            {
                // Apply the same Graphics Transform logic as used in OnPaint.
                int y = 0;
                if (UseColumns)
                {
                    y += ColumnHeaderHeight;
                    if (Columns.Count == 0)
                        return;
                }
                int firstRowY = _rowLayout.GetRowBounds(FirstVisibleRow).Y;
                y -= firstRowY;
                gr.ResetTransform();
                gr.TranslateTransform(-OffsetX, y);

                DrawContext context = new DrawContext();
                context.Graphics = gr;
                for (int i = 0; i < _expandingNodes.Count; i++)
                {
                    foreach (NodeControlInfo item in GetNodeControls(_expandingNodes[i]))
                    {
                        if (item.Control is ExpandingIcon)
                        {
                            Rectangle bounds = item.Bounds;
                            if (item.Node.Parent == null && UseColumns)
                                bounds.Location = Point.Empty; // display root expanding icon at 0,0

                            context.Bounds = bounds;
                            item.Control.Draw(item.Node, context);
                        }
                    }
                }
            }
        }
        public TreeViewAdv()
        {
            InitializeComponent();
            SetStyle(ControlStyles.AllPaintingInWmPaint
                | ControlStyles.UserPaint
                | ControlStyles.OptimizedDoubleBuffer
                | ControlStyles.ResizeRedraw
                | ControlStyles.Selectable,
                true);


            if (Application.RenderWithVisualStyles)
                _columnHeaderHeight = 20;
            else
                _columnHeaderHeight = 17;

            ////BorderStyle = BorderStyle.Fixed3D;
            _hScrollBar.Height = SystemInformation.HorizontalScrollBarHeight;
            _vScrollBar.Width = SystemInformation.VerticalScrollBarWidth;
            _rowLayout = new FixedRowHeightLayout(this, RowHeight);
            _rowMap = new List<TreeNodeAdv>();
            _selection = new List<TreeNodeAdv>();
            _readonlySelection = new ReadOnlyCollection<TreeNodeAdv>(_selection);
            _columns = new TreeColumnCollection(this);
            _toolTip = new ToolTip();

            _measureContext = new DrawContext();
            _measureContext.Font = Font;
            _measureContext.Graphics = Graphics.FromImage(new Bitmap(1, 1));

            Input = new NormalInputState(this);
            _search = new IncrementalSearch(this);
            CreateNodes();
            CreatePens();

            ArrangeControls();

            _plusMinus = new NodePlusMinus();
            _controls = new NodeControlsCollection(this);

            Font = _font;
            ExpandingIcon.IconChanged += ExpandingIconChanged;
        }
 protected virtual void OnRowDraw(PaintEventArgs e, TreeNodeAdv node, DrawContext context, int row, Rectangle rowRect)
 {
     if (RowDraw != null)
     {
         TreeViewRowDrawEventArgs args = new TreeViewRowDrawEventArgs(e.Graphics, e.ClipRectangle, node, context, row, rowRect);
         RowDraw(this, args);
     }
 }
		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;
				}
			}
		}