protected override void OnMouseDown(DataGridViewCellMouseEventArgs e) { if (e.Location.X > this.InheritedStyle.Padding.Left) { base.OnMouseDown(e); } else { // Expand the node //TODO: Calculate more precise location HierarchicalGridNode node = this.OwningNode; if (node != null) { node._grid._inExpandCollapseMouseCapture = true; if (node.IsExpanded) { node.Collapse(); } else { node.Expand(); } } } }
private void UpdateChildNodes(HierarchicalGridNode node) { if (node.HasChildren) { foreach (HierarchicalGridNode childNode in node.Nodes) { childNode._grid = node._grid; this.UpdateChildNodes(childNode); } } }
internal protected virtual bool RemoveChildNode(HierarchicalGridNode node) { if ((this.IsRoot || this._isSited) && this.IsExpanded) { //We only unsite out child node if we are sited and expanded. this._grid.UnSiteNode(node); } node._grid = null; node._parent = null; return(true); }
protected override void OnMouseUp(DataGridViewCellMouseEventArgs e) { base.OnMouseUp(e); HierarchicalGridNode node = this.OwningNode; if (node != null) { node._grid._inExpandCollapseMouseCapture = false; } }
internal protected virtual void SiteNode(HierarchicalGridNode node, int index) { if (index < base.Rows.Count) { base.Rows.Insert(index, node); } else { // for the last item. base.Rows.Add(node); } }
public HierarchicalGridView() { // Control when edit occurs because edit mode shouldn't start when expanding/collapsing this.EditMode = DataGridViewEditMode.EditProgrammatically; this.RowTemplate = new HierarchicalGridNode() as DataGridViewRow; // This sample does not support adding or deleting rows by the user. this.AllowUserToAddRows = false; this.AllowUserToDeleteRows = false; this._root = new HierarchicalGridNode(this); this._root.IsRoot = true; // Ensures that all rows are added unshared by listening to the CollectionChanged event. base.Rows.CollectionChanged += delegate(object sender, System.ComponentModel.CollectionChangeEventArgs e){}; }
internal protected virtual bool InsertChildNode(int index, HierarchicalGridNode node) { node._parent = this; node._grid = this._grid; // ensure that all children of this node has their grid set if (this._grid != null) { UpdateChildNodes(node); } //TODO: do we need to use index parameter? if ((this._isSited || this.IsRoot) && this.IsExpanded) { this._grid.SiteNode(node); } return(true); }
internal protected virtual bool AddChildNode(HierarchicalGridNode node) { node._parent = this; node._grid = this._grid; // ensure that all children of this node has their grid set if (this._grid != null) { UpdateChildNodes(node); } if ((this._isSited || this.IsRoot) && this.IsExpanded && !node._isSited) { this._grid.SiteNode(node); } return(true); }
internal protected virtual bool ExpandNode(HierarchicalGridNode node) { if (!node.IsExpanded || this._virtualNodes) { ExpandingEventArgs exp = new ExpandingEventArgs(node); this.OnNodeExpanding(exp); if (!exp.Cancel) { this.LockVerticalScrollBarUpdate(true); this.SuspendLayout(); _inExpandCollapse = true; node.IsExpanded = true; //TODO Convert this to a InsertRange foreach (HierarchicalGridNode childNode in node.Nodes) { Debug.Assert(childNode.RowIndex == -1, "Row is already in the grid."); this.SiteNode(childNode); //this.BaseRows.Insert(rowIndex + 1, childRow); //TODO : remove -- just a test. //childNode.Cells[0].Value = "child"; } ExpandedEventArgs exped = new ExpandedEventArgs(node); this.OnNodeExpanded(exped); //TODO: Convert this to a specific NodeCell property _inExpandCollapse = false; this.LockVerticalScrollBarUpdate(false); this.ResumeLayout(true); this.InvalidateCell(node.Cells[0]); } return(!exp.Cancel); } else { // row is already expanded, so we didn't do anything. return(false); } }
public override object Clone() { HierarchicalGridNode r = (HierarchicalGridNode)base.Clone(); r.UniqueValue = -1; r._level = this._level; r._grid = this._grid; r._parent = this.Parent; r._imageIndex = this._imageIndex; if (r._imageIndex == -1) { r.Image = this.Image; } r.IsExpanded = this.IsExpanded; //r.treeCell = new TreeGridCell(); return(r); }
internal protected virtual void UnSiteNode(HierarchicalGridNode node) { if (node.IsSited || node.IsRoot) { // remove child rows first foreach (HierarchicalGridNode childNode in node.Nodes) { this.UnSiteNode(childNode); } // now remove this row except for the root if (!node.IsRoot) { base.Rows.Remove(node); // Row isn't sited in the grid anymore after remove. Note that we cannot // Use the RowRemoved event since we cannot map from the row index to // the index of the expandable row/node. node.UnSited(); } } }
internal protected virtual bool CollapseNode(HierarchicalGridNode node) { if (node.IsExpanded) { CollapsingEventArgs exp = new CollapsingEventArgs(node); this.OnNodeCollapsing(exp); if (!exp.Cancel) { this.LockVerticalScrollBarUpdate(true); this.SuspendLayout(); _inExpandCollapse = true; node.IsExpanded = false; foreach (HierarchicalGridNode childNode in node.Nodes) { Debug.Assert(childNode.RowIndex != -1, "Row is NOT in the grid."); this.UnSiteNode(childNode); } CollapsedEventArgs exped = new CollapsedEventArgs(node); this.OnNodeCollapsed(exped); //TODO: Convert this to a specific NodeCell property _inExpandCollapse = false; this.LockVerticalScrollBarUpdate(false); this.ResumeLayout(true); this.InvalidateCell(node.Cells[0]); } return(!exp.Cancel); } else { // row isn't expanded, so we didn't do anything. return(false); } }
public ExpandingEventArgs(HierarchicalGridNode node) : base() { this._node = node; }
internal protected virtual void SiteNode(HierarchicalGridNode node) { //TODO: Raise exception if parent node is not the root or is not sited. int rowIndex = -1; HierarchicalGridNode currentRow; node._grid = this; if (node.Parent != null && node.Parent.IsRoot == false) { // row is a child Debug.Assert(node.Parent != null && node.Parent.IsExpanded == true); if (node.Index > 0) { currentRow = node.Parent.Nodes[node.Index - 1]; } else { currentRow = node.Parent; } } else { // row is being added to the root if (node.Index > 0) { currentRow = node.Parent.Nodes[node.Index - 1]; } else { currentRow = null; } } if (currentRow != null) { while (currentRow.Level >= node.Level) { if (currentRow.RowIndex < base.Rows.Count - 1) { currentRow = base.Rows[currentRow.RowIndex + 1] as HierarchicalGridNode; Debug.Assert(currentRow != null); } else { // no more rows, site this node at the end. break; } } if (currentRow == node.Parent) { rowIndex = currentRow.RowIndex + 1; } else if (currentRow.Level < node.Level) { rowIndex = currentRow.RowIndex; } else { rowIndex = currentRow.RowIndex + 1; } } else { rowIndex = 0; } Debug.Assert(rowIndex != -1); this.SiteNode(node, rowIndex); Debug.Assert(node.IsSited); if (node.IsExpanded) { // add all child rows to display foreach (HierarchicalGridNode childNode in node.Nodes) { //TODO: could use the more efficient SiteRow with index. this.SiteNode(childNode); } } }
public HierarchicalGridNodeEventBase(HierarchicalGridNode node) { this._node = node; }
public CollapsingEventArgs(HierarchicalGridNode node) : base() { this._node = node; }
public CollapsedEventArgs(HierarchicalGridNode node) : base(node) { }
public ExpandedEventArgs(HierarchicalGridNode node) : base(node) { }
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts) { HierarchicalGridNode node = this.OwningNode; if (node == null) { return; } Image image = node.Image; if (this._imageHeight == 0 && image != null) { this.UpdateStyle(); } // paint the cell normally base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts); // TODO: Indent width needs to take image size into account Rectangle glyphRect = new Rectangle(cellBounds.X + this.GlyphMargin, cellBounds.Y, INDENT_WIDTH, cellBounds.Height - 1); int glyphHalf = glyphRect.Width / 2; //TODO: This painting code needs to be rehashed to be cleaner int level = this.Level; //TODO: Rehash this to take different Imagelayouts into account. This will speed up drawing // for images of the same size (ImageLayout.None) if (image != null) { Point pp; if (_imageHeight > cellBounds.Height) { pp = new Point(glyphRect.X + this.glyphWidth, cellBounds.Y + _imageHeightOffset); } else { pp = new Point(glyphRect.X + this.glyphWidth, (cellBounds.Height / 2 - _imageHeight / 2) + cellBounds.Y); } // Graphics container to push/pop changes. This enables us to set clipping when painting // the cell's image -- keeps it from bleeding outsize of cells. System.Drawing.Drawing2D.GraphicsContainer gc = graphics.BeginContainer(); { graphics.SetClip(cellBounds); graphics.DrawImageUnscaled(image, pp); } graphics.EndContainer(gc); } #region Paint tree lines if (node._grid.ShowLines) { using (Pen linePen = new Pen(SystemBrushes.ControlDark, 1.0f)) { linePen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; bool isLastSibling = node.IsLastSibling; bool isFirstSibling = node.IsFirstSibling; if (node.Level == 1) { graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2); } else { if (isLastSibling) { // last sibling doesn't draw the line extended below. Paint horizontal then vertical graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2); graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top, glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2); } else { // normal drawing draws extended from top to bottom. Paint horizontal then vertical graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top + cellBounds.Height / 2, glyphRect.Right, cellBounds.Top + cellBounds.Height / 2); graphics.DrawLine(linePen, glyphRect.X + 4, cellBounds.Top, glyphRect.X + 4, cellBounds.Bottom); } } } } #endregion if (node.HasChildren || node._grid.VirtualNodes) { // Paint node glyphs if (node.IsExpanded) { node._grid.rOpen.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10)); } else { node._grid.rClosed.DrawBackground(graphics, new Rectangle(glyphRect.X, glyphRect.Y + (glyphRect.Height / 2) - 4, 10, 10)); } } }