请选择 进入手机版 | 继续访问电脑版

无忧编程_ASP.NET  / C# / PHP 程序员的软件世界

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 103|回复: 0

C#控件datagridview列合并相同项居中的代码

[复制链接]

322

主题

351

帖子

1444

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1444
发表于 2018-5-8 09:12:37 | 显示全部楼层 |阅读模式
C#控件datagridview列合并相同项居中的代码
要行或列合并,要写Paint事件哦....先算出合并所占的矩形,然后DrawString就行了。
我写了一个简单的例子,先要在Load中生成数据,再写Paint。还有一个类。
[C#] 纯文本查看 复制代码
public partial class SpanEntity  //这就是用来存要合并的内容、左上角点、长宽
{
    public virtual string Item { get; set; }
 
    public virtual Point XY { get; set; }
 
    public virtual Size WH { get; set; }
}

这里开始就是Load写数据
[C#] 纯文本查看 复制代码
private void Form1_Load(object sender, EventArgs e)
{
    var list = new List();
    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事件
[C#] 纯文本查看 复制代码
private void dataGridView1_Paint(object sender, PaintEventArgs e)
{
    List PointList = new List(); ;
    string str = "";
    //先来行合并
    for (int i = 0; i < dataGridView1.Rows.Count; i++)
    {
        var row = dataGridView1.Rows;
        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;
        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)//如果是第五列
            {



这样界面才不会卡,不然会卡。但是这样的话,例如我那一列某个值改变了,但是那线和文字位置没有改变,要给当前的那几行给予焦点才行,这是怎么回事?

内容来自:https://zhidao.baidu.com/question/684851547758804932.html


windows .net(C#+MSSQL) linux(php+mysql)  
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|软件编程 ( 鄂ICP备11006601号鄂公网安备 42011102001337号 |

GMT+8, 2018-5-25 13:01 , Processed in 0.102699 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表