datagridview видимых линий сетки даже без данных c # - PullRequest
0 голосов
/ 08 октября 2018

У меня есть сетка данных, которая отображает данные, но отображаемые данные не заполняют всю сетку данных, которую показывает серый фон сетки данных.то, что я хочу сделать, это показать линии сетки представления данных даже без данных в каждой строке.enter image description here

К счастью, я нашел код относительно этого (этот код предназначен для свойства AutoSizeColumnsMode == Заполнить, но мне нужно, чтобы это свойство было установлено на AllCells для более длинных строк внутри каждого столбца) сначала я подумал, что это код, который я ищу:

private void dataGridView1_Paint(object sender, PaintEventArgs e)
{
    int rowHeight = this.dataGridView1.RowTemplate.Height;

    Pen slategraypen = new Pen(Brushes.SlateGray,0.5f);
    slategraypen.LineJoin = System.Drawing.Drawing2D.LineJoin.Bevel;
    slategraypen.Alignment = System.Drawing.Drawing2D.PenAlignment.Center;

    int h = this.dataGridView1.ColumnHeadersHeight + (rowHeight) * (this.dataGridView1.NewRowIndex);

    Bitmap rowImg = new Bitmap(this.dataGridView1.Width, rowHeight);

    Graphics g = Graphics.FromImage(rowImg);

    Rectangle rFrame = new Rectangle(1, 1, this.dataGridView1.Width-4, rowHeight);

    g.DrawRectangle(slategraypen, rFrame);

    Rectangle rFill = new Rectangle(2, 1, this.dataGridView1.Width - 4, rowHeight-1);

    g.FillRectangle(Brushes.White, rFill);

    // for rowheaders drawing. in my case, I dont want to show the rowheaders so I didnt include this in my code
    //Rectangle rowHeader = new Rectangle(2, 2, this.dataGridView1.RowHeadersWidth - 2, rowHeight - 4);

    //g.FillRectangle(new SolidBrush(this.dataGridView1.RowHeadersDefaultCellStyle.BackColor), rowHeader);

    int w = this.dataGridView1.RowHeadersWidth-40;// -40 is the width of the row header that I dont want to show

    for (int j = 0; j < this.dataGridView1.ColumnCount; j++)
    {
        w += this.dataGridView1.Columns[j].Width;
        g.DrawLine(slategraypen, new Point(w, 0), new Point(w, rowHeight));
    }

    int loop = (this.dataGridView1.Height - h) / rowHeight;

    for (int j = 0; j < loop + 1; j++)
    {
        e.Graphics.DrawImage(rowImg, 0, h + j * rowHeight);
    }
}

, и это произошло:

enter image description here

Но,когда я ввожу длинную строку в столбец, это происходит: обратите внимание на правую часть таблицы данных, некоторые столбцы уменьшаются из-за свойства заполнения, установленного для autosizecolumnsmode enter image description here

Я пытался изменитьСвойство AutoSizeColumnsMode для allcells, и это происходило: всякий раз, когда я прокручивал горизонтальную полосу прокрутки, линии, нарисованные ниже, рисовались в неправильных местах.Я не совсем уверен, произойдет ли это также, если я прокручиваю вертикальную полосу прокрутки вверх и вниз.

enter image description here

Мне нужна ваша помощь в написании правильного кода дляэтот.Буду очень признателен за вашу помощь.

1 Ответ

0 голосов
/ 08 октября 2018

Вот быстрый:

enter image description here

Я использую CellPainting для сбора текущих позиций столбцов.Этот маленький трюк позволяет мне игнорировать любую прокрутку, изменение размера столбца и т. Д.

Вот как:

List<int> colX = new List<int>();

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.RowIndex == 0)
    {
        if (e.ColumnIndex == (dataGridView1.RowHeadersVisible ?  -1 : 0)) colX.Clear();
        colX.Add(e.CellBounds.X);
    }
}

И в событии Paint я рисую «ячейки».

using System.Drawing.Drawing2D;
..

private void dataGridView1_Paint(object sender, PaintEventArgs e)
{
    Rectangle cRect = dataGridView1.ClientRectangle;
    int y0 = 0;
    if (dataGridView1.ColumnHeadersVisible) y0 += dataGridView1.ColumnHeadersHeight;
    int rhw = dataGridView1.RowHeadersVisible ? dataGridView1.RowHeadersWidth : 0;

    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        y0 += row.Height;
    }
    int y1 = cRect.Height;
    using (SolidBrush brush = new SolidBrush(dataGridView1.DefaultCellStyle.BackColor))
        e.Graphics.FillRectangle(brush, cRect.Left + 2, y0, cRect.Right - 4, y1 - y0 - 2);
    using (Pen gridPen1 = new Pen(dataGridView1.GridColor, 1f) 
            { DashStyle = DashStyle.Dot })
    using (Pen gridPen2 = new Pen(dataGridView1.GridColor, 1f) 
            { DashStyle = DashStyle.Solid })
    {
        for (int i = 0; i < colX.Count; i++)
            e.Graphics.DrawLine(gridPen1, colX[i] - 1, y0, colX[i] - 1, y1);
        int y = y0;
        while (y < cRect.Bottom)
        {
            e.Graphics.DrawLine(y == y0 ? gridPen2 : gridPen1, 
                                cRect.Left, y, cRect.Right, y);
            y += dataGridView1.Rows[0].Height;
        }
        if (rhw > 0)  e.Graphics.DrawLine(gridPen1, rhw, y0, rhw, y1);

    }
}

Гораздо проще, чем код, который вы нашли, в котором есть несколько других ошибок, таких как утечка ресурсов в событии Paint.

Примечание: я сделал псевдо-Ячейки немного выделяются, рисуя пунктирной линией.

Также обратите внимание, что код предполагает RowHeaders.

Если у вас их нет, вы также должны Invalidate в событии Scroll:

private void dataGridView1_Scroll(object sender, ScrollEventArgs e)
{
    dataGridView1.Invalidate();
}

Также сделайте DGV DoubleBuffered , чтобы избежать мерцания !!

В зависимости от ваших потребностей, вам может понадобиться Invalidate в еще нескольких событиях, таких как:

private void dataGridView1_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
{
    dataGridView1.Invalidate();
}

Другие могут включать ColumnAdded, ColumnRemoved ..

Обновление: Я исправил незначительнуюошибка по RowHeaders ..

...