Обеспечение переноса текста в столбце dataGridView - PullRequest
16 голосов
/ 13 июня 2011

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

| textdsadasda...  |

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

| textdsadasda     |
| dasdasa          |  <i>(continuation of line above)</i>

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

Ответы [ 7 ]

17 голосов
/ 13 июня 2011

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

  • .AutoSizeMode до .DisplayedCells.
  • Установите AutoSizeRowsMode на AllCells.
  • DataGridView.DefaultCellStyle.WrapMode до DataGridViewTriState.True
14 голосов
/ 28 июня 2012

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

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

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

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

4 голосов
/ 13 июня 2011

Вы можете попробовать установить DataGridView.DefaultCellStyle.WrapMode на DataGridViewTriState.True

3 голосов
/ 13 июня 2012

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

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

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

Я выполнил доработку кода @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's 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;
    }
}

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

2 голосов
/ 13 июня 2011

Помогает ли установка этого значения в достижении нужного значения дисплея

dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells;

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

1 голос
/ 13 июня 2011

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

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;
        }
    }
}
0 голосов
/ 25 октября 2012

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

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

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

Например:

datagrid1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.Green;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...