【问题标题】:datagridview Scroll event not firing when scrolling using keyboard使用键盘滚动时未触发datagridview滚动事件
【发布时间】:2024-01-13 22:36:01
【问题描述】:

我试图捕捉用户在 datagridview 中结束水平滚动的那一刻。我需要这个来重新定位网格标题中的按钮。

到目前为止,我所做的是添加我在此链接上找到的 scrollListener:How can I receive the "scroll box" type scroll events from a DataGridView?

这很好用,只是使用键盘滚动不会触发滚动事件。当我将代码中的鼠标悬停在 Scroll 事件上时,它会显示“当滚动框被鼠标或键盘操作移动时发生”。因此,当使用键盘滚动时应该触发该事件,但它不会。

我的代码是这样的:

    bool addScrollListener(DataGridView dgv)
    {
        // capture horizonal scrolling and redirect to s_Scroll. Purpose is to redraw buttons after scrolling
        bool Result = false;

        Type t = dgv.GetType();
        PropertyInfo pi = t.GetProperty("HorizontalScrollBar", BindingFlags.Instance | BindingFlags.NonPublic);
        ScrollBar s = null;

        if (pi != null)
            s = pi.GetValue(dgv, null) as ScrollBar;

        if (s != null)
        {
            s.Scroll += new ScrollEventHandler(s_Scroll);

            Result = true;
        }

        return Result;
    }

    void s_Scroll(object sender, ScrollEventArgs e)
    {
        // if grid is done scrolling horizontal, than redraw our buttons
        if (e.Type == ScrollEventType.EndScroll)
        {
            // code works well, but only get here when scrolling with mouse
            PositionButtons();
        }
    }

所以我的问题是当用户使用鼠标滚动时会触发 s_Scroll 事件,但是当使用键盘滚动时根本不会触发 s_Scroll 事件。

我的问题是如何解决这个问题,以便在这两种情况下都会触发事件, 如果这是不可能的,还有另一种方法可以从 datagridview 捕获水平滚动的结尾。

【问题讨论】:

  • 您是否尝试使用ValueChanged 事件而不是Scroll 事件?
  • 您是否需要要求按钮定位仅在用户完成滚动时发生?
  • ValueChanged 事件听起来不错,但是如何使用它来发现用户已停止水平滚动?当用户按住右箭头键并在滚动例如 8 列后放手时,我想做我的代码,而不是 8 次。

标签: c# datagridview


【解决方案1】:

DataGridView 中,键盘操作由DataGridView 处理以更新当前单元格位置。

您必须使用ScrollBar.ValueChanged 事件并将ScrollBar.ValueScrollBar.Maximum 进行比较才能执行您想要的操作。


您有另一种解决方案来做您想做的事情,而不是在 ScrollBar.Scroll 上添加事件侦听器:处理 DataGridView.Scroll 事件并使用 DataGridView.FirstDisplayedScrollingRowIndex 属性和 DataGridView.DisplayedRowCount(true) 方法验证 datagridview 是否向下滚动。

这样会更简单、更安全。

【讨论】:

  • ValueChanged 事件听起来不错,但是如何使用它来发现用户已停止水平滚动?当用户按住右箭头键并在滚动例如 8 列后放手时,我想做我的代码,而不是 8 次。
  • 您使用滚动事件和 FirstDisplayedScrollingRowIndex 给出的示例,这不适用于垂直滚动而不是水平滚动?我需要它来水平滚动。
  • 它也适用于水平滚动的这些方法:FirstDisplayedScrollingColumnIndexDisplayedColumnCount(true)
  • 对于您的第一条评论:ScrollBar.Value 为您提供滚动位置,因此您可以根据滚动的确切位置与MinimumMaximum 相比运行代码。
  • 原谅我今天有点慢,但是将 Value 属性与 Minumn 和 Maximum 进行比较如何告诉我用户已停止滚动?例如,数据网格有 20 列,用户在第 2 列并按住右箭头直到他在第 16 列。这个时候我需要调用我的代码,所以这个时候我需要知道他停止滚动了。
【解决方案2】:
private void TransactionsDGV_KeyUp(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.End)
    {
        e.Handled = true;
        DataGridViewCell cell = TransactionsDGV.Rows[TransactionsDGV.Rows.Count-2].Cells[0];
        TransactionsDGV.CurrentCell = cell;
        TransactionsDGV.BeginEdit(true);
        TransactionsDGV.EndEdit();
    }

    if (e.KeyCode == Keys.Home)
    {
        e.Handled = true;
        DataGridViewCell cell = TransactionsDGV.Rows[0].Cells[0];
        TransactionsDGV.CurrentCell = cell;
        TransactionsDGV.BeginEdit(true);
        TransactionsDGV.EndEdit();
    }
}

【讨论】:

    最近更新 更多