resizing issue in columns of datagridview

Rishabh aggarwal 40 Reputation points
2023-11-13T12:32:35.63+00:00

User's image

The above is the screenshot of a datagridview having two columns column1 and column2 . (column0 and column3 is hidden)

            dataGridView1.ColumnHeadersVisible = false;
            dataGridView1.AllowUserToAddRows = false;                         
            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;            
            dataGridView1.ReadOnly = true; 
            dataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.None;
 dataGridView1.Columns[0].Visible = false;           
  dataGridView1.Columns[3].Visible = false;
            dataGridView1.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
            dataGridView1.ScrollBars = ScrollBars.None;
            dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dataGridView1.MultiSelect = false;
            dataGridView1.AllowUserToResizeColumns = false;
            dataGridView1.RowHeadersVisible = false;
            dataGridView1.AllowUserToResizeRows = false;
            


private void DataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    columnTextBox = e.Control as TextBox;

    if (columnTextBox != null)
        columnTextBox.KeyPress += TextBox_KeyPress;
}

private void TextBox_KeyPress(object sender, KeyPressEventArgs e)
{
    var textBox = (TextBox)sender;
    
}

and the above is the properties that i have used for my datagridview . as it is visible that the content of column1 has cut off as both the columns are given equal width probably due to

            dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;   


Although as a temporary solution , we can allocate more width to column1 but there is a possibility that in future that both column's (column1 and column2) 's content might be longer than their width .

so i decided to create a method named as autofittext which fits the text being written according to width of column1 by minimising the space between each characters so as to fit all of them inside a column . (my intention is not to reduce the font size at all )

   private void Form1_Load(object sender, EventArgs e)
        {
            autofittext(dataGridView1);
        }

        private void autofittext(DataGridView dataGridView)
        {
            int column0Width = dataGridView.Columns[1].Width;

            for (int rowIndex = 0; rowIndex < dataGridView.Rows.Count; rowIndex++)
            {
                for (int columnIndex = 0; columnIndex < dataGridView.Columns.Count; columnIndex++)
                {
                    DataGridViewCell cell = dataGridView.Rows[rowIndex].Cells[columnIndex];

                    string text = cell.Value?.ToString() ?? "";

                    Size textSize = TextRenderer.MeasureText(text, dataGridView.Font);

                    if (textSize.Width > column0Width)
                    {
                        // Subtract the space between characters according to the difference in width
                        int difference = textSize.Width - column0Width;
                        int spaceBetweenCharacters = difference / text.Length;

                        // Update the text with the adjusted width
                        cell.Value = text.Substring(0, text.Length - spaceBetweenCharacters);
                    }
                }
            }
        }

now it brought me two problems

  1. it brings back my hidden column0
  2. it doesn't work at all .

please suggest a working approach . Thanks in advance

Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,865 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,500 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Jiale Xue - MSFT 41,426 Reputation points Microsoft Vendor
    2023-11-13T13:52:32.93+00:00

    Hi @rishabh aggarwal , Welcome to Microsoft Q&A, Updated:

    You can use the Graphics.MeasureString method to calculate the width of the text and adjust the font size accordingly. You can perform a null reference check before accessing ConvertEventArgs.Value to ensure it is not null.

    using System.Drawing;
    using System.Windows.Forms;
    
    namespace _7_15_x
    {
        public partial class Form1 : Form
        {
            private const int MaxCharacters = 15;
            private DataGridView dataGridView;
            public Form1()
            {
    
                InitializeComponent();
                InitializeDataGridView();
            }
            private void InitializeDataGridView()
            {
                dataGridView = new DataGridView();
                dataGridView.Dock = DockStyle.Fill;
                dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
    
                // add column
                DataGridViewTextBoxColumn textColumn = new DataGridViewTextBoxColumn();
                textColumn.Name = "TextColumn";
                textColumn.HeaderText = "Text Column";
                dataGridView.Columns.Add(textColumn);
    
                // add row
                dataGridView.Rows.Add("This is a long text that will be squeezed.");
    
                // add event handler
                dataGridView.CellFormatting += DataGridView_CellFormatting;
    
                Controls.Add(dataGridView);
            }
    
            private void DataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
            {
                if (e.ColumnIndex == dataGridView.Columns["TextColumn"].Index && e.RowIndex >= 0)
                {
                    // ensure that the value is not null
                    if (e.Value != null)
                    {
                        string cellValue = e.Value.ToString();
    
                        if (cellValue.Length > MaxCharacters)
                        {
                            using (Graphics g = dataGridView.CreateGraphics())
                            {
                                SizeF textSize = g.MeasureString(cellValue, dataGridView.Font);
    
                                float adjustedFontSize = dataGridView.Font.Size * (dataGridView.Columns["TextColumn"].Width / textSize.Width);
    
                                Font adjustedFont = new Font(dataGridView.Font.FontFamily, adjustedFontSize, dataGridView.Font.Style);
    
                                // set the font
                                e.CellStyle.Font = adjustedFont;
    
                                // set the value
                                e.Value = cellValue;
                            }
                        }
                    }
                }
            }
        }
    }
    
    

    enter image description here


    If you are not sure about the length of your data, you may choose to use the WarpMode property.

    DataGridViewCellStyle.WrapMode Property Please refer to the documentation above.

    dataGridView1.ColumnHeadersVisible = false;
    dataGridView1.AllowUserToAddRows = false;
    dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
    dataGridView1.ReadOnly = true;
    dataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.None;
    dataGridView1.Columns[0].Visible = false;
    dataGridView1.Columns[3].Visible = false;
    dataGridView1.Columns[2].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
    dataGridView1.ScrollBars = ScrollBars.None;
    dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
    dataGridView1.MultiSelect = false;
    dataGridView1.AllowUserToResizeColumns = false;
    dataGridView1.RowHeadersVisible = false;
    dataGridView1.AllowUserToResizeRows = false;
    
    dataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
    dataGridView1.Columns[1].DefaultCellStyle.WrapMode = DataGridViewTriState.True;
    dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
    

    enter image description here

    Best Regards,

    Jiale


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". 

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.