예제 #1
0
        internal protected virtual void UnSiteNode(TreeDataGridViewRow node)
        {
            if (node.IsSited || node.IsRoot)
            {
                // remove child rows first
                foreach (TreeDataGridViewRow childNode in node.Nodes)
                {
                    this.UnSiteNode(childNode);

                    childNode.Grid  = null;
                    childNode.Owner = null;
                    childNode.Index = -1;
                }

                // 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();
                }
            }
        }
예제 #2
0
 protected override void OnMouseDown(DataGridViewCellMouseEventArgs e)
 {
     if (e.Location.X > InheritedStyle.Padding.Left)
     {
         base.OnMouseDown(e);
     }
     else
     {
         // Expand the node
         //TODO: Calculate more precise location
         TreeDataGridViewRow node = OwningNode;
         if (node != null)
         {
             node.Grid._inExpandCollapseMouseCapture = true;
             if (node.IsExpanded)
             {
                 node.Collapse();
             }
             else
             {
                 node.Expand();
             }
         }
     }
 }
예제 #3
0
 private void UpdateChildNodes(TreeDataGridViewRow node)
 {
     if (node.HasChildren)
     {
         foreach (TreeDataGridViewRow childNode in node.Nodes)
         {
             childNode.Grid = node.Grid;
             UpdateChildNodes(childNode);
         }
     }
 }
예제 #4
0
        protected override void OnMouseUp(DataGridViewCellMouseEventArgs e)
        {
            base.OnMouseUp(e);

            TreeDataGridViewRow node = OwningNode;

            if (node != null)
            {
                node.Grid._inExpandCollapseMouseCapture = false;
            }
        }
예제 #5
0
 internal protected virtual void RemoveChildNode(TreeDataGridViewRow node)
 {
     if ((IsRoot || _isSited) && IsExpanded)
     {
         //We only unsite out child node if we are sited and expanded.
         Grid.UnSiteNode(node);
     }
     node.Grid    = null;
     node.Owner   = null;
     node.Index   = -1;
     node._parent = null;
 }
예제 #6
0
 internal protected virtual void SiteNode(TreeDataGridViewRow node, int index)
 {
     if (index < base.Rows.Count)
     {
         base.Rows.Insert(index, node);
     }
     else
     {
         // for the last item.
         base.Rows.Add(node);
     }
 }
예제 #7
0
        /// <summary>
        ///
        /// </summary>
        public TreeDataGridView()
        {
            _groups = new DataGridViewGroupCollection(this);
            // Control when edit occurs because edit mode shouldn't start when expanding/collapsing
            //this.EditMode = DataGridViewEditMode.EditProgrammatically;
            RowTemplate = new TreeDataGridViewRow();
            // This sample does not support adding or deleting rows by the user.
            AllowUserToAddRows    = false;
            AllowUserToDeleteRows = false;
            _root        = new TreeDataGridViewRow(this);
            _root.IsRoot = true;

            // Ensures that all rows are added unshared by listening to the CollectionChanged event.
            base.Rows.CollectionChanged += delegate {};
        }
예제 #8
0
        internal protected virtual void AddChildNode(TreeDataGridViewRow node)
        {
            node._parent = this;
            node.Grid    = Grid;

            // ensure that all children of this node has their grid set
            if (Grid != null)
            {
                UpdateChildNodes(node);
            }

            if ((_isSited || IsRoot) && IsExpanded && !node._isSited)
            {
                Grid.SiteNode(node);
            }
        }
예제 #9
0
        internal protected virtual void InsertChildNode(int index, TreeDataGridViewRow node)
        {
            node._parent = this;
            node.Grid    = Grid;

            // ensure that all children of this node has their grid set
            if (Grid != null)
            {
                UpdateChildNodes(node);
            }

            //TODO: do we need to use index parameter?
            if ((_isSited || IsRoot) && IsExpanded)
            {
                Grid.SiteNode(node);
            }
        }
