修改TreeList單元格格式(實現類似單元格合並效果)


關鍵點:(1)TreeList中顯示的單元格默認不顯示上、下、左、右邊框,顯示的是TreeList自身的行橫邊框、列縱邊框,具體對應TreeList屬性中OptionView項下的ShowVertLines、ShowHorzLines兩項,將其對應默認值由默認False改為True即可去除行橫邊框、列縱邊框,然后設置怎樣的單元格格式顯示什么樣的單元格格式;

    (2)在*_CustomDrawNodeCell中修改函數,而不是*_NodeCellStyle中修改,另外需要注意,前者在后者前運行,因此后者中的修改會覆蓋掉前者中的修改。

    (3)繪制TreeList單元格網線時,自動會覆蓋掉單元格的所有邊框,這與WinForm中只需繪制右、下,不需要繪制左上邊框不同。

  

    (4)如果只想匯總Treelist單元格邊框,則不需要設置e.Hander = true;而如果想重繪單元格值或填充顏色則必須設置e.Hander = true;並且其值域不同,重繪的區域不同,即可以針對性重繪。

效果圖如下:

舉例:

(1)具體實現相關代碼如下:

 

        private void tlPublic_CustomDrawNodeCell(object sender, DevExpress.XtraTreeList.CustomDrawNodeCellEventArgs e)
        {
            DataRow dr = e.Node.Tag as DataRow;
            if (dr != null)
            {
                Brush grid = new SolidBrush(Color.LightGray);//Color.Gray
                Pen gridPen = new Pen(grid);

                if (dr["PublicId"].ToString() == "-2")
                {
                    //e.Appearance.ForeColor = TrueLore.PBTool.BaseUI.DataGridViewComponent.GridViewSumRowFontColor;
                    e.Appearance.Font = new Font(this.Font, FontStyle.Bold);
                }
                else if (e.Node.HasChildren)
                {
                    Color parentCellBackColor = TrueLore.PBTool.BaseUI.DataGridViewComponent.TreeGridViewBidFileRowBackColor;
                    e.Cache.FillRectangle(parentCellBackColor,e.Bounds);
                    ////繪制值
                    e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y, e.Bounds.X + e.Bounds.Width, e.Bounds.Y);
                    e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                }
                else
                {
                    #region TreeList實現類似單元格合並的效果
                    //現在屬性中OptionView項下將ShowHorzlines設置為True
                    //當繪制TreeList單元格時會覆蓋掉單元格的上下左右邊框,因為TreeList的列縱線被設置為顯示,行橫線被設置為不顯示,所以只需繪制上下線即可。

                    bool isMergeCell = false;
                    string cellCaption = string.Empty;
                    foreach (string caption in colsHeaderText_H)
                    {
                        if (this.tlPublic.Columns[e.Column.AbsoluteIndex].Caption == caption) 
                        {
                            isMergeCell = true;
                            cellCaption = caption;
                            break;
                        }
                    }
                        //縱向合並
                    if (isMergeCell == true)   //this.tlPublic.Columns[e.Column.AbsoluteIndex].Caption == caption) //&& e.Node.NextNode != null
                        {
                            Brush cellBackBrush = new System.Drawing.SolidBrush(e.Appearance.BackColor);
                            if (e.Node.NextNode == null)
                            {
                                //下邊緣的線
                                e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                            }
                            else if (e.Node.GetDisplayText(e.Column.AbsoluteIndex) != e.Node.NextNode.GetDisplayText(e.Column.AbsoluteIndex))
                            {
                                //下邊緣的線
                                e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                            }
                            else
                            {
                                e.Graphics.FillRectangle(cellBackBrush, e.Bounds);
                                e.Handled = true;  //顯示重繪(放置位置即值域不同,顯示重繪的區域不同)
                            }
                            //首子節點繪制上邊框,之所以放在代碼最后是因為放在前面可能在單元格填充時覆蓋掉
                            if (e.Node == e.Node.ParentNode.FirstNode)
                            {
                                e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y, e.Bounds.X + e.Bounds.Width, e.Bounds.Y);
                            }
                        }
                        //非合並列
                        else
                        {
                            //當繪制TreeList單元格時會覆蓋掉單元格的上下左右邊框,因為TreeList的列縱線被設置為顯示,行橫線被設置為不顯示,所以只需繪制上下線即可。
                            e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y, e.Bounds.X + e.Bounds.Width, e.Bounds.Y);
                            e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                        }
                    #endregion
                }
            }

        }

 

 多加代碼:

