文本溢出用于DataGridView的自定义单元绘画 [英] Text overflows for custom cell painting of DataGridView

查看:81
本文介绍了文本溢出用于DataGridView的自定义单元绘画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的细胞绘画方法

DataGridView grid = (DataGridView)sender;

        if (e.RowIndex == -1 || e.ColumnIndex == -1) { return; }
        if ((grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value == null)) return;
        Brush gridBrush = new SolidBrush(GridList[0].GridColor),backColorBrush = new SolidBrush(e.CellStyle.BackColor);

        Pen gridLinePen = new Pen(gridBrush);

        // Erase the cell.
        e.Graphics.FillRectangle(backColorBrush, e.CellBounds);

        // Draw the grid lines (only the right and bottom lines;
        // DataGridView takes care of the others).
        e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left,e.CellBounds.Bottom - 1, e.CellBounds.Right - 1,e.CellBounds.Bottom - 1);
        e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1,e.CellBounds.Top, e.CellBounds.Right - 1,e.CellBounds.Bottom);
        // Draw the text content of the cell, ignoring alignment.
        if (e.Value != null)
        {

            Brush brush = new SolidBrush(Color.Red);
            Brush brush1 = new SolidBrush(Color.Black);
            String s = (String)e.Value;

            System.Drawing.Rectangle rect = e.CellBounds;
            List<int> pos = null;
            if (grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Tag!=null){
                pos = (List<int>)grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Tag;
            }

            String[] arr = s.Split('\n');
            SizeF stringSize = TextRenderer.MeasureText(e.Graphics, arr[0], e.CellStyle.Font, e.CellBounds.Size);

            float wid = stringSize.Height;
            int X,Y;

            for(int i=0;i<arr.Length;i++){
                if (pos==null||pos.IndexOf(i)==-1)
                {
                    X = (e.CellBounds.X);
                    Y = (e.CellBounds.Y + i * ((int)stringSize.Height));
                    TextRenderer.DrawText(e.Graphics, arr[i], e.CellStyle.Font, new Point(X, Y), SystemColors.ControlText);
                    //e.Graphics.DrawString(arr[i], e.CellStyle.Font, brush1, new PointF(X, Y), StringFormat.GenericDefault);
                }
                else
                {
                    X = (e.CellBounds.X);
                    Y = (e.CellBounds.Y + i * (int)stringSize.Height );
                    Brush brushForBox = new SolidBrush(Color.FromArgb(100, 120, 50,0));
                    e.Graphics.FillRectangle(brushForBox, X, Y, e.CellBounds.Width, (int)stringSize.Height);
                    TextRenderer.DrawText(e.Graphics, arr[i], e.CellStyle.Font, new Point(X, Y), SystemColors.ControlText);
                    //e.Graphics.DrawString(arr[i], e.CellStyle.Font, brush, new PointF(X, Y), StringFormat.GenericDefault);
                }
            }                   
        }
        //grid.InvalidateCell(-1, e.RowIndex);
        e.Handled = true;

现在它可以正常工作,但是第一个和最后一个单元格的文本溢出.例如,如果dataGridView中的第一个单元格部分可见,则在行标题中呈现文本.对于行中的最后一个单元格类似地,文本从中流出.任何建议/解决方案表示赞赏.

now it works just fine but the text overflows for first and last cells. For example if if first cell in the dataGridView is partially visible then text is rendered in row header. Similarly for last cell in the row text flows out of it. Any suggestion/solution is appreciated.

推荐答案

CellPainting事件将使您能够绘制DataGridView整个可见区域,包括所有标头,并且仅排除滚动条.

The CellPainting event will let you draw onto the whole visible area of the DataGridView, including all headers and excluding only scrollbars.

它确实为您提供了e.CellBounds矩形中的Cell区域,但是仍然可以让您在其外部绘制.

It does provide you with the Cell's area in the e.CellBounds rectangle but it will still let you draw outside of it.

要将图形限制为Cell,最简单的方法是将e.Graphics.ClipBounds更改为单元格的边界矩形.为确保行头不会溢出,我们将其限制为仅在行头的左侧开始,例如:

To restrict your drawing to the Cell the simplest way is to change the e.Graphics.ClipBoundsto the cell's bounding rectangle; to make sure no overflow into the rowheaders can occur we restrict it to only start left of the rowheader, maybe like this:

int rhw = grid.RowHeadersWidth;
Rectangle clip = e.CellBounds;
if (e.CellBounds.X < rhw)
    clip = new Rectangle(rhw, clip.Y, clip.Width - rhw, clip.Height);
e.Graphics.SetClip(clip, CombineMode.Replace);

现在,您绘制的所有内容都不会溢出.

Now nothing you draw can overflow.

注意:

  • 您还可以为两个 DrawString ,但是使用不同的字体进行绘制会使该操作更加困难.
  • 由于某些原因,剪切的区域似乎不适用于TextRenderer.
  • You could also set the target rectangle for for both DrawText and DrawString, but drawing in different fonts will make that a bit harder.
  • For some reason the clipped region doesn't seem to work with TextRenderer.

还请注意:我无法再现下溢到标头中的效果.我可以想象,如果顶部的单元格不是十分完全可见,则可能来自单元格的顶部,可能是负值. (不过,我的DGV只允许我按整数行滚动.)要排除这些情况,您可能需要计算一个更好的剪切矩形,该矩形仅在标头单元格的下方开始.

Also note: I couldn't reproduce the effect of underflowing into the headers. I can imagine that it might come from the cell's top can lying in the negative if the top cell isn't quite fully visible. (My DGV only let's me scroll by integral rows, though.) To exclude these cases you may need to calculate a better clipping rectangle that only starts right below the header cells..

这篇关于文本溢出用于DataGridView的自定义单元绘画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