예제 #10
0
        internal protected virtual bool ExpandNode(TreeDataGridViewRow 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 (TreeDataGridViewRow 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);
            }
        }
예제 #11
0
        //protected override void OnCellDoubleClick(DataGridViewCellEventArgs e)
        //{
        //    if (e.RowIndex >= 0)
        //    {
        //        TreeDataGridViewRow row = base.Rows[e.RowIndex] as TreeDataGridViewRow;
        //        if (row != null && row.IsGroupRow)
        //        {
        //            row.Grid._inExpandCollapseMouseCapture = true;
        //            if (row.IsExpanded)
        //                CollapseNode(row);
        //            else
        //                ExpandNode(row);
        //        }
        //    }
        //    base.OnCellClick(e);
        //}

        protected override void OnCellClick(DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0)
            {
                TreeDataGridViewRow row = base.Rows[e.RowIndex] as TreeDataGridViewRow;
                if (row != null && row.IsGroupRow)
                {
                    row.Grid._inExpandCollapseMouseCapture = true;
                    if (row.IsExpanded)
                    {
                        CollapseNode(row);
                    }
                    else
                    {
                        ExpandNode(row);
                    }
                }
            }
            base.OnCellClick(e);
        }
예제 #12
0
        public override object Clone()
        {
            TreeDataGridViewRow r = (TreeDataGridViewRow)base.Clone();

            if (r == null)
            {
                return(null);
            }

            r._level  = _level;
            r.Grid    = Grid;
            r._parent = Parent;

            r._imageIndex = _imageIndex;
            if (r._imageIndex == -1)
            {
                r.Image = Image;
            }
            r.IsExpanded = IsExpanded;

            return(r);
        }
예제 #13
0
        internal protected virtual bool CollapseNode(TreeDataGridViewRow 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 (TreeDataGridViewRow 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);
            }
        }
예제 #14
0
        internal protected virtual void SiteNode(TreeDataGridViewRow node)
        {
            //TODO: Raise exception if parent node is not the root or is not sited.
            int rowIndex = -1;
            TreeDataGridViewRow 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 TreeDataGridViewRow;
                        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 (TreeDataGridViewRow childNode in node.Nodes)
                {
                    //TODO: could use the more efficient SiteRow with index.
                    this.SiteNode(childNode);
                }
            }
        }
예제 #15
0
        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)
        {
            TreeDataGridViewRow node = OwningNode;

            if (node == null)
            {
                return;
            }

            Image image = node.Image;

            if (_imageHeight == 0 && image != null)
            {
                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 + GlyphMargin, cellBounds.Y, IndentWidth, cellBounds.Height - 1);
            int       glyphHalf = glyphRect.Width / 2;

            //TODO: This painting code needs to be rehashed to be cleaner
            int level = 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 + _glyphWidth, cellBounds.Y + _imageHeightOffset);
                }
                else
                {
                    pp = new Point(glyphRect.X + _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);
            }

            // 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)
                    {
                        // the Root nodes display their lines differently
                        if (isFirstSibling && isLastSibling)
                        {
                            // only node, both first and last. Just draw horizontal line
                            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 if (isFirstSibling)
                        {
                            // first sibling doesn't draw the line extended above. 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 + cellBounds.Height / 2, glyphRect.X + 4, cellBounds.Bottom);
                        }
                        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);
                        }
                    }
                    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);
                        }

                        // paint lines of previous levels to the root
                        TreeDataGridViewRow previousNode = node.Parent;
                        int horizontalStop = (glyphRect.X + 4) - IndentWidth;

                        while (!previousNode.IsRoot)
                        {
                            if (previousNode.HasChildren && !previousNode.IsLastSibling)
                            {
                                // paint vertical line
                                graphics.DrawLine(linePen, horizontalStop, cellBounds.Top, horizontalStop, cellBounds.Bottom);
                            }
                            previousNode   = previousNode.Parent;
                            horizontalStop = horizontalStop - IndentWidth;
                        }
                    }
                }
            }

            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));
                }
            }
        }