DataGridView vertical scrollbar not updating properly (Forms bug?)

后端 未结 14 1735
伪装坚强ぢ
伪装坚强ぢ 2021-01-03 23:49

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 proper

相关标签:
14条回答
  • 2021-01-04 00:01

    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.

    0 讨论(0)
  • 2021-01-04 00:02

    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);
    }
    
    0 讨论(0)
  • 2021-01-04 00:06

    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.

    0 讨论(0)
  • 2021-01-04 00:08

    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 });
            }
    
    0 讨论(0)
  • 2021-01-04 00:09

    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();
    
    0 讨论(0)
  • 2021-01-04 00:14

    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.

    0 讨论(0)
提交回复
热议问题