DataGridView vertical scrollbar not updating prope

2019-04-18 11:14发布

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.

13条回答
成全新的幸福
2楼-- · 2019-04-18 11:41

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.

查看更多
三岁会撩人
3楼-- · 2019-04-18 11:46

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.

查看更多
不美不萌又怎样
4楼-- · 2019-04-18 11:46

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.

查看更多
放荡不羁爱自由
5楼-- · 2019-04-18 11:48

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.

查看更多
时光不老,我们不散
6楼-- · 2019-04-18 11:49

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

查看更多
混吃等死
7楼-- · 2019-04-18 11:50

I found your post while searching for a fix for the issue I was having. What I encountered on my Microsoft Surface (Win10) was the inability to vertical scroll the DataGridView to the very last line of a long list using a touch gesture (like flick). Frequently, the last line was maddeningly hard to get to. The solution was simple but took me a while to figure out. I'm leaving it here in case it's helpful.

// Override WndProc in your custom class inherited from DataGridView
protected override void WndProc(ref Message m)
{
  switch (m.Msg)
  {
    case 0x115:// WM_VSCROLL
      // The low-order word holds the command
      uint cmd = ((uint)m.WParam & (uint)0x0000FFFF);
      switch (cmd)
      {
        case 5: // SB_THUMBTRACK
          if (Rows.Count > 0)
          {
            // The high-order word holds the position
            uint pos = ((uint)m.WParam & (uint)0xFFFF0000) >> 16;

            // SAVE: This would give us the "true" ratio based on 100%
            // SAVE: double ratio = (double)pos / (double)(VerticalScrollBar.Maximum - VerticalScrollBar.LargeChange);
            // SAVE: Debug.WriteLine("Scroll Position: " + pos + "\t" + (ratio * 100.0).ToString("F2") + "%");

            // What we want is the ratio to the TOP of the thumb, BECAUSE
            // THIS GIVES US THE RATIO TO THE FIRST LINE INDEX
            double firstLineRatio = (double)pos / (double)(VerticalScrollBar.Maximum);
            // We want to make it so that it shows the full line 
            // even if we just barely meet the ratio
            double dFirstLine = firstLineRatio * Rows.Count;
            int iFirstLine = (int)(dFirstLine + 0.9999);
            // SAVE: Debug.WriteLine("Scroll Position: " + pos + "\t" + (ratio * 100.0).ToString("F2") + "%");
            FirstDisplayedScrollingRowIndex = iFirstLine;
            // We do this INSTEAD OF the default for this message, so RETURN
            return;
          }
          break;
      }
      break;
    default:
      break;
  }
  base.WndProc(ref m);
}
查看更多
登录 后发表回答