如何使用鼠标滚轮一次使DataGridView滚动一个项目?

Ken*_*ton 7 .net c# datagridview

当使用具有此控件的鼠标滚轮时,我们想要覆盖DataGridView的默认行为.默认情况下,DataGridView滚动的行数等于SystemInformation.MouseWheelScrollLines设置.我们想要做的是一次只滚动一个项目.

(我们在DataGridView中显示图像,它们有点大.由于这个滚动三行(典型的系统设置)太多,经常导致用户滚动到他们甚至看不到的项目.)

我已经尝试了几件事,到目前为止还没有取得多大成功.以下是我遇到的一些问题:

  1. 您可以订阅MouseWheel事件,但无法将事件标记为已处理并执行自己的操作.

  2. 您可以覆盖OnMouseWheel,但似乎从未调用过.

  3. 您可能能够在基本滚动代码中更正此问题,但这听起来像一个混乱的工作,因为其他类型的滚动(例如使用键盘)来自同一个管道.

有人有个好主意吗?

这是最终的代码,使用给出的精彩答案:

    /// <summary>
    /// Handle the mouse wheel manually due to the fact that we display
    /// images, which don't work well when you scroll by more than one
    /// item at a time.
    /// </summary>
    /// 
    /// <param name="sender">
    /// sender
    /// </param>
    /// <param name="e">
    /// the mouse event
    /// </param>
    private void mImageDataGrid_MouseWheel(object sender, MouseEventArgs e)
    {
        // Hack alert!  Through reflection, we know that the passed
        // in event argument is actually a handled mouse event argument,
        // allowing us to handle this event ourselves.
        // See http://tinyurl.com/54o7lc for more info.
        HandledMouseEventArgs handledE = (HandledMouseEventArgs) e;
        handledE.Handled = true;

        // Do the scrolling manually.  Move just one row at a time.
        int rowIndex = mImageDataGrid.FirstDisplayedScrollingRowIndex;
        mImageDataGrid.FirstDisplayedScrollingRowIndex =
            e.Delta < 0 ?
                Math.Min(rowIndex + 1, mImageDataGrid.RowCount - 1):
                Math.Max(rowIndex - 1, 0);
    }
Run Code Online (Sandbox Code Playgroud)

Joe*_*ant 4

我只是自己做了一些搜索和测试。我使用Reflector进行了调查并发现了一些事情。该MouseWheel事件提供了一个MouseEventArgs参数,但OnMouseWheel()重写将DataGridView其转换为。这在处理事件时也适用。确实被调用,并且它使用的是在 的 override中。HandledMouseEventArgsMouseWheelOnMouseWheel()DataGridViewSystemInformation.MouseWheelScrollLines

所以:

  1. 您确实可以处理该MouseWheel事件,将其转换MouseEventArgsHandledMouseEventArgs并设置Handled = true,然后执行您想要的操作。

  2. 子类化DataGridView,重写自己,并尝试重新创建我在ReflectorOnMouseWheel()中阅读的所有代码,除了替换为.SystemInformation.MouseWheelScrollLines1

后者将是一个巨大的痛苦,因为它使用了许多私有变量(包括对 s 的引用ScrollBar),并且您需要用自己的变量替换一些变量,并使用反射获取/设置其他变量。