Обеспечение обертки текста в столбце 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
, чтобы столбцы не изменяли размер
(поэтому они остаются на заданной пользователем ширине).
После этого текст должен быть перенесен на следующую строку, если в столбце недостаточно места.
Ответ 4
Вы можете попробовать установить DataGridView.DefaultCellStyle.WrapMode
на DataGridViewTriState.True
Ответ 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;