Вертикальная полоса прокрутки DataGridView не обновляется должным образом (ошибка формы?)

Я столкнулся с ошибкой (предположим) в .NET 3.5. При добавлении строк в DataGridView с помощью Rows.Add(), в то время как DGV отключен, вертикальная полоса прокрутки не обновляется должным образом. Следовательно, вы не можете прокручивать весь путь до нижней части DGV, используя полосу прокрутки или колесико мыши после повторного включения DGV (однако перемещение со стрелками все еще работает.)

Итак, я ищу обходной путь. Есть ли способ заставить панель прокрутки обновить ее границы или вы можете вручную ввести новое максимальное значение? Я бы предпочел не переписывать DGV.

*) На самом деле это родительская форма, которая отключена, но я предполагаю, что проблема заключается в том, что она распространяется на элемент управления DGV.

Ответы

Ответ 1

У меня была эта проблема (моя форма была отключена при добавлении строк) и решила ее, установив для свойства прокрутки сетки значение "Нет" перед добавлением строк, а затем вернув ее "Оба" после того, как все мои строки были добавлены.

Ответ 2

Это также решило проблему для меня:

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

Он может быть вызван до перезапуска DGV.


UPDATE: Это также делает работу:

DataGridView.PerformLayout();

Ответ 3

Если ни одно из других заданных решений не сработало для вас, я столкнулся с аналогичной проблемой с вертикальной полосой прокрутки в DataGridView. Но проблема в том, что, когда число строк выходит за пределы высоты datagridview, вертикальная прокрутка создала испорченный пользовательский интерфейс. Вид строк, перекрывающих друг друга.

У меня был DataGridView с привязкой к данным.

Это список вещей, которые я пробовал, но не работал.

  • Устанавливаем свойство ScrollBars значение None, изменяем источник данных, а затем устанавливаем свойство ScrollBars на Both.
  • Использование SuspendLayout, ResumeLayout и PerformLayout в различных комбинациях.
  • Установите двойной буфер для DataGridView с использованием метода расширения.

Наконец, установка AutoSizeRowsMode на DataGridViewAutoSizeRowsMode.AllCells исправила проблему для меня.

Если у вас есть аналогичная проблема с горизонтальной прокруткой, я думаю, что игра с AutoSizeColumnsMode должна устранить проблему.

Ответ 4

Моя проблема заключалась в том, что моя вертикальная полоса прокрутки полностью исчезла. Я справился со всеми вышеперечисленными предложениями и, наконец, обнаружил, что создание панели, содержащей DataGridView, уже, чем форма, решает проблему. В моем случае работала более 16 пикселей.

Ответ 5

На самом деле, я нашел одно обходное решение, но мне это не нравится. После повторного подключения DGV вы можете сделать это:

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

И затем обновляется полоса прокрутки. Но это не очень красиво, это вызывает раздражающее небольшое мерцание, и это может привести к некоторым событиям, которые я должен сознательно игнорировать. Я немного оставлю вопрос открытым в надежде на лучшее решение.

Ответ 6

Было отмечено, что когда ширина и высота DataGridView1 сравнивались с шириной и высотой формы, а ширина и высота были reset, если они превышали размеры формы, полосы прокрутки стали видимыми.

Попробуйте использовать следующий код, который динамически добавит элемент управления DataGridView в форму и создаст квадратную сетку с именами заголовков строк и столбцов:

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

Ответ 7

Я хотел бы добавить комментарий к исходному сообщению, но пока не могу (менее 50 репутации).

Я столкнулся с той же проблемой при удалении строк. Полоса прокрутки выглядит как отключенная, ползунок не виден, а стрелки серые.
Попробуем обходные пути, описанные здесь, и по этой ссылке (явно включите полосы прокрутки) или просто держите весь DGV включенным.
Кроме того, эта ссылка предлагает одно и то же обходное решение (явно разрешающее...) и вызывает его работу.

Ответ 8

Моя проблема связана с вызовом dgv.Add() в пользовательском потоке. После изменения его для вызова из потока пользовательского интерфейса, полоса прокрутки отображается и работает нормально:

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

Ответ 9

Поскольку слайдер правильно не подбирал размер и занимал большую часть вертикальной полосы прокрутки, мое решение было -

DGV.height = DGV.Height + 1

DGV.Height = DGV.Height - 1

Затем ползунок был правильно установлен

Но теперь я использую

DGV.PerformLayout

который также решает проблему

Ответ 10

Я нашел ваше сообщение во время поиска исправления проблемы, которую я имел. То, что я встретил на моей Microsoft Surface (Win10), заключалось в невозможности вертикального прокрутки DataGridView до последней строки длинного списка с помощью жестов касания (например, щелчка). Часто последняя строка была безумно трудной для достижения. Решение было простым, но мне потребовалось некоторое время, чтобы понять. Я оставляю это здесь, если это будет полезно.

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

Ответ 11

Мое решение состояло в том, чтобы отключить полосы прокрутки от его свойств. Затем включите их из строки кода после инициализации окна. DataGridViewObj.ScrollBars = ScrollBars.Both

Ответ 12

Последние две строки моего DataGridView всегда были скрыты на моих WinForms. Я мог бы прокручивать их с помощью клавиши со стрелкой клавиатуры (но все равно не вижу, на какой строке я был на самом деле). Колесо мыши и стрелка вниз по стрелке не попадут к ним. Только с небольшим набором данных и максимизацией формы я мог бы увидеть последние две строки.

Вот как я исправил проблему: я поместил DataGridView в Panel. BAM!

Это также устранило еще одну проблему с DataGridView: когда я изменил размер заголовков столбцов, на экране управления DataGridView появятся странные вертикальные линии. Это было очень уродливо и непрофессионально. Но теперь это исправлено.