C# 如何使用鼠标滚轮使DataGridView一次滚动一个项目?
我们希望在将鼠标滚轮与此控件一起使用时覆盖DataGridView的默认行为。默认情况下,DataGridView滚动的行数等于SystemInformation.MouseWheelScrollLines设置。我们要做的是一次只滚动一个项目 (我们在DataGridView中显示图像,图像有点大。因此,滚动三行(典型的系统设置)太多,通常会导致用户滚动到他们甚至看不到的项目。) 我已经试过几次了,到目前为止还没有成功。以下是我遇到的一些问题:C# 如何使用鼠标滚轮使DataGridView一次滚动一个项目?,c#,.net,datagridview,C#,.net,Datagridview,我们希望在将鼠标滚轮与此控件一起使用时覆盖DataGridView的默认行为。默认情况下,DataGridView滚动的行数等于SystemInformation.MouseWheelScrollLines设置。我们要做的是一次只滚动一个项目 (我们在DataGridView中显示图像,图像有点大。因此,滚动三行(典型的系统设置)太多,通常会导致用户滚动到他们甚至看不到的项目。) 我已经试过几次了,到目前为止还没有成功。以下是我遇到的一些问题: 您可以订阅MouseWheel事件,但无法将事件标
/// <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);
}
//
///由于我们显示
///图像,当您滚动多个图像时,这些图像无法正常工作
///一次一个项目。
///
///
///
///寄件人
///
///
///鼠标事件
///
私有void mImageDataGrid_鼠标滚轮(对象发送器,鼠标指针e)
{
//黑客警报!通过反思,我们知道
//in-event参数实际上是一个已处理的鼠标事件参数,
//让我们自己来处理这件事。
//看http://tinyurl.com/54o7lc 更多信息。
HandledMouseEventArgs handledE=(HandledMouseEventArgs)e;
handledE.Handled=true;
//手动滚动。一次只移动一行。
int rowIndex=mImageDataGrid.FirstDisplayedScrollingRowIndex;
mImageDataGrid.FirstDisplayedScrollingRowIndex=
e、 δ<0?
Math.Min(行索引+1,mImageDataGrid.RowCount-1):
Max(rowIndex-1,0);
}
我会将DataGridView子类化为我自己的自定义控件(您知道,添加一个新的Windows窗体-->自定义控件文件,并将基类从control更改为DataGridView)
然后重写WndProc方法并替换如下内容:
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x20a)
{
int wheelDelta = ((int)m.WParam) >> 16;
// 120 = UP 1 tick
// -120 = DOWN 1 tick
this.FirstDisplayedScrollingRowIndex -= (wheelDelta / 120);
}
else
{
base.WndProc(ref m);
}
}
当然,您将检查是否未将FirstDisplayedScrollingRowIndex设置为超出网格范围的数字,等等。但这非常有效
Richard覆盖onmouseheel而不调用base.onmouseheel应该可以工作。某些滚轮鼠标具有特殊设置,您可能需要自行设置才能使其正常工作。请看这篇文章我只是自己做了一些搜索和测试。我曾经调查并发现了一些事情。
MouseWheel
事件提供了一个MouseEventArgs
参数,但是DataGridView
中的OnMouseWheel()
覆盖将其强制转换为已处理的
。这在处理鼠标滚轮
事件时也起作用OnMouseWheel()
确实会被调用,并且它在DataGridView
的覆盖中使用了SystemInformation.MouseWheelScrollLines
因此:
您确实可以处理MouseWheel
事件,将MouseEventArgs
强制转换为HandledMouseEventArgs
并设置Handled=true
,然后执行所需操作
子类DataGridView
,重写onmouseheel()
您自己,并尝试重新创建我在此处阅读的所有代码,除了用1
替换SystemInformation.mouseheelScrollLines
后者将是一个巨大的痛苦,因为它使用了许多私有变量(包括对滚动条的引用),您必须用自己的替换一些,并使用反射获取/设置其他变量。更新:,因为我现在了解到DataGridView
有一个鼠标滚轮事件,我添加了第二个更简单的覆盖
实现这一点的一种方法是对DataGridView
进行子类化,并覆盖WndProc
,以添加对WM\u mouseweel
消息的特殊处理
此示例捕获鼠标滚轮的移动,并将其替换为调用SendKeys.Send
(这与滚动略有不同,因为它还选择了DataGridView
的下一行/上一行。但它可以工作。)
公共类MyDataGridView:DataGridView
{
私人建筑WM_鼠标轮=0x20a;
受保护的覆盖无效WndProc(参考消息m)
{
如果(m.Msg==WM_鼠标轮)
{
var wheelDelta=((int)m.WParam)>>16;
如果(车轮三角洲<0)
{
SendKeys.Send(“{DOWN}”);
}
如果(车轮三角洲>0)
{
SendKeys.Send(“{UP}”);
}
返回;
}
基准WndProc(参考m);
}
}
第二步(与上述注意事项相同):
公共类MyDataGridView:DataGridView
{
MouseWheel上的受保护覆盖无效(MouseEventArgs e)
{
如果(e.Delta<0)
SendKeys.Send(“{DOWN}”);
其他的
SendKeys.Send(“{UP}”);
}
}
我确实提到了这一点,但我做错了什么。我认为这会起作用(假设有人做得正确!)。谢谢。我认为这是可行的,尽管我选择的答案更简单。
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x20a)
{
int wheelDelta = ((int)m.WParam) >> 16;
// 120 = UP 1 tick
// -120 = DOWN 1 tick
this.FirstDisplayedScrollingRowIndex -= (wheelDelta / 120);
}
else
{
base.WndProc(ref m);
}
}
public class MyDataGridView : DataGridView
{
private const uint WM_MOUSEWHEEL = 0x20a;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MOUSEWHEEL)
{
var wheelDelta = ((int)m.WParam) >> 16;
if (wheelDelta < 0)
{
SendKeys.Send("{DOWN}");
}
if (wheelDelta > 0)
{
SendKeys.Send("{UP}");
}
return;
}
base.WndProc(ref m);
}
}
public class MyDataGridView : DataGridView
{
protected override void OnMouseWheel(MouseEventArgs e)
{
if (e.Delta < 0)
SendKeys.Send("{DOWN}");
else
SendKeys.Send("{UP}");
}
}