开发者

DataGridView AutoSize

开发者 https://www.devze.com 2023-03-14 14:39 出处:网络
Is there any way to make DataGridView fit the开发者_如何学编程 width and height of colums/rows? I have found the solution which requires manual calulation: http://www.codeguru.com/csharp/.net/net_data

Is there any way to make DataGridView fit the开发者_如何学编程 width and height of colums/rows? I have found the solution which requires manual calulation: http://www.codeguru.com/csharp/.net/net_data/datagrid/article.php/c9603 Does DataGridView really not support this feature?


if you want to make all the columns to resize automatically according to data:

for (int i = 0; i < dataGridView.Columns.Count; i++)
{
    dataGridView.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}


This is a pretty old question that has been misunderstood IMHO. What Idsa wants to achieve is to make the actual AutoSize winforms feature to work with the DataGridView. The property exists but it has no effect.

This means the DataGridView has to fit around its content, not its content has to fit inside the DataGridView.

There are a lot of things to think about to achieve a AutoSize implementation. The DataGridView size depends on a lot of criterias:

  • Border size
  • Padding
  • Cell Delimiter size
  • Row Header height
  • Column header width
  • How the DataGridView is populated (DataBound or manually)
  • ... a lot more

The best is to select a set of some criteria that fits your specific scenario, and write something that will compute the DataGridView size for you.

Here my specific scenario as an example:

  • my grid is data bound. So its size is supposed to change each time a DataBinding operation is complete. This is the condition that trigger a recalculation of the DataGridView size. So I hook it to the DataBindingComplete event.

  • my grid is not supposed to display scrollbars. So I set the Scrollbars property to None.

  • My row and columns autosize mode are set to AllCells.

  • Rows and Columns header are not visible. If they were, their sizes has to be included in the calculation.

The extension below method fits my needs. It is very simple because my grids are very simple. You will probably have to tweak it a bit to make it work as you wish, and a lot to make it work for every DataGridView scenarios.

public static void HandleAutoSize(this DataGridView dgv)
{
    dgv.DataBindingComplete += (s, e) =>
    {
        var dg = (DataGridView)s;
        var width = dg.Columns.GetColumnsWidth(DataGridViewElementStates.None);
        var height = dg.Rows.GetRowsHeight(DataGridViewElementStates.None);

        dg.ClientSize = new Size(width, height);
    };
}


Use the AutoSizeMode and Fill Mode


This VB.NET translation worked for me:

For i As Integer = 0 To dataGridView.ColumnCount - 1
    dataGridView.Columns(i).AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells
Next


The thread is quite old, but in case someone still needs it now he can use grid.AutoResizeColumns() works fine with me


The Real Answer

I wrote this code to calculate the exact size of the grid using pixel color and comparing it the background. It works great for me. It causes some flicker if you use autosize on the containing form, you must disable autosize or modify the code to manually set the size on the containing form. But, without autosize on the parent control it works perfectly.

 private void gridViewAutoSize(DataGridView dgv)
        {

            Bitmap dgvBmp = new Bitmap(dgv.Width,dgv.Height);
            dynRecDataGridView.DrawToBitmap(dgvBmp, new Rectangle(0, 0, dgv.Width, dgv.Height));

            int x = dgv.Width-1;
            int y = dgv.Height-1;
            int halfHeaderW = dgv.RowHeadersWidth / 2;
            int halfHeaderH = dgv.ColumnHeadersHeight / 2;
            int borderX = 0;
            int borderY = 0;
            const int widthLimit = 800;
            const int heightLimit = 350;

            while (x == dgv.Width - 1)
            {
                borderX = 0;
                while (x >= 0 && dgvBmp.GetPixel(x, halfHeaderH).ToArgb() != dgv.BackgroundColor.ToArgb())
                {
                    borderX++;
                    x--;
                }
                if (x < 0)
                {
                    if(dgv.Width-1 <= widthLimit)
                    {
                        dgv.Width += 100;
                        dgvBmp = new Bitmap(dgv.Width, dgv.Height);
                        dynRecDataGridView.DrawToBitmap(dgvBmp, new Rectangle(0, 0, dgv.Width, dgv.Height));

                        x = dgv.Width - 1;
                    }
                    else
                    {
                        x = widthLimit;
                        borderX = 0;
                    }
                }
            }
            if (x > widthLimit)
            {
                x = widthLimit;
                borderX = 0;
            }
            else if(x < widthLimit)
            {
                while (dgvBmp.GetPixel(x, halfHeaderH).ToArgb() == dgv.BackgroundColor.ToArgb())
                {
                    x--;
                }
            }
            while (y == dgv.Height - 1)
            {
                borderY = 0;
                while (y >= 0  && dgvBmp.GetPixel(halfHeaderW, y).ToArgb() != dgv.BackgroundColor.ToArgb())
                {
                    borderY++;
                    y--;
                }
                if (y < 0)
                {
                    if (dgv.Height-1 <= heightLimit)
                    {
                        dgv.Height += 100;
                        dgvBmp = new Bitmap(dgv.Width, dgv.Height);
                        dynRecDataGridView.DrawToBitmap(dgvBmp, new Rectangle(0, 0, dgv.Width, dgv.Height));

                        y = dgv.Height - 1;
                    }
                    else
                    {
                        y = heightLimit;
                        borderY = 0;
                    }
                }
            }
            if (y > heightLimit)
            {
                y = heightLimit;
                borderY = 0;
            }
            else if (y < heightLimit)
            {
                while (dgvBmp.GetPixel(halfHeaderW, y).ToArgb() == dgv.BackgroundColor.ToArgb())
                {
                    y--;
                }
            }

            dgv.Size = new Size(x+borderX+1, y+borderY+1);

        }


you can just change dataGridView properties To

dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号