Обеспечение обертки текста в столбце dataGridView

У меня есть dataGridView с определенным столбцом. Когда я пишу длинный текст в dataGridView, он показывает сокращенную версию с эллипсами, потому что столбец недостаточно широк, чтобы отобразить всю строку.

| textdsadasda...  |

Что мне нужно сделать, если я хочу, чтобы dataGridView отображал этот текст в следующей строке или обертывал текст?

| textdsadasda     |
| dasdasa          |  (continuation of line above)

Как это можно сделать?

Ответы

Ответ 1

Может быть, обработка событий с ячейкой может помочь вам

private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    if (e.Value == null)
        return;
    var s = e.Graphics.MeasureString(e.Value.ToString(), dataGridView1.Font);
    if (s.Width > dataGridView1.Columns[e.ColumnIndex].Width)
    {
        using (
  Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor),
  backColorBrush = new SolidBrush(e.CellStyle.BackColor))
        {
            e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
            e.Graphics.DrawString(e.Value.ToString(), dataGridView1.Font, Brushes.Black, e.CellBounds,StringFormat.GenericDefault);
            dataGridView1.Rows[e.RowIndex].Height = (int)(s.Height * Math.Ceiling( s.Width / dataGridView1.Columns[e.ColumnIndex].Width)) ;
            e.Handled = true;
        }
    }
}

Ответ 2

Попробуйте установить

  • .AutoSizeMode до .DisplayedCells.
  • Установите AutoSizeRowsMode в AllCells.
  • DataGridView.DefaultCellStyle.WrapMode to DataGridViewTriState.True

Ответ 3

Нет необходимости изобретать колесо, перекрашивая ячейку.

Вместо этого просто:

  • Задайте для свойства AutoSizeRowsMode значение AllCells. Это позволяет высоту строки расти с любым завернутым текстом.
  • Установить DataGridView.DefaultCellStyle.WrapMode на DataGridViewTriState.True, чтобы обернуть текст в ячейки.
  • Самое главное установить DataGridView.AutoSizeColumnsMode на DataGridViewAutoSizeColumnsMode.None, чтобы столбцы не изменяли размер (поэтому они остаются на заданной пользователем ширине).

После этого текст должен быть перенесен на следующую строку, если в столбце недостаточно места.

Ответ 5

Я нашел @DeveloperX answer действительно полезным, но с парой икота:

  • Он вызывает мерцание некоторых строк, если имеется более одной ячейки, которая требует обертывания
  • В некоторых ячейках последняя строка отсутствует или усечена (это происходит, если есть длинные слова, которые не могут быть обернуты внутри текста).

И это также вызвало недостающие границы ячеек (но это зависит от настроек границы сетки/ячейки).

Я сделал переделку кода @DeveloperX для решения этих проблем и придумал следующий код:

private int _rowMaxHeight = 0;
private int _rowDefaultHeight = 0;
private void dataGridView1_CellPainting(object sender, 
    DataGridViewCellPaintingEventArgs e)
{
    if (e.Value == null || e.RowIndex < 0)
    {
        // The WordWrap code is ony executed if requested the cell has a value,
        // and if this is not the heading row.
        return;
    }
    if (e.ColumnIndex == 0)
    {
        // Resetting row max height on each row first cell
        _rowMaxHeight = 0;
        if (_rowDefaultHeight == 0)
        {
            /* The default DataGridView row height is saved when the first cell
             * inside the first row is populated the first time. This is later
             * used as the minimum row height, to avoid 
             * smaller-than-default rows. */
            _rowDefaultHeight = dataGridView1.Rows[e.RowIndex].Height;
        }
    }
    // Word wrap code
    var sOriginal = e.Graphics.MeasureString(e.Value.ToString(), 
        dataGridView1.Font);
    var sWrapped = e.Graphics.MeasureString(e.Value.ToString(), 
        dataGridView1.Font,
        // Is is MeasureString that determines the height given the width, so
        // that it properly takes the actual wrapping into account
        dataGridView1.Columns[e.ColumnIndex].Width);    
    if (sOriginal.Width != dataGridView1.Columns[e.ColumnIndex].Width)
    {
        using (Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor), 
            backColorBrush = new SolidBrush(e.CellStyle.BackColor), 
            fontBrush = new SolidBrush(e.CellStyle.ForeColor))
        {
            e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
            // The DrawLine calls restore the missing borders: which borders
            // miss and how to paint them depends on border style settings
            e.Graphics.DrawLine(new Pen(gridBrush, 1),
                new Point(e.CellBounds.X - 1, 
                    e.CellBounds.Y + e.CellBounds.Height - 1),
                new Point(e.CellBounds.X + e.CellBounds.Width - 1, 
                    e.CellBounds.Y + e.CellBounds.Height - 1));
            e.Graphics.DrawLine(new Pen(gridBrush, 1),
                new Point(e.CellBounds.X + e.CellBounds.Width - 1, 
                    e.CellBounds.Y - 1),
                new Point(e.CellBounds.X + e.CellBounds.Width - 1, 
                    e.CellBounds.Y + e.CellBounds.Height - 1));
            //Updating the maximum cell height for wrapped text inside the row:
            // it will later be set to the row height to avoid the flickering
            // that would occur by setting the height multiple times.
            _rowMaxHeight = (Math.Ceiling(sWrapped.Height) > _rowMaxHeight)
                ? (int)Math.Ceiling(sWrapped.Height) : _rowMaxHeight;
            // The text is generated inside the row.
            e.Graphics.DrawString(e.Value.ToString(), dataGridView1.Font, 
                fontBrush, e.CellBounds, StringFormat.GenericDefault);
            e.Handled = true;
        }
    }
    if (e.ColumnIndex == dataGridView1.ColumnCount -1 
        && _rowMaxHeight > 0 
        && _rowMaxHeight != dataGridView1.Rows[e.RowIndex].Height)
    {
        // Setting the height only in the last cell, when the full row has been
        // painted, helps to avoid flickering when more than one row 
        // needs the wrap.
        dataGridView1.Rows[e.RowIndex].Height = 
            (_rowMaxHeight > _rowDefaultHeight) 
            ? _rowMaxHeight : _rowDefaultHeight;
    }
}

Обратите внимание, что с этим кодом еще не решена проблема: текст больше не центрируется по центру внутри ячеек!

Ответ 6

Помогает ли настройка этого значения при достижении отображения, как вы хотите

dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells;

в дополнение к установке WrapMode = DataGridViewTriState.True;

Ответ 7

Я согласен с ответом, в котором обсуждалось просто установка WordWrap в ячейке и добавление к нему этого сценария.

Мне нужно было менять цвета и стили шрифтов "на лету" на основе данных в каждой ячейке. Первоначально я думал, что я застрял, выясняя, как сделать работу DrawString с обертыванием внутри события CellPainting из-за необходимости использования разных цветов текста.

Однако в конце я просто установил свойства Cell.Style внутри события CellPainting, а затем вышел из события без установки e.Handled = true. Таким образом, событие рисования сетки использовало стили, которые я установил для каждой ячейки, и текст был обернут правильно.

Например:

datagrid1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.Green;