SiberianGuy
SiberianGuy

Reputation: 25312

DataGridView AutoSize

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?

Upvotes: 17

Views: 45665

Answers (7)

Vikash Singh
Vikash Singh

Reputation: 131

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

Upvotes: 3

Motomotes
Motomotes

Reputation: 4237

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);

        }

Upvotes: 1

Larry
Larry

Reputation: 18051

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);
    };
}

Upvotes: 6

Ali Gubran
Ali Gubran

Reputation: 1

you can just change dataGridView properties To

dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;

Upvotes: -1

twip
twip

Reputation: 648

This VB.NET translation worked for me:

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

Upvotes: 2

love Computer science
love Computer science

Reputation: 1828

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;
}

Upvotes: 8

Jude Cooray
Jude Cooray

Reputation: 19872

Use the AutoSizeMode and Fill Mode

Upvotes: 3

Related Questions