18

I've encountered a bug (I assume) in .NET 3.5. When adding rows to a DataGridView using Rows.Add(), while the DGV is disabled, the vertical scrollbar doesn't update properly. Consequently you can't scroll all the way to the bottom of the DGV using the scrollbar or the mouse wheel after reenabling the DGV (navigating with arrow keys still works, though.)

So I'm looking for a workaround. Is there a way to force the scrollbar to update its bounds or can you manually input a new maximum value? I'd rather not have to repopulate the DGV.

*) Actually, it's the parent form that's disabled, but I assume the problem is that it propagates to the DGV control.

ReturningTarzan
  • 1,068
  • 1
  • 13
  • 23

13 Answers13

22

This also solved the problem for me:

DataGridView.SuspendLayout();
DataGridView.ResumeLayout();

It can be called before the DGV is re-enabled.


UPDATE: This also does the job:

DataGridView.PerformLayout();
Mylodon
  • 221
  • 2
  • 4
  • I had a problem with scrollbars disabled with autosizemode.fill, doing the performlayout after changing the content worked for me too. Thanks! you saved my day! – MazarD Mar 17 '14 at 20:05
  • 3
    This should be the accepted answer. Helped me too. Thank you! – Robert S. Nov 12 '15 at 12:56
  • 1
    I got the same problem with a `DataGridView` on a `TabPage`. The simple line `DataGridView.PerformLayout()` solved the problem. Thx. – Sebastian Brosch Jul 27 '16 at 08:15
  • This worked for me too. I did not have the DGV disabled, but it was hidden while adding new rows programmatically. I had to call `myDGV.PerformLayout()` at the moment `myDGV` was about to be shown to make it work. – BillyJoe Oct 21 '19 at 10:27
15

I've just had this problem (my form was disabled while adding rows) and solved it by setting the scrollbar property of the grid to 'None' before adding the rows then setting it back to 'Both' once all my rows have been added.

user1169275
  • 174
  • 3
2

My problem was that my vertical scrollbar disappeared completely. I flailed with all of the above suggestions and finally discovered that making the panel containing the DataGridView narrower than the form solved the problem. In my case, 16 pixels narrower worked.

DWALK
  • 21
  • 2
1

If none of the other given solution worked for you, I came across a similar issue with vertical scrollbar in DataGridView. But the issue is like whenever the number of rows extend beyond the height of the datagridview, vertical scrolling created a messed up UI. Kind of rows overlapping each other.

I had a databound DataGridView.

These are the list of things I tried but didn't work.

  1. Setting the ScrollBars property to None, modify datasource and then set the ScrollBars property to Both.
  2. Using SuspendLayout, ResumeLayout and PerformLayout at various combinations.
  3. Set Double Buffering for the DataGridView using extension method.

Finally, Setting AutoSizeRowsMode to DataGridViewAutoSizeRowsMode.AllCells fixed the issue for me.

If you have similar issue with horizontal scrolling, I think playing with AutoSizeColumnsMode should fix the issue.

Venkatesh Kumar
  • 642
  • 1
  • 7
  • 19
1

As the slider was not sizing correctly and took up most of the vertical scrollbar my solution was -

DGV.height = DGV.Height + 1

DGV.Height = DGV.Height - 1

Then the slider was correctly sized

But I now use

DGV.PerformLayout

which also solves the problem

Tony
  • 49
  • 4
1

For me the problem was that I put my datagrid in a TabPage which was not displayed during data generation time so the srolling was messed up.

I found a was to make a correct update just by auto diable/enable at each visible change :

public MyForm()
{
    InitializeComponent();

    // Automatic scroll to bottom (it might not work if you try to do it without this event)
    datagrid.RowsAdded += (sender, e) =>
    {
        datagrid.FirstDisplayedScrollingRowIndex = datagrid.RowCount - 1;
    };

    // WinForms bug fix: scrollbar update
    datagrid.VisibleChanged += (sender, e) =>
    {
        Enabled = false;
        Enabled = true;
    };
}
56ka
  • 1,463
  • 1
  • 21
  • 37
0

It was observed that, when the DataGridView1's width and height were compared with the width and height of the form, and the width and height were reset if they exceeded the form's dimensions, the scroll bars became visible.

