在DataGridView中换行 [英] Wrap a row in DataGridView

查看:221
本文介绍了在DataGridView中换行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个聊天机器人。我会很诚实,UI不是我的强项。我正在逻辑聊天部分的聊天机器人的后端上工作,但是为了进行测试,我需要一个合适的工作UI。因此,我选择了更易于使用的winforms。我创建了一个单列DataGridView,所有在聊天窗口底部的文本框中编写的文本将显示为DataGridView行。 Winform被锚定以向各个方向扩展。因此,当我加载该exe时,它显示为一个微型窗口,当我最大化它时,DataGridView部分和文本框会相应地增长。

I am trying to create a chatbot. I will be very honest, UI is not my forte. I am working on the backend of the chatbot as in the logic part, but for testing I need a proper working UI. So, I opted for easier to use winforms. I created a single column DataGridView and all the text written in a textbox at the bottom part of the chat window will appear as DataGridView rows. The winform is anchored to grow in all directions. So, when I load the exe, it shows as a miniature window, when I maximize it, the DataGridView portion and the textbox grow accordingly.

当我键入一个长字符串时并且winform不在最大化状态下,该文本未包装在可见区域的行中。它水平延伸,因此在屏幕上显然不可见。当我最大化窗口时,可以看到文本。当我给出一个非常长的字符串并最大化窗口时,该行中只显示了大部分字符串,因为它可以适合屏幕大小。

When I type a long string and the winform is not in a maximized state, the text is not wrapped in the row in the visible area. It extends horizontally and so obviously not visible in the screen. When I maximize the window, I can see the text. When I give a veryyy long string and maximize the window, only that much of the string is shown in the row as it can fit in the screen size.

我想要的要做的事情:我希望文本自动换行,这样,无论我的窗口是最大化还是最小化,我都可以以换行格式看到窗口中的整个字符串。

What I want to do: I want the text to wrap automatically in the rows, so that, irrespective of whether my window is maximized or minimized, I can see the entire string in the window in a wrapped format.

我尝试过的事情:

dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;


推荐答案

DataGridViewTextBox 使用断字执行换行。这意味着,如果您的文字较长,则中断将仅适用于单词的结尾。根据您的要求,换行时需要断字符。为此,您需要创建一个自定义单元格并执行以下字符换行包装:

DataGridViewTextBox performs wrapping using word-break. It means if you have a long text, the break will just apply at the end of words. Based on your requirement, you need character-break when word wrapping. To do so, you need to create a custom cell and perform character-break wrapping this way:


  • 覆盖 GetPreferredSize 方法可根据换行符换行来计算单元格/行的高度。为此,您可以使用 Graphics.MeasureString 方法。

  • Override GetPreferredSize method to calculate the height of Cell/Row based on character break word wrapping. To so so you can use Graphics.MeasureString method.

覆盖 Paint 方法使用 Graphics.DrawString 方法绘制带换行符的字符串。

Override Paint method to draw the wrapped string with character break using Graphics.DrawString method.

您可以执行以下设置:


  • 要使用<$的宽度c $ c> DataGridView 作为列,则应将其 AutoSizeMode 设置为填充。这样,您的列宽将填满网格,并将根据网格大小更改其大小。另外,如果您有多个列,则可以设置 FillWeight 来控制相对于其他列的列大小百分比。

  • To use the width of DataGridView for your column, you should set it's AutoSizeMode to Fill. This way, your column width will fill the grid and will be change its size according to grid size. Also if you had more than one column, you can set FillWeight to control the percent of column size relative to other columns.

要将文本包装在列中,应将列的 DefaultCellStyle.WrapMode 设置为 DataGridViewTriState.True

To wrap the text in column you should set DefaultCellStyle.WrapMode of the column to DataGridViewTriState.True.

要使行自动调整大小,应将 AutoSizeRowMode > DataGridView 到 DataGridViewAutoSizeRowsMo​​de.AllCells

To make the rows auto-size you should set AutoSizeRowMode of DataGridView to DataGridViewAutoSizeRowsMode.AllCells.

注册自定义单元我们创建为该列的 CellTemplate

Register the custom cell which we created as CellTemplate of the column.

MyDataGridViewTextBoxCell

此单元格使用断字符而不是分词来执行文本换行。

This cell performs text-wrapping using character-break instead of word break.

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 });
}

这篇关于在DataGridView中换行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