Ensuring text wraps in a dataGridView column

前端 未结 9 1515
感动是毒
感动是毒 2021-01-01 17:41

I have dataGridView with a particular column. When I write long text in dataGridView it shows me a shortened version, with ellipses, because the column isn\'t wide enough to

相关标签:
9条回答
  • 2021-01-01 18:04

    To do wrapping add this after binding

    DataGrid1.ItemStyle.Wrap = true;
    
    0 讨论(0)
  • 2021-01-01 18:07

    Try setting

    • .AutoSizeMode to .DisplayedCells.
    • Set the AutoSizeRowsMode to AllCells.
    • DataGridView.DefaultCellStyle.WrapMode to DataGridViewTriState.True
    0 讨论(0)
  • 2021-01-01 18:08

    I've found @DeveloperX answer really useful, but with a couple of hiccups:

    1. It causes some rows to flicker, if there is more than one cell that needs wrapping
    2. Some cells have the last line missing or truncated (this happens if there are long words which can't be wrapped inside the text)

    And it also caused missing cell borders (but this depends on grid/cell border settings).

    I did a rework of @DeveloperX code to solve this issues, and came up with the following code:

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

    Note that there is one problem still unresolved with this code: the text is not vertically centered anymore inside the cells!

    0 讨论(0)
  • 2021-01-01 18:09

    Does setting this value help in achieving the display as you want

    dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells;
    

    in addition to setting the WrapMode = DataGridViewTriState.True;

    0 讨论(0)
  • 2021-01-01 18:09

    May be handling cell painting event can help you

    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 讨论(0)
  • 2021-01-01 18:11

    There is no need to reinvent the wheel by repainting the cell.

    Instead simply:

    • Set AutoSizeRowsMode property to AllCells. This allows row height to grow with any wrapped text.
    • Set DataGridView.DefaultCellStyle.WrapMode to DataGridViewTriState.True to wrap text in the cells.
    • Most importantly set DataGridView.AutoSizeColumnsMode to DataGridViewAutoSizeColumnsMode.None so that the columns don't resize themselves (so they remain at the user specified width).

    After that the text should wrap to the next line if there is not enough space in the column.

    0 讨论(0)
提交回复
热议问题