Try the following code, which will dynamically add a DataGridView control to a Form and create a square grid with row and column header names:

  Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        'Following code adds a Datagridview control to a Form dynamically
        'Step 1.  Add a textbox to a Form, and input the number of columns (ncol). (Note: in this example, ncol=nrow).   
        'Step 2.  Set the Form's Windowstate property to Maximized
        For Each cont As Control In Me.Controls 'remove DataGridView if it already exists on the Form
            If TypeOf (cont) Is DataGridView Then
                Me.Controls.Remove(cont)
            End If
        Next
        Dim DataGridView1 As New DataGridView 'create new data grid view dynamically during run-time
        Me.Controls.Add(DataGridView1) 'add the data grid view to the Form
        Me.Refresh()
        Dim i, nrow, ncol As Integer ' ncol=nrow -->this is a square grid
        ncol = TextBox1.Text
        nrow = ncol 'Note: add a second textbox to the form and input nrow if you don't want a square grid
        DataGridView1.Visible = True
        DataGridView1.Top = 100
        DataGridView1.Left = 100
        DataGridView1.Rows.Clear()
        Do While DataGridView1.Columns.Count > 0
            DataGridView1.Columns.RemoveAt(DataGridView1.Columns.Count - 1)
        Loop
        For i = 1 To ncol
            DataGridView1.Columns.Add(i, "V" & i)
        Next
        DataGridView1.Width = ncol * 115
        DataGridView1.Height = nrow * 22 + 45
        If DataGridView1.Width > Me.Width - DataGridView1.Left Then DataGridView1.Width = Me.Width - DataGridView1.Left - 20
        If DataGridView1.Height > Me.Height - DataGridView1.Top Then DataGridView1.Height = Me.Height - DataGridView1.Top - 50
        DataGridView1.ScrollBars = ScrollBars.None
        For i = 1 To nrow
            DataGridView1.Rows.Add()
            DataGridView1.Rows.Item(i - 1).HeaderCell.Value = "V" & i
        Next
        DataGridView1.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders)
        Dim dgvColumnHeaderStyle As New DataGridViewCellStyle()
        dgvColumnHeaderStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
        DataGridView1.ColumnHeadersDefaultCellStyle = dgvColumnHeaderStyle
        DataGridView1.AllowUserToAddRows = False
        DataGridView1.ScrollBars = ScrollBars.Both
        Me.WindowState = FormWindowState.Maximized
    End Sub
0

I would like to add a comment to the original post, but I can't yet (lower than 50 reputation).

I have encountered the same problem on deleting rows. The scrollbar looks like disabled, no slider is visible and the arrows are grey.
Will try the workarounds described here and at this link (explicitly enable the scrollbars again) or simply keep the whole DGV enabled.
Also, this link suggests the same workaround (explicitly enabling...) and calls it working.

Tobias Knauss
  • 3,361
  • 1
  • 21
  • 45
0

My problem stemmed from calling dgv.Add() in a user thread. After changing it to be called from the UI thread instead, the scroll bar displayed and functioned normally:

        if (dataGridView1.InvokeRequired)
        {
            dataGridView1.Invoke((Action)(() => dataGridView1.Rows.Add(new String[] { abc, efg })));
        }
        else
        {
            dataGridView1.Rows.Add(new String[] { calPoint, logUrl });
        }
Arvind
  • 93
  • 8
0

My solution was to disable scrollbars from it's properties. Then enable them from code line after initializing the window. DataGridViewObj.ScrollBars = ScrollBars.Both

Zunair
  • 1,085
  • 1
  • 13
  • 21
0

I had this problem too. It seems to be related to having the table embedded in a TabPage.

I tried all of the other answers in turn. The solution that ultimately worked for me was to do the following after adding all the rows/updating the table.

this.Height -= 5;
this.PerformLayout();
this.Height += 5;
this.PerformLayout();

This is in my own modified DataGridView class (hence the use of "this"). You'd just substitute the name of your DataGridView.

Andrew17856
  • 161
  • 13
0

Actually, I just found one workaround but I don't like it. After the DGV is reenabled you can do this:

int x = Rows.Add();
Rows.RemoveAt(x);

And then the scrollbar is updated. But it's not very pretty, it causes an annoying little flicker, and it might fire some events which I'd have to deliberately ignore. I'll leave the question open for a bit in the hope of a better solution.

ReturningTarzan
  • 1,068
  • 1
  • 13
  • 23
-2

The last two rows of my DataGridView were always hidden on my WinForms. I could scroll to them using the keyboard down arrow key (but still not see which row I was actually on). The mouse wheel and scrollbar down arrow would not get to them either. Only with a small data set and maximizing the form could I see the last two rows.

Here is how I fixed the problem: I placed the DataGridView in a Panel. BAM!

It also fixed another problem with the DataGridView, that when I resized a column headers weird vertical lines would appear on any UI control below the DataGridView. It was very ugly and unprofessional looking. But now it is fixed too.