DataGridView MouseWheel sendkeys 上下问题
DataGridView MouseWheel sendkeys updown issue
我创建了一个子类 datagridview 来覆盖鼠标滚轮事件以捕获鼠标滚动,然后发送向上键或向下键。我创建了一个数据表,通过单击按钮
绑定为 mydatagridview 的数据源
private void button1_Click(object sender, EventArgs e)
{
DataTable myDataTable = new DataTable();
int NUM_ROWS = 150;
int NUM_COLS_TO_CREATE = 10;
for (int i = 0; i < NUM_COLS_TO_CREATE; i++)
{
myDataTable.Columns.Add("x" + i, typeof(string));
}
for (int i = 0; i < NUM_ROWS; i++)
{
var theRow = myDataTable.NewRow();
for (int j = 0; j < NUM_COLS_TO_CREATE; j++)
{
theRow[j] = "whatever";
}
//add the row *after* populating it
myDataTable.Rows.Add(theRow);
}
MyDataGridView1.DataSource = myDataTable;
}
覆盖鼠标滚轮事件的代码如此
public partial class MyDataGridView : DataGridView
{
protected override void OnMouseWheel(MouseEventArgs e)
{
if (e.Delta < 0)
SendKeys.Send("{DOWN}");
else
SendKeys.Send("{UP}");
}
}
如果我们使用鼠标滚轮以缓慢的方式滚动每个项目,它工作正常,但如果您使用鼠标滚轮滚动得太快,则 datagridview 会有些滞后。
例如从第1行到第5行,它会从第1行跳到第3行,然后从第3行跳到第5行之类的,这里又出现了一个奇怪的问题。我每天使用 "Navicat" 很多..
所以如果我同时打开我的应用程序和 Navicat。即使我滚动得太快,鼠标滚轮滚动现在在我的应用程序上也变得非常流畅。但是如果我关闭 Navicat 然后滚动再次变得滞后。是什么原因造成的?如果我不能很好地解释,我很抱歉,我只想让每个项目的滚动顺畅。有什么建议吗?
SendKeys
方法在精确计时方面并不可靠 - 请参阅 official documentation。尝试将 "SendKeys" 应用程序设置设置为 "SendInput" 以强制执行新行为。
但是您最好处理 MouseWheel
事件而不是覆盖 它。您需要手动挂钩它 - 不确定为什么它没有出现在 属性 Window 中。鉴于您的 DataGridView
被命名为 dgv
:
private void Form1_Load(object sender, EventArgs e)
{
dgv.MouseWheel += Dgv_MouseWheel;
}
接下来,你考虑过FirstDisplayedScrollingRowIndex吗?在事件中适当设置即可,设置Handled
标志,像这样:
private void dgv_MouseWheel(object sender, MouseEventArgs e)
{
dgv.FirstDisplayedScrollingRowIndex += 3;
var he = (HandledMouseEventArgs);
he.Handled = true;
}
正如@Bozhidar 提到的,我应该更好地处理 MouseWheel 事件而不是或覆盖它。所以我想出了解决方案,以防万一有人需要它。
在Form_Load中添加
MyDataGridView1.MouseWheel += new MouseEventHandler(MyDataGridView1_MouseWheel);
然后将其放在 class
中的任意位置
private void MyDataGridView1_MouseWheel(object sender, MouseEventArgs e)
{
HandledMouseEventArgs hme = (HandledMouseEventArgs)e;
hme.Handled = true;
int rowIndex = MyDataGridView1.CurrentCell.RowIndex;
int cellIndex = MyDataGridView1.CurrentCell.ColumnIndex;
MyDataGridView1.CurrentCell = MyDataGridView1.Rows[e.Delta < 0 ? Math.Min(rowIndex + 1, MyDataGridView1.RowCount - 1) : Math.Max(rowIndex - 1, 0)].Cells[cellIndex];
}
这是一种保留滚动视口的默认滚动行为但不更改行选择的方法。
当在虚拟网格中处理数百万行时,它的执行速度也比内置鼠标滚轮处理程序快得多:
private void Form1_Load(object sender, EventArgs e)
{
DataGridView1.MouseWheel += DataGridView1_MouseWheel;
}
private void DataGridView1_MouseWheel(object sender, MouseEventArgs e)
{
var hme = e as HandledMouseEventArgs;
hme.Handled = true;
int displayedRowIndex = DataGridView1.FirstDisplayedScrollingRowIndex;
// each "detente" scroll appears to create a delta of 120
// dividing delta by 120 to get the number of rows scrolled
// taking the negative of the delta so that it can be added to the displayedRowIndex intuitively as negative is down, positive is up
var rowDelta = -(e.Delta / 120);
var newDisplayedRowIndex = e.Delta < 0 ? Math.Min(displayedRowIndex + rowDelta, DataGridView1.RowCount - 1) : Math.Max(displayedRowIndex + rowDelta, 0);
DataGridView1.FirstDisplayedScrollingRowIndex = newDisplayedRowIndex;
}
我创建了一个子类 datagridview 来覆盖鼠标滚轮事件以捕获鼠标滚动,然后发送向上键或向下键。我创建了一个数据表,通过单击按钮
绑定为 mydatagridview 的数据源 private void button1_Click(object sender, EventArgs e)
{
DataTable myDataTable = new DataTable();
int NUM_ROWS = 150;
int NUM_COLS_TO_CREATE = 10;
for (int i = 0; i < NUM_COLS_TO_CREATE; i++)
{
myDataTable.Columns.Add("x" + i, typeof(string));
}
for (int i = 0; i < NUM_ROWS; i++)
{
var theRow = myDataTable.NewRow();
for (int j = 0; j < NUM_COLS_TO_CREATE; j++)
{
theRow[j] = "whatever";
}
//add the row *after* populating it
myDataTable.Rows.Add(theRow);
}
MyDataGridView1.DataSource = myDataTable;
}
覆盖鼠标滚轮事件的代码如此
public partial class MyDataGridView : DataGridView
{
protected override void OnMouseWheel(MouseEventArgs e)
{
if (e.Delta < 0)
SendKeys.Send("{DOWN}");
else
SendKeys.Send("{UP}");
}
}
如果我们使用鼠标滚轮以缓慢的方式滚动每个项目,它工作正常,但如果您使用鼠标滚轮滚动得太快,则 datagridview 会有些滞后。
例如从第1行到第5行,它会从第1行跳到第3行,然后从第3行跳到第5行之类的,这里又出现了一个奇怪的问题。我每天使用 "Navicat" 很多..
所以如果我同时打开我的应用程序和 Navicat。即使我滚动得太快,鼠标滚轮滚动现在在我的应用程序上也变得非常流畅。但是如果我关闭 Navicat 然后滚动再次变得滞后。是什么原因造成的?如果我不能很好地解释,我很抱歉,我只想让每个项目的滚动顺畅。有什么建议吗?
SendKeys
方法在精确计时方面并不可靠 - 请参阅 official documentation。尝试将 "SendKeys" 应用程序设置设置为 "SendInput" 以强制执行新行为。
但是您最好处理 MouseWheel
事件而不是覆盖 它。您需要手动挂钩它 - 不确定为什么它没有出现在 属性 Window 中。鉴于您的 DataGridView
被命名为 dgv
:
private void Form1_Load(object sender, EventArgs e)
{
dgv.MouseWheel += Dgv_MouseWheel;
}
接下来,你考虑过FirstDisplayedScrollingRowIndex吗?在事件中适当设置即可,设置Handled
标志,像这样:
private void dgv_MouseWheel(object sender, MouseEventArgs e)
{
dgv.FirstDisplayedScrollingRowIndex += 3;
var he = (HandledMouseEventArgs);
he.Handled = true;
}
正如@Bozhidar 提到的,我应该更好地处理 MouseWheel 事件而不是或覆盖它。所以我想出了解决方案,以防万一有人需要它。
在Form_Load中添加
MyDataGridView1.MouseWheel += new MouseEventHandler(MyDataGridView1_MouseWheel);
然后将其放在 class
中的任意位置private void MyDataGridView1_MouseWheel(object sender, MouseEventArgs e)
{
HandledMouseEventArgs hme = (HandledMouseEventArgs)e;
hme.Handled = true;
int rowIndex = MyDataGridView1.CurrentCell.RowIndex;
int cellIndex = MyDataGridView1.CurrentCell.ColumnIndex;
MyDataGridView1.CurrentCell = MyDataGridView1.Rows[e.Delta < 0 ? Math.Min(rowIndex + 1, MyDataGridView1.RowCount - 1) : Math.Max(rowIndex - 1, 0)].Cells[cellIndex];
}
这是一种保留滚动视口的默认滚动行为但不更改行选择的方法。
当在虚拟网格中处理数百万行时,它的执行速度也比内置鼠标滚轮处理程序快得多:
private void Form1_Load(object sender, EventArgs e)
{
DataGridView1.MouseWheel += DataGridView1_MouseWheel;
}
private void DataGridView1_MouseWheel(object sender, MouseEventArgs e)
{
var hme = e as HandledMouseEventArgs;
hme.Handled = true;
int displayedRowIndex = DataGridView1.FirstDisplayedScrollingRowIndex;
// each "detente" scroll appears to create a delta of 120
// dividing delta by 120 to get the number of rows scrolled
// taking the negative of the delta so that it can be added to the displayedRowIndex intuitively as negative is down, positive is up
var rowDelta = -(e.Delta / 120);
var newDisplayedRowIndex = e.Delta < 0 ? Math.Min(displayedRowIndex + rowDelta, DataGridView1.RowCount - 1) : Math.Max(displayedRowIndex + rowDelta, 0);
DataGridView1.FirstDisplayedScrollingRowIndex = newDisplayedRowIndex;
}