.net DataGridView 垂直滚动条未正确更新(表单错误?)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8632375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 16:07:56  来源:igfitidea点击:

DataGridView vertical scrollbar not updating properly (Forms bug?)

.netdatagridviewscrollbar

提问by ReturningTarzan

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

我在 .NET 3.5 中遇到了一个错误(我假设)。使用 Rows.Add() 向 DataGridView 添加行时,在禁用 DGV 的情况下,垂直滚动条不会正确更新。因此,您无法在重新启用 DGV 后使用滚动条或鼠标滚轮一直滚动到 DGV 的底部(不过,使用箭头键导航仍然有效。)

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.

所以我正在寻找一种解决方法。有没有办法强制滚动条更新其边界,或者您可以手动输入新的最大值?我宁愿不必重新填充 DGV。

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

*) 实际上,禁用的是父窗体,但我认为问题在于它会传播到 DGV 控件。

采纳答案by user1169275

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.

我刚刚遇到了这个问题(我的表单在添加行时被禁用)并通过在添加行之前将网格的滚动条属性设置为“无”然后在添加所有行后将其设置回“两者”来解决它.

回答by Mylodon

This also solved the problem for me:

这也为我解决了问题:

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

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

可以在重新启用 DGV 之前调用它。



UPDATE: This also does the job:

更新:这也可以完成这项工作:

DataGridView.PerformLayout();

回答by DWALK

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.

我的问题是我的垂直滚动条完全消失了。我对上述所有建议感到不满,最后发现使包含 DataGridView 的面板比表单更窄解决了问题。就我而言,缩小 16 个像素有效。

回答by 56ka

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

对我来说,问题是我将数据网格放在了TabPage数据生成期间未显示的a 中,因此滚动被搞砸了。

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

我发现只需在每个可见更改时自动禁用/启用即可进行正确更新:

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

回答by Venkatesh Kumar

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.

如果其他给定的解决方案都不适合您,我在 DataGridView 中遇到了与垂直滚动条类似的问题。但问题是,每当行数超出 datagridview 的高度时,垂直滚动就会创建一个混乱的 UI。一种相互重叠的行。

I had a databound DataGridView.

我有一个数据绑定 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.
  1. 将 ScrollBars 属性设置为 None,修改数据源,然后将 ScrollBars 属性设置为 Both。
  2. 以各种组合使用 SuspendLayout、ResumeLayout 和 PerformLayout。
  3. 使用扩展方法为 DataGridView 设置双缓冲。

Finally, Setting AutoSizeRowsModeto DataGridViewAutoSizeRowsMode.AllCellsfixed the issue for me.

最后,将AutoSizeRowsMo​​de设置为DataGridViewAutoSizeRowsMo​​de.AllCells为我解决了这个问题。

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

如果你有类似的水平滚动问题,我认为使用AutoSizeColumnsMode应该可以解决这个问题。

回答by Tony

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

DGV.Height = DGV.Height - 1

DGV.Height = DGV.Height - 1

Then the slider was correctly sized

然后滑块的大小正确

But I now use

但我现在用

DGV.PerformLayout

DGV.PerformLayout

which also solves the problem

这也解决了问题

回答by ReturningTarzan

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

实际上,我只是找到了一种解决方法,但我不喜欢它。重新启用 DGV 后,您可以执行以下操作:

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.

然后滚动条更新。但它不是很漂亮,它会导致令人讨厌的小闪烁,并且它可能会触发一些我不得不故意忽略的事件。我将问题悬而未决,希望有更好的解决方案。

回答by ReturningTarzan

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.

观察到,当DataGridView1的宽高与窗体的宽高进行比较时,如果超过窗体的尺寸,则宽高被重置,滚动条变得可见。

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:

试试下面的代码,它会动态地将一个 DataGridView 控件添加到一个 Form 并创建一个带有行和列标题名称的方形网格:

  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

回答by Tobias Knauss

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

我想对原始帖子添加评论,但我还不能(低于 50 声望)。

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.

我在删除行时遇到了同样的问题。滚动条看起来像是被禁用了,没有滑块可见,箭头是灰色的。
将尝试此处和此链接中描述的变通方法(再次显式启用滚动条)或简单地保持整个 DGV 启用。
此外,此链接建议使用相同的解决方法(显式启用...)并称其有效。

回答by Arvind

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:

我的问题源于在用户线程中调用 dgv.Add()。改为从UI线程调用后,滚动条显示和功能正常:

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