Ali Tor
Ali Tor

Reputation: 3005

Why doesn't AutoResize work for Row Header Width in DataGridView in C#?

I am new at DataGridView control and it confused me so much. I have a problem in with row header width doesn't have a good fit to the text inside of it. I did make a search but currently exist solutions didn't give me what I expect.

I am using this code to create dynamically DataGridView:

DataGridView CreateInputBox(int proc,int mac)
{
    DataGridView databox = new DataGridView();
    for (int i = 0; i < mac; i++)
    {
        databox.Columns.Add("col" + (i + 1), "M" + (i + 1));
        databox.Columns[i].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
        databox.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
    }
    for (int i = 0; i < proc; i++)
    {
        databox.Rows.Add();
        databox.Rows[i].HeaderCell.Value = "P" + (i + 1);
    }
    databox.AllowUserToAddRows = false;
    databox.AllowUserToDeleteRows = false;
    databox.AllowUserToOrderColumns = false;
    databox.AutoSize = true;
    databox.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
    databox.RowHeadersDefaultCellStyle.Padding = new Padding(3);

    return databox;
}

The result:

enter image description here

As it can be seen, P1,P2,P3 row headers haven't a good fit and there is some space. I want them to be like M1,M2,M3 column headers. How can I solve this issue?

I want the width of row headers fit the content of row header without showing record selector.

Upvotes: 2

Views: 5617

Answers (1)

Reza Aghaei
Reza Aghaei

Reputation: 125312

DataGridView calculates the preferred size of the row header by applying text width, row icon width and padding.

To change the way which preferred size is calculated and also to prevent drawing icons, you need to create a custom row header cell inheriting DataGridViewRowHeaderCell and override GetPreferredSize and Paint methods:

public class CustomHeaderCell : DataGridViewRowHeaderCell
{
    protected override Size GetPreferredSize(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize)
    {
        var size1 = base.GetPreferredSize(graphics, cellStyle, rowIndex, constraintSize);
        var value = string.Format("{0}", this.DataGridView.Rows[rowIndex].HeaderCell.FormattedValue);
        var size2 = TextRenderer.MeasureText(value, cellStyle.Font);
        var padding = cellStyle.Padding;
        return new Size(size2.Width + padding.Left+padding.Right, size1.Height);
    }
    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, DataGridViewPaintParts.Background);
        base.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);
        TextRenderer.DrawText(graphics, string.Format("{0}", formattedValue), cellStyle.Font, cellBounds, cellStyle.ForeColor);
    }
}

Then it's enough to replace current header cells with your new header cell:

//Put this lines before adding rows
grid.RowTemplate.DefaultHeaderCellType = typeof(CustomHeaderCell);
grid.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
grid.RowHeadersDefaultCellStyle.Padding = new Padding(2);

Upvotes: 2

Related Questions