展开全部
要行或列合并,要写Paint事件哦....先算出合并所占的矩形,然后DrawString就行了。
我写了一个简单的例子,先要在Load中生成数据,再写Paint。还有一个类。
public partial class SpanEntity //这就是用来存要合并的内容、左上角点、长宽
{
public virtual string Item { get; set; }
public virtual Point XY { get; set; }
public virtual Size WH { get; set; }
}
这里开始就是Load写数据
private void Form1_Load(object sender, EventArgs e)
{
var list = new List<Object>();
list.Add(new { ID = "1", Class = "1班", Name = "张三", Score1 = 70, Score2 = 70 });
list.Add(new { ID = "1", Class = "1班", Name = "李四", Score1 = 80, Score2 = 80 });
list.Add(new { ID = "1", Class = "1班", Name = "王五", Score1 = 90, Score2 = 90 });
list.Add(new { ID = "1", Class = "2班", Name = "Tom", Score1 = 60, Score2 = 60 });
list.Add(new { ID = "1", Class = "2班", Name = "Jack", Score1 = 50, Score2 = 50 });
list.Add(new { ID = "6", Class = "2班", Name = "Jarry", Score1 = 40, Score2 = 40 });
dataGridView1.DataSource = list;
}
把第一列,就是ID进行[行]合并,同时会把第4、5列按[列]合并。Paint事件
private void dataGridView1_Paint(object sender, PaintEventArgs e)
{
List<SpanEntity> PointList = new List<SpanEntity>(); ;
string str = "";
//先来行合并
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
var row = dataGridView1.Rows[i];
var cell = row.Cells[0];
var s = cell.Value.ToString().Trim(); //取第1列
var rect = dataGridView1.GetCellDisplayRectangle(cell.ColumnIndex, cell.RowIndex, true);
if (str != s) //计算要跨的单元格的起点与终点
{
var iX = (Int32)(rect.Width);
var iY = (Int32)(rect.Height);
PointList.Add(new SpanEntity() { Item = s, XY = new Point(rect.X, rect.Y), WH = new Size(iX, iY) });
str = s;
}
else
{
//修定偏移量
var newY = PointList[PointList.Count - 1].WH;
newY.Height += (Int32)(rect.Height);
PointList[PointList.Count - 1].WH = newY;
}
} // end of for
//=====算列合并
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
var row = dataGridView1.Rows[i];
var cell1 = row.Cells[3]; //第4列与第5列合并
var cell2 = row.Cells[4];
if (cell1.Value.ToString().Trim() == cell2.Value.ToString().Trim())
{
var rect1 = dataGridView1.GetCellDisplayRectangle(cell1.ColumnIndex, cell1.RowIndex, true);
var rect2 = dataGridView1.GetCellDisplayRectangle(cell2.ColumnIndex, cell2.RowIndex, true);
//两列相同就合并了
PointList.Add(new SpanEntity() { Item = cell1.Value.ToString()
, XY = new Point(rect1.X, rect1.Y)
, WH = new Size(rect1.Width + rect2.Width, rect1.Height) });
}
}
//========画新的量
Brush backColorBrush = new SolidBrush(Color.White);
Pen gridLinePen = new Pen(this.dataGridView1.GridColor);//线色
foreach (var obj in PointList)
{
e.Graphics.FillRectangle(backColorBrush, new Rectangle(obj.XY, obj.WH));
//画右边线
e.Graphics.DrawLine(gridLinePen
, obj.XY.X + obj.WH.Width - 1 //右边线X点
, obj.XY.Y
, obj.XY.X + obj.WH.Width - 1
, obj.XY.Y + obj.WH.Height - 1);
//画下边线
e.Graphics.DrawLine(gridLinePen
, obj.XY.X //右边线X点
, obj.XY.Y + obj.WH.Height - 1
, obj.XY.X + obj.WH.Width - 1
, obj.XY.Y + obj.WH.Height - 1);
var sizeFont = e.Graphics.MeasureString(obj.Item, dataGridView1.Font); //根据第1列的字体算出value所占大小
StringFormat format = new StringFormat(); //样式
format.LineAlignment = StringAlignment.Center; // 垂直居中
format.Alignment = StringAlignment.Center; // 水平居中
RectangleF rect = new Rectangle(obj.XY, obj.WH);
e.Graphics.DrawString(obj.Item, dataGridView1.Font, Brushes.Black, rect, format);
}
}
=======截图=====
====合并后居中====,Class和 Name没居中
追问
我在paint代码加了这句:
if (e.ColumnIndex == 5)//如果是第五列
{
}
这样界面才不会卡,不然会卡。但是这样的话,例如我那一列某个值改变了,但是那线和文字位置没有改变,要给当前的那几行给予焦点才行,这是怎么回事?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询