Devexpress Grid 自定义合并单元格,横向或纵向合并
前言
为了合并单元格我查了很多资料,大多数合并单元格的实现都是只能纵向合并,不能横向合并。或者是有的文章设置了vip可见(我没vip不要喷我啊大家),当然设置文章收费也无可厚非。但是秉持互联网是需要有共享精神的理念。所以我自己实现了以下方法,实现单元格的横向合并,供小伙伴们一起参考吧
gridView1.OptionsView.AllowCellMerge = true 开启这个属性,表格会自动合并相同值得单元格,但是是纵向合并的,不能横向合并。gridView1.CellMerge这个事件也可以控制单元格的合并,但是也是纵向的,不能横向合并。所以使用 gridView1.CustomDrawCell 这个事件来自定义绘制合并的单元格。
效果如图,合并了中间的两行两列
代码
public Form1()
{
InitializeComponent();
//this.gridView1.OptionsView.AllowCellMerge = true; //开启这个属性会自动合并相同值得单元格,纵向的,不能横向合并
//this.gridView1.CellMerge += new DevExpress.XtraGrid.Views.Grid.CellMergeEventHandler(gridView1_CellMerge); //这个事件可以结合 this.gridView1.OptionsView.AllowCellMerge = true; 控制纵向的合并--还是不能横向合并
this.gridView1.CustomDrawCell += new DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventHandler(gridView1_CustomDrawCell); //自己绘制单元格,实现单元格合并
}
private void Form1_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("班级");
dt.Columns.Add("姓名");
dt.Rows.Add("一班", "AA");
dt.Rows.Add("一班", "BB");
dt.Rows.Add("二班", "CC");
dt.Rows.Add("二班", "DD");
dt.Rows.Add("三班", "EE");
dt.Rows.Add("三班", "FF");
this.gridControl1.DataSource = dt;
}
void gridView1_CustomDrawCell(object sender, DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventArgs e)
{
//这4个参数可以由外部输入
int rowIndex = 2; //起始单元格所在行
int colIndex = 0; //起始单元格所在列
int colCount = 2; //向右总共合并几列(值为 0 或 1 则不合并)
int rowCount = 2; //向下总共合并几行(值为 0 或 1 则不合并)
if (rowIndex < 0 || colIndex < 0) //超出实际表格范围
return;
int lastRowIndex = rowIndex + rowCount - 1; //最后一个单元格所在行
int lastColIndex = colIndex + colCount - 1; //最后一个单元格所在列
if (lastRowIndex > this.gridView1.RowCount - 1) //超出实际表格范围
lastRowIndex = this.gridView1.RowCount - 1;
if (lastColIndex > this.gridView1.Columns.Count - 1)
lastColIndex = this.gridView1.Columns.Count - 1;
int currentRowIndex = e.RowHandle; //当前单元格行索引
int currentColIndex = e.Column.VisibleIndex; //当前单元格列索引
//当前单元格在需要合并的范围之类
if (rowIndex <= currentRowIndex && currentRowIndex <= lastRowIndex && colIndex <= currentColIndex && currentColIndex <= lastColIndex)
{
GridViewInfo vi = (GridViewInfo)this.gridView1.GetViewInfo(); //GetViewInfo()这个方法VS编辑器不能直接"点"出来。但实际上存在的,可以调用
GridCellInfo ci1 = vi.GetGridCellInfo(rowIndex, colIndex); //起始单元格
GridCellInfo ci2 = vi.GetGridCellInfo(lastRowIndex, lastColIndex); //结尾单元格
Rectangle newR = Rectangle.Union(ci1.Bounds, ci2.Bounds); //合并的区域大小
//ci1.ViewInfo.Bounds = newR;
//ci1.Bounds = newR;
//ci1.CellValueRect = newR;
GridCellInfo ci3 = vi.GetGridCellInfo(currentRowIndex, currentColIndex); //当前单元格
ci3.ViewInfo.Bounds = newR;
ci3.Bounds = newR;
ci3.CellValueRect = newR;
//取消合并区域中每个单元格的边框
IndentInfoCollection lines = (e.Cell as GridCellInfo).RowInfo.Lines; //该单元格所在的行中的所有边框线
foreach (IndentInfo currentLine in lines)
{
if (newR.X <= currentLine.Bounds.X && currentLine.Bounds.X < newR.X + newR.Width && newR.Y <= currentLine.Bounds.Y && currentLine.Bounds.Y < newR.Y + newR.Height)
{
currentLine.OffsetContent(-currentLine.Bounds.X, -currentLine.Bounds.Y); //直接偏移到表格边界(即这个边框线不显示了)
}
}
string text = this.gridView1.GetRowCellValue(rowIndex, this.gridView1.Columns[colIndex]).ToString(); //起始单元格的值
e.Appearance.DrawBackground(e.Cache, newR); //绘制背景区域
e.DisplayText = text; //当前单元格显示的文本显示为第一个起始单元格的文本
e.Appearance.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center; //合并区域文本居中
e.Appearance.DrawString(e.Cache, e.DisplayText, newR); //绘制文本
e.Handled = true;
}
}