如何使DataGridView的宽度和高度适合其内容?

时间:2016-06-06 15:29:58

标签: c# winforms datagridview

我有一个动态创建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;
            }
            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);
        }
    }

结果:

enter image description here

正如您所看到的,DataGridView控件的宽度太长了。我怎样才能适应这两个维度?

2 个答案:

答案 0 :(得分:3)

主要问题是新创建的DataGridView在添加到父容器之前尚未完成其内部布局,并且仍会将所有列报告为宽度= 100。

解决这个问题的一种方法是在显示DGV后调用大小调整功能

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

请注意,我已经修复了一些问题:

  • 宽度和高度均未包含标题
  • 更改外部尺寸会忽略边框。我改为更改ClientSize。
  • 在尺寸可以工作之前,我们需要关闭滚动条。

答案 1 :(得分:0)

只需使用

dataGridView1.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

完整代码:

public class Person
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public Form1()
{
    InitializeComponent();

    List<Person> persons = new List<Person> {new Person() {ID = 0, Name = "one"}, new Person() {ID = 1, Name = "two"}, new Person() {ID = 2, Name = "tree"}, new Person() {ID = 3, Name = "four"}};
    dataGridView1.DataSource = persons;
    dataGridView1.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; 
}

private System.Windows.Forms.DataGridView dataGridView1;
private void InitializeComponent()
{
    this.dataGridView1 = new System.Windows.Forms.DataGridView();
    ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
    this.SuspendLayout();
    // 
    // dataGridView1
    // 
    this.dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
    this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
    this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
    this.dataGridView1.Location = new System.Drawing.Point(0, 0);
    this.dataGridView1.Name = "dataGridView1";
    this.dataGridView1.Size = new System.Drawing.Size(284, 262);
    this.dataGridView1.TabIndex = 0;
    // 
    // Form1
    // 
    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.ClientSize = new System.Drawing.Size(284, 262);
    this.Controls.Add(this.dataGridView1);
    this.Name = "Form1";
    this.Text = "Form1";
    ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
    this.ResumeLayout(false);

}

enter image description here