Ensuring text wraps in a dataGridView column

前端 未结 9 1516
感动是毒
感动是毒 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:13

    I agree with the answer that discussed simply setting the WordWrap on the cell and would add to it this scenario.

    I was needing to change the colors and font styles on the fly based on the data in each cell. Initially I thought that I was stuck figuring out how to make the DrawString work with wrapping inside CellPainting event due to needing different text colors.

    However, in the end I just set the Cell.Style properties inside the CellPainting event and then exited the event without setting the e.Handled = true. This way the grid's paint event used the styles I set for each cell and the text wrapped properly.

    For example:

    datagrid1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.Green;
    
    0 讨论(0)
  • 2021-01-01 18:22

    You can try setting the DataGridView.DefaultCellStyle.WrapMode to DataGridViewTriState.True

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

    I found DeveloperX's answer to be very good. But I found I needed to tweak it a little. Firstly, I needed to ensure that the column in question was not in AutoSizeMode:

        if (dgv.Columns[e.ColumnIndex].AutoSizeMode != DataGridViewAutoSizeColumnMode.None)
            throw new InvalidOperationException(String.Format("dgv {0} AutoSizeMode <> 'None'", dgv.Columns[e.ColumnIndex].Name));
    

    I also found that using

    var s = e.Graphics.MeasureString(e.Value.ToString(), dataGridView1.Font);
    

    returns a string length, which can't be used for comparison to ColumnWidth, which is given in pixels. So, using How can I convert a string length to a pixel unit?, I modified the above line of code to be

    var s = e.Graphics.MeasureString(e.Value.ToString(), new Font("Segoe UI", 11, FontStyle.Regular, GraphicsUnit.Pixel));
    

    I also found that doing a direct comparison of widths was insufficient to determine when to prevent clipping - there were some edge cases that weren't being caught. So, I replaced

    if (s.Width > dataGridView1.Columns[e.ColumnIndex].Width)
    

    with a ratio comparison (cutoff value determined by experiment) :

    if (e.Value.ToString().Length / (double)dataGridView1.Columns[e.ColumnIndex].Width >= .189)
    

    Finally, the cell in the selected row was not hightlighted, so I added the following:

           SolidBrush backColorBrush;
            if (dataGridView1.SelectedRows[0].Index == e.RowIndex)
                backColorBrush = new SolidBrush(e.CellStyle.SelectionBackColor);
            else
                backColorBrush = new SolidBrush(e.CellStyle.BackColor);
    

    Final code:

    private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
    {
        if (e.Value == null || e.RowIndex == -1)
            return;
    
        if (dataGridView1.Columns[e.ColumnIndex].AutoSizeMode != DataGridViewAutoSizeColumnMode.None)
            throw new InvalidOperationException(Format("dataGridView1 {0} AutoSizeMode <> 'None'", dataGridView1.Columns[e.ColumnIndex].Name));
    
        var s = e.Graphics.MeasureString(e.Value.ToString(), new Font("Segoe UI", 11, FontStyle.Regular, GraphicsUnit.Pixel));
        if (e.Value.ToString().Length / (double)dataGridView1.Columns[e.ColumnIndex].Width >= .189)
        {
            SolidBrush backColorBrush;
            if (dataGridView1.SelectedRows[0].Index == e.RowIndex)
                backColorBrush = new SolidBrush(e.CellStyle.SelectionBackColor);
            else
                backColorBrush = new SolidBrush(e.CellStyle.BackColor);
    
            using (backColorBrush)
            {
                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 = System.Convert.ToInt32((s.Height * Math.Ceiling(s.Width / (double)dataGridView1.Columns[e.ColumnIndex].Width)));
                e.Handled = true;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题