DataGridView: Change Edit Control size while editing

后端 未结 7 926
遇见更好的自我
遇见更好的自我 2020-12-20 16:59

in the DataGridView I want the cell size to expand according to the string length when I edit the cell. Excel does the same.

In the DataGridView, w

7条回答
  •  北荒
    北荒 (楼主)
    2020-12-20 17:12

    This question is quite old but hopefully my answer helps somebody down the road. I ran across the same problem and was able to use a process similar to the following to make the column width update dynamically as the user typed, in order to ensure the text fit in the column.

    Events used:

    • CellBeginEdit
    • CellEndEdit
    • EditingControlShowing
    • TextBoxKeyPressEvent (i.e. KeyPress)

    NOTE: The following code assumes that AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells

    // ---------------------------------------------------------------------------
    
    private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
    {
        // Copies the original column width because switching to DataGridViewAutoSizeColumnMode.None
        // will automatically make the column a default width.
        int origColumnWidth = dataGridView1.Columns[e.ColumnIndex].Width;
    
        dataGridView1.Columns[e.ColumnIndex].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
    
        // Reverts back to the original width.
        dataGridView1.Columns[e.ColumnIndex].Width = origColumnWidth;
    }
    
    // ---------------------------------------------------------------------------
    
    private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    {
        dataGridView1.Columns[e.ColumnIndex].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    }
    
    // ---------------------------------------------------------------------------
    
    private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {
        if (e.Control is TextBox)
        {
            var tbox = (e.Control as TextBox);
    
            // De-register the event FIRST so as to avoid multiple assignments (necessary to do this or the event
            // will be called +1 more time each time it's called).
            tbox.KeyPress -= TextBoxKeyPressEvent;
            tbox.KeyPress += TextBoxKeyPressEvent;
        }
    }
    
    // ---------------------------------------------------------------------------
    
    private void TextBoxKeyPressEvent(object sender, KeyPressEventArgs e)
    {
        // Gets the text prior to the new character being added.  Appending an arbitrary "0" to the value
        // to account for the missing character when determining appropriate measurements.
        string prevText = dataGridView1.CurrentCell.EditedFormattedValue.ToString() + "0";
    
        Graphics editControlGraphics = dataGridView1.EditingControl.CreateGraphics();
    
        // Gets the length of the current text value.
        SizeF stringSize = editControlGraphics.MeasureString(prevText, dataGridView1.EditingControl.Font);
    
        int widthForString = (int)Math.Round(stringSize.Width, 0);
    
        // Makes the column width big enough if it's not already.
        if (dataGridView1.CurrentCell.OwningColumn.Width < widthForString)
        {
            dataGridView1.CurrentCell.OwningColumn.Width = widthForString;
        }
    }
    

    EDIT: Update to the TextBoxKeyPressEvent logic to account for Backspace:

    private void TextBoxKeyPressEvent(object sender, KeyPressEventArgs e)
            {
                string prevText;
                bool wasBackspaced = false;
    
                // The following logic will either add or remove a character to/from the text string depending if the user typed
                // an additional character or pressed the Backspace key.  At the end of the day, the cell will (at least) be
                // sized to the configured minimum column width or the largest row width in the column because we're using 
                // AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells.
                if (e.KeyChar == Convert.ToChar(Keys.Back))
                {
                    prevText = dataGridView1.CurrentCell.EditedFormattedValue.ToString();
    
                    if (prevText.Length == 0)
                    {
                        // Don't try to make it any smaller...
                        return;
                    }
    
                    // Remove an arbitrary character for determining appropriate measurements.
                    prevText = prevText.Remove(prevText.Length - 1);
                    wasBackspaced = true;
                }
                else
                {
                    // Gets the text prior to the new character being added.  Appending an arbitrary "0" to the value
                    // to account for the missing character when determining appropriate measurements.
                    prevText = dataGridView1.CurrentCell.EditedFormattedValue.ToString() + "0";
                }
    
                Graphics editControlGraphics = dataGridView1.EditingControl.CreateGraphics();
    
                // Gets the length of the current text value.
                SizeF stringSize = editControlGraphics.MeasureString(prevText, dataGridView1.EditingControl.Font);
    
                int widthForString = (int)Math.Round(stringSize.Width, 0);
    
                // Makes the column width big, or small, enough if it's not already.
                if (dataGridView1.CurrentCell.OwningColumn.Width < widthForString ||  // 1. Applies when adding text
                    (dataGridView1.CurrentCell.OwningColumn.Width > widthForString &&          // ---
                     dataGridView1.CurrentCell.OwningColumn.MinimumWidth < widthForString &&   // 2. Applies when backspacing
                     wasBackspaced))                                                           // ---
                {
                    dataGridView1.CurrentCell.OwningColumn.Width = widthForString;
                }
            }
    

提交回复
热议问题