(2)具體實現相關代碼如下:

        //需要(行、列)合並的所有列標題名
        List<String> colsHeaderText_H = new List<String>();

        private void InitFormatColumns()
        {
            colsHeaderText_H.Add("量化合計");
            colsHeaderText_H.Add("投標報價");
            colsHeaderText_H.Add("評標價");
        }

        private void tlPublic_CustomDrawNodeCell(object sender, DevExpress.XtraTreeList.CustomDrawNodeCellEventArgs e)
        {
            DataRow dr = e.Node.Tag as DataRow;
            if (dr != null)
            {
                Brush gridBrush = new SolidBrush(Color.Pink);
                Brush grid = new SolidBrush(Color.Gray);
                Pen gridPen = new Pen(grid);

                ////e.Graphics.FillRectangle(gridBrush, e.Bounds);
                //e.Cache.DrawRectangle(gridPen, e.Bounds);
                //下邊緣的線
                //e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                ////繪制值
                //e.Graphics.DrawString(e.Node.GetDisplayText(e.Column.AbsoluteIndex), e.Appearance.Font,
                //        Brushes.Crimson, e.Bounds.X + 2, e.Bounds.Y + 2, StringFormat.GenericDefault);

                if (dr["PublicId"].ToString() == "-2")
                {
                    e.Appearance.ForeColor = TrueLore.PBTool.BaseUI.DataGridViewComponent.GridViewSumRowFontColor;
                    e.Appearance.Font = new Font(this.Font, FontStyle.Bold);

                    //e.Graphics.FillRectangle(gridBrush, e.Bounds);
                    //e.Cache.DrawRectangle(gridPen,e.Bounds);
                    //下邊緣的線
                    //e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                    
                    ////繪制值
                    //e.Graphics.DrawString(e.Node.GetDisplayText(e.Column.AbsoluteIndex), e.Appearance.Font,
                    //        Brushes.Crimson, e.Bounds.X + 2, e.Bounds.Y + 2, StringFormat.GenericDefault);
                }
                else if (e.Node.HasChildren)
                {
                    //e.Appearance.BackColor = TrueLore.PBTool.BaseUI.DataGridViewComponent.TreeGridViewParentRowBackColor;
                    Color parentCellBackColor = TrueLore.PBTool.BaseUI.DataGridViewComponent.TreeGridViewParentRowBackColor;
                    //e.Cache.DrawRectangle(gridPen, e.Bounds);
                    e.Cache.FillRectangle(parentCellBackColor,e.Bounds);
                    ////繪制值
                    e.Graphics.DrawString(e.Node.GetDisplayText(e.Column.AbsoluteIndex), e.Appearance.Font,
                            Brushes.Crimson, e.Bounds.X + 2, e.Bounds.Y + 2, StringFormat.GenericDefault);//下邊緣的線
                    e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                    
                    //e.Handled = true;
                    
                }
                else
                {
                    #region 注釋代碼
                    //string tmpCaption = e.Column.Caption;
                    //if ("量化合計" == tmpCaption || "投標報價" == tmpCaption || "評標價" == tmpCaption)
                    //{
                    //    e.Appearance.BorderColor = e.Appearance.BackColor;
                    //    e.Handled = true;
                    //}
                    //e.Node.TreeList.RefreshCell(e.Node, e.Column);
                    //e.Cache.DrawRectangle();
                    #endregion

                    #region TreeList實現類似單元格合並的效果
                    //現在屬性中OptionView項下將ShowHorzlines設置為True
                    //當繪制TreeList單元格時會覆蓋掉單元格的上下左右邊框,因為TreeList的列縱線被設置為顯示,行橫線被設置為不顯示,所以只需繪制上下線即可。

                    bool isMergeCell = false;
                    string cellCaption = string.Empty;
                    foreach (string caption in colsHeaderText_H)
                    {
                        if (this.tlPublic.Columns[e.Column.AbsoluteIndex].Caption == caption) 
                        {
                            isMergeCell = true;
                            cellCaption = caption;
                            break;
                        }
                    }
                        //縱向合並
                    if (isMergeCell == true)   //this.tlPublic.Columns[e.Column.AbsoluteIndex].Caption == caption) //&& e.Node.NextNode != null
                        {
                            Brush cellBackBrush = new System.Drawing.SolidBrush(e.Appearance.BackColor);

                            //若與下一單元格值不同
                            //if (e.CellValue.ToString() != e.Node.NextNode.GetDisplayText(e.Column.AbsoluteIndex))
                            if (e.Node.NextNode == null)
                            {
                                //e.Cache.DrawRectangle(gridPen, e.Bounds);
                                e.Graphics.FillRectangle(cellBackBrush, e.Bounds);
                                //e.Appearance.FillRectangle(e.Cache, e.Bounds);
                                //下邊緣的線
                                e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                                //繪制值
                                e.Graphics.DrawString(e.Node.GetDisplayText(e.Column.AbsoluteIndex), e.Appearance.Font,
                                        Brushes.Crimson, e.Bounds.X + 2, e.Bounds.Y + 2, StringFormat.GenericDefault);
                            }
                            else if (e.Node.GetDisplayText(e.Column.AbsoluteIndex) != e.Node.NextNode.GetDisplayText(e.Column.AbsoluteIndex))
                            {
                                //e.Cache.DrawRectangle(gridPen, e.Bounds);
                                e.Graphics.FillRectangle(cellBackBrush, e.Bounds);
                                //e.Appearance.FillRectangle(e.Cache, e.Bounds);
                                //下邊緣的線
                                //e.Graphics.DrawLine(gridPen, e.Bounds.Left, e.Bounds.Bottom - 1, e.Bounds.Right, e.Bounds.Bottom);
                                //e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                                //繪制值
                                e.Graphics.DrawString(e.Node.GetDisplayText(e.Column.AbsoluteIndex), e.Appearance.Font,
                                        Brushes.Crimson, e.Bounds.X + 2, e.Bounds.Y + 2, StringFormat.GenericDefault);
                            }
                            else
                            {
                                //e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                                //e.Appearance.FillRectangle(e.Cache, e.Bounds);
                                e.Graphics.FillRectangle(cellBackBrush, e.Bounds);
                            }

                            //break;
                        }
                        //非合並列
                        else
                        {
                            //e.Cache.DrawRectangle(gridPen, e.Bounds); 
                            //當繪制TreeList單元格時會覆蓋掉單元格的上下左右邊框,因為TreeList的列縱線被設置為顯示,行橫線被設置為不顯示,所以只需繪制上下線即可。
                            e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y, e.Bounds.X + e.Bounds.Width, e.Bounds.Y);
                            //繪制值
                            e.Graphics.DrawString(e.Node.GetDisplayText(e.Column.AbsoluteIndex), e.Appearance.Font,
                                    Brushes.Crimson, e.Bounds.X + 2, e.Bounds.Y + 2, StringFormat.GenericDefault);
                            //e.Handled = true;
                            ////下邊緣的線
                            e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                           
                        }


                        ////設置處理事件完成(關鍵點),只有設置為ture,才能顯示出想要的結果。
                        //e.Handled = true;
                    #endregion

                    //}
                }
                

                //設置處理事件完成(關鍵點),只有設置為ture,才能顯示出想要的結果。
                e.Handled = true;
                          
            }

        }
        #endregion


        private void tlPublic_NodeCellStyle(object sender, DevExpress.XtraTreeList.GetCustomNodeCellStyleEventArgs e)
        {
            //string tmpCaption = e.Column.Caption;
            //if ("量化合計" == tmpCaption || "投標報價" == tmpCaption || "評標價" == tmpCaption)
            //{
            //    e.Appearance.BorderColor = e.Appearance.BackColor;
            //    e.Appearance.ForeColor = Color.Red;
            //    e.Node.TreeList.OptionsView.ShowFocusedFrame = false;
            //e.Column.AppearanceCell.Options.UseBorderColor = true;
            //e.Column.AppearanceCell.BorderColor = Color.DeepPink;
            //}
            //e.Appearance.BackColor = TrueLore.PBTool.BaseUI.DataGridViewComponent.TreeGridViewParentRowBackColor;
        }

 

