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

发布于 2024-12-22 18:09:35 字数 262 浏览 1 评论 0原文

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

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

嘴硬脾气大 2024-12-29 18:09:35

这也为我解决了问题:

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

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


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

DataGridView.PerformLayout();

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();
漆黑的白昼 2024-12-29 18:09:35

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

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.

白云不回头 2024-12-29 18:09:35

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

我有一个数据绑定 DataGridView。

这些是我尝试过但没有成功的事情的列表。

  1. 将 ScrollBars 属性设置为 None,修改数据源,然后将 ScrollBars 属性设置为 Both。
  2. 以各种组合使用 SuspendLayout、ResumeLayout 和 PerformLayout。
  3. 使用扩展方法为 DataGridView 设置双缓冲。

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

如果您在水平滚动方面遇到类似问题,我认为使用 AutoSizeColumnsMode 应该可以解决该问题。

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.

愁杀 2024-12-29 18:09:35

我的问题是我的垂直滚动条完全消失了。我尝试了上述所有建议,最终发现使包含 DataGridView 的面板比表单窄可以解决问题。就我而言,缩小 16 像素是可行的。

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.

看春风乍起 2024-12-29 18:09:35

由于滑块的大小不正确并占据了大部分垂直滚动条,我的解决方案是 -

DGV.height = DGV.Height + 1

DGV.Height = DGV.Height - 1

然后滑块的大小正确

但我现在使用

DGV.PerformLayout

这也解决了问题

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

红尘作伴 2024-12-29 18:09:35

对我来说,问题是我将数据网格放在 TabPage 中,该标签在数据生成期间未显示,因此滚动混乱。

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

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

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;
    };
}
心是晴朗的。 2024-12-29 18:09:35

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

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

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

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.

云之铃。 2024-12-29 18:09:35

据观察,当 DataGridView1 的宽度和高度与表单的宽度和高度进行比较时,如果宽度和高度超出表单的尺寸,则重置宽度和高度,滚动条变得可见。

尝试以下代码,它将动态地将 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'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

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
可遇━不可求 2024-12-29 18:09:35

我想在原始帖子中添加评论,但目前还不能(声誉低于 50)。

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

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.

-黛色若梦 2024-12-29 18:09:35

我的问题源于在用户线程中调用 dgv.Add() 。将其更改为从 UI 线程调用后,滚动条显示并正常运行:

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

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 });
        }
相权↑美人 2024-12-29 18:09:35

我的解决方案是从其属性中禁用滚动条。
然后在初始化窗口后从代码行启用它们。
DataGridViewObj.ScrollBars = ScrollBars.Both

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

哑剧 2024-12-29 18:09:35

我也有这个问题。这似乎与将表格嵌入到 TabPage 中有关。

我依次尝试了所有其他答案。最终对我有用的解决方案是在添加所有行/更新表后执行以下操作。

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

这是我自己修改的 DataGridView 类中的(因此使用“this”)。您只需替换 DataGridView 的名称即可。

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.

老街孤人 2024-12-29 18:09:35

我的 DataGridView 的最后两行始终隐藏在我的 WinForms 上。我可以使用键盘向下箭头键滚动到它们(但仍然看不到我实际位于哪一行)。鼠标滚轮和滚动条向下箭头也无法到达它们。只有使用小数据集并最大化表单才能看到最后两行。

以下是我解决问题的方法:我将 DataGridView 放置在面板中。嘭!

它还修复了 DataGridView 的另一个问题,即当我调整列标题大小时,DataGridView 下面的任何 UI 控件上都会出现奇怪的垂直线。它看起来非常丑陋且不专业。但现在它也被修复了。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文