Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
489 views
in Technique[技术] by (71.8m points)

c# - How to fit DataGridView width and height to its content?

I have a method to create DataGridView dynamically but when it is shown up, the width is greater than the content width (total width of the columns). Also the height has not enough length to meet the length of the rows.

I tried using this method but it didn't work:

    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;
            }
            databox.RowTemplate.DefaultHeaderCellType = typeof(CustomHeaderCell);
            databox.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
            databox.RowHeadersDefaultCellStyle.Padding = new Padding(2);
            for (int i = 0; i < proc; i++)
            {
                databox.Rows.Add();
                databox.Rows[i].HeaderCell.Value = "P" + (i + 1);
            }
            databox.DefaultCellStyle.SelectionBackColor = Color.LightGray;
            databox.AllowUserToAddRows = false;
            databox.AllowUserToDeleteRows = false;
            databox.AllowUserToOrderColumns = false;
            databox.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
            databox.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;

            //This block doesn't work
            var totalHeight = databox.Rows.GetRowsHeight(DataGridViewElementStates.None);
            var totalWidth = databox.Columns.GetColumnsWidth(DataGridViewElementStates.None);
            databox.Width = totalWidth;
            databox.Height = totalHeight;
            //
            return databox;
        }
    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);
        }
    }

Result:

enter image description here

As you can see the width of the DataGridView control is so long. How can I fit it for both dimension?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The main problem is that your newly created DataGridView has not finished its internal layout before being added to a parent container and will still report all columns as having a width = 100.

One way to fix it is to call a sizing function after the DGV has been displayed:

void sizeDGV(DataGridView dgv)
{
    DataGridViewElementStates states = DataGridViewElementStates.None;
    dgv.ScrollBars = ScrollBars.None;
    var totalHeight = dgv.Rows.GetRowsHeight(states) + dgv.ColumnHeadersHeight;
    totalHeight += dgv.Rows.Count * 4  // a correction I need
    var totalWidth = dgv.Columns.GetColumnsWidth(states) + dgv.RowHeadersWidth;
    dgv.ClientSize = new Size(totalWidth , totalHeight );
}

enter image description here

Note that I have fixed a few things along the way:

  • Both width and height did not include the headers
  • changing the outer size ignores the border. I change the ClientSize instead.
  • Before the size can work we need to switch off the scroll bars.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...