關鍵點:(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; //不想覆蓋已有內容就注掉(只繪制邊框) } }