我正在尝试创建一个聊天机器人。老实说,UI 不是我的强项。我在聊天机器人的后端工作,就像在逻辑部分一样,但为了测试,我需要一个正常工作的用户界面。所以,我选择了更容易使用的winforms。我创建了一个单列 DataGridView,聊天窗口底部文本框中的所有文本都将显示为 DataGridView 行。 winform被锚定在各个方向生长。因此,当我加载 exe 时,它显示为一个微型窗口,当我最大化它时,DataGridView 部分和文本框会相应地增长。
当我键入一个长字符串并且 winform 未处于最大化状态时,文本不会在可见区域的行中换行。它水平延伸,因此在屏幕上显然不可见。当我最大化窗口时,我可以看到文本。当我给出一个非常长的字符串并最大化窗口时,行中只会显示适合屏幕大小的字符串。
我想做的:我希望文本在行中自动换行,这样,无论我的窗口是最大化还是最小化,我都可以在窗口中看到换行格式的整个字符串。
我尝试过的:
dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
最佳答案
DataGridViewTextBox
使用断字执行换行。这意味着如果你有一个长文本,中断将只适用于单词的末尾。根据您的要求,您在换行时需要换行。为此,您需要创建一个自定义单元格并以这种方式执行换行符:
重写
GetPreferredSize
方法以根据字符换行计算单元格/行的高度。为此,您可以使用Graphics.MeasureString
方法。重写
Paint
方法以使用Graphics.DrawString
方法绘制换行字符串。
您可以执行这些设置:
要为您的列使用
DataGridView
的宽度,您应该将其AutoSizeMode
设置为Fill
。这样,您的列宽将填充网格并根据网格大小更改其大小。此外,如果您有多个列,则可以设置FillWeight
来控制列大小相对于其他列的百分比。要将列中的文本换行,您应该将列的
DefaultCellStyle.WrapMode
设置为DataGridViewTriState.True
。要使行自动调整大小,您应该将
DataGridView
的AutoSizeRowMode
设置为DataGridViewAutoSizeRowsMode.AllCells
。将我们创建的自定义单元格注册为列的
CellTemplate
。
MyDataGridViewTextBoxCell
此单元格使用字符分隔而不是单词分隔执行文本换行。
public class MyDataGridViewTextBoxCell:DataGridViewTextBoxCell
{
protected override Size GetPreferredSize(Graphics graphics,
DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize)
{
if(cellStyle.WrapMode== DataGridViewTriState.True && this.RowIndex>=0)
{
var value= string.Format("{0}", this.FormattedValue);
using (var g = this.OwningColumn.DataGridView.CreateGraphics())
{
var r = g.MeasureString(value, cellStyle.Font, this.OwningColumn.Width )
.ToSize();
r.Width += cellStyle.Padding.Left + cellStyle.Padding.Right;
r.Height += cellStyle.Padding.Top + cellStyle.Padding.Bottom;
return r;
}
}
else
{
return base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize);
}
}
protected override void Paint(Graphics graphics, Rectangle clipBounds,
Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState,
object value, object formattedValue, string errorText,
DataGridViewCellStyle cellStyle,
DataGridViewAdvancedBorderStyle advancedBorderStyle,
DataGridViewPaintParts paintParts)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value,
formattedValue, errorText, cellStyle, advancedBorderStyle,
paintParts & ~ DataGridViewPaintParts.ContentForeground);
graphics.DrawString(string.Format("{0}", formattedValue),
cellStyle.Font, Brushes.Black, cellBounds);
}
}
示例
public class Model
{
public string Text { get; set; }
}
BindingList<Model> list = new BindingList<Model>();
private void Form1_Load(object sender, EventArgs e)
{
var column1 = new DataGridViewTextBoxColumn();
column1.CellTemplate = new MyDataGridViewTextBoxCell();
column1.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
column1.DataPropertyName = "Text";
column1.DefaultCellStyle = new DataGridViewCellStyle();
column1.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
column1.HeaderText = "Text";
column1.Name = "column1";
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
dataGridView1.Columns.Add(column1);
this.dataGridView1.DataSource = list;
}
private void button1_Click(object sender, EventArgs e)
{
list.Add(new Model() { Text = textBox1.Text });
}
关于c# - 在 DataGridView 中换行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39660850/