DataGridView鼠标轮轴sendkeys Updown问题



i创建一个子类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的第5行跳到另一个奇怪的问题。我每天都在使用" navicat"。

因此,如果我同时打开了我的应用程序和Navicat。现在,即使我滚动太快,鼠标滚动滚动的滚动也会变得非常流畅。但是,如果我关闭Navicat,然后滚动再次落后。是什么原因造成的?如果我不能很好地解释,我感到非常抱歉,我想要的只是要使滚动每个物品光滑。有任何建议吗?

@bozhidar提到,我应该更好地处理鼠标轮事件或覆盖它。因此,我想出了解决方案,以防万一也需要它。

在form_load中添加

MyDataGridView1.MouseWheel += new MouseEventHandler(MyDataGridView1_MouseWheel);

然后将其放在班级中的任何地方

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

SendKeys方法在确切的时机时不那么可靠 - 请参阅官方文档。尝试将" sendkeys"应用程序设置设置为" sendInput",以强迫新行为。

但是,您会更好地处理 MouseWheel事件,而不是覆盖 it。您需要手工连接它 - 不确定为什么它不存在于属性窗口中。鉴于您的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;
}

这是一种保留滚动视口的默认滚动行为,但不更改行选择的方法。

当在虚拟网格中处理数百万行时,它的性能也比内置的鼠标车轮处理程序快得多:

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

最新更新