c# - 在 DataGridView 中换行

标签 c# .net winforms datagridview

我正在尝试创建一个聊天机器人。老实说,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

  • 要使行自动调整大小,您应该将 DataGridViewAutoSizeRowMode 设置为 DataGridViewAutoSizeRowsMo​​de.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/

相关文章:

c# - DispatcherOperation.Task 立即返回

c# - 如何为在套接字上发送的文件创建长度前缀?

.net - 在.NET Windows窗体上从Chrome实现拖放

c# - 您将如何对数据注释进行单元测试?

C# - 如何在一段时间内阻止方法返回?

c# - 如何创建一个 C# 应用程序来决定是显示为控制台应用程序还是窗口应用程序?

C#图形闪烁

c# - 禁用 Windows 窗体上的退出按钮?

c# - 如何在 C# 中监控文件访问

c# - TFS REST API .NET 客户端,TFS2017,个人访问 token : "You must pass a valid patch document in the body of the request."