修改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);
gridview不显示
//下边缘的线
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;  //不想覆盖已有内容就注掉(只绘制边框)
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。