(3)不想覆蓋已有單元格內容(選擇性覆蓋):首選將數節點的縱向邊框去掉,再則添加事件及代碼如下:

        private void tlcBidEvalationPrice_CustomDrawNodeCell(object sender, DevExpress.XtraTreeList.CustomDrawNodeCellEventArgs e)
        {
           if (e.Node == null)
            {
                return;
            }

            DataRow dr = e.Node.Tag as DataRow;
            
                
           if (dr != null)
            {
                Brush grid = new SolidBrush(Color.LightGray);       //Color.Gray
                Pen gridPen = new Pen(grid);
                if (dr["PublicId"].ToString() == "-1")
                {
                    Color parentCellBackColor = TrueLore.PBTool.BaseUI.DataGridViewComponent.TreeGridViewBidFileRowBackColor;
                    e.Cache.FillRectangle(parentCellBackColor, e.Bounds);
                    e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y, e.Bounds.X + e.Bounds.Width, e.Bounds.Y);
                    
                    e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                }
                else if (dr["PublicId"].ToString() == "-2")
                {
                    //Color sumRowBackColor = TrueLore.PBTool.BaseUI.DataGridViewComponent.GridViewSumRowBackColor;
                    //e.Cache.FillRectangle(sumRowBackColor, e.Bounds);
                    //當繪制TreeList單元格時會覆蓋掉單元格的上下左右邊框,因為TreeList的列縱線被設置為顯示,行橫線被設置為不顯示,所以只需繪制上下線即可。
                    e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y, e.Bounds.X + e.Bounds.Width, e.Bounds.Y);
                    
                    //下邊緣的線
                    e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                }
                else
                {
                    #region TreeList實現類似單元格合並的效果
                    //現在屬性中OptionView項下將ShowHorzlines設置為True
                    //當繪制TreeList單元格時會覆蓋掉單元格的上下左右邊框,因為TreeList的列縱線被設置為顯示,行橫線被設置為不顯示,所以只需繪制上下線即可。

                    bool isMergeCell = false;
                    string cellCaption = string.Empty;
                    foreach (string caption in colsHeaderText_H)
                    {
                        if (this.tlcBidEvalationPrice.Columns[e.Column.AbsoluteIndex].Caption == caption)
                        {
                            isMergeCell = true;
                            cellCaption = caption;
                            break;
                        }
                    }
                    //縱向合並
                    if (isMergeCell == true)   
                    {
                        Brush cellBackBrush = new System.Drawing.SolidBrush(e.Appearance.BackColor);

                        //若與下一單元格值不同
                        if (e.Node.NextNode == null )//|| e.Node.NextNode.NextNode == null
                        {
                            e.Graphics.FillRectangle(cellBackBrush, e.Bounds);
                            //當繪制TreeList單元格時會覆蓋掉單元格的上下左右邊框,因為TreeList的列縱線被設置為顯示,行橫線被設置為不顯示,所以只需繪制上下線即可。
                            e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y, e.Bounds.X + e.Bounds.Width, e.Bounds.Y);
                            //下邊緣的線
                            e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                            //繪制值
                            e.Graphics.DrawString(e.Node.GetDisplayText(e.Column.AbsoluteIndex), e.Appearance.Font,
                                    Brushes.Black, e.Bounds.X, e.Bounds.Y, StringFormat.GenericTypographic);
                        }
                        else if (e.Node.GetDisplayText(e.Column.AbsoluteIndex) != e.Node.NextNode.GetDisplayText(e.Column.AbsoluteIndex))
                        {
                            e.Graphics.FillRectangle(cellBackBrush, e.Bounds);
                        }
                        else
                        {
                            e.Graphics.FillRectangle(cellBackBrush, e.Bounds);
                        }
                    }
                    //非合並列
                    else
                    {
                        //當繪制TreeList單元格時會覆蓋掉單元格的上下左右邊框,因為TreeList的列縱線被設置為顯示,行橫線被設置為不顯示,所以只需繪制上下線即可。
                        e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y, e.Bounds.X + e.Bounds.Width, e.Bounds.Y);
                       
                        //下邊緣的線
                        e.Graphics.DrawLine(gridPen, e.Bounds.X, e.Bounds.Y + e.Bounds.Height, e.Bounds.X + e.Bounds.Width, e.Bounds.Y + e.Bounds.Height);
                    }
                    #endregion

                }

                //設置處理事件完成(關鍵點),只有設置為ture,才能顯示出想要的結果。
                //e.Handled = true;		//不想覆蓋已有內容就注掉(只繪制邊框)

            }

        }

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM