按住DataGridView中的箭头键不能平滑地移动光标

时间:2018-01-12 14:27:49

标签: c# datagridview arrow-keys

如果我按住向上或向下箭头键,当聚焦在DataGridView上时,光标(蓝色突出显示的单元格)不会在行中均匀移动,而是跳跃批次一次几行。有时它甚至似乎都没有移动,直到钥匙最终被释放,然后光标直接跳到前面的几行,可能存储了所有按键。

Here is a GIF image showing the behaviour when pressing and holding the DOWN arrow, then releasing it and pressing and holding the UP arrow.

此移动看起来不对,并且使用户难以判断何时释放键以在几行上平滑导航。它甚至似乎都不会在每次跳跃时移动多行(每次跳转时有10-20行,有时是整个页面,甚至在用户最终释放密钥时再次出现很多行)。

例如,如果用户想要将光标移动到页面的一半左右,按下向下箭头键并按住它,则很难知道何时释放键,因为光标没有向下移动在一个平稳的进步。

为什么它不会以平滑的重复方式一次一个地移动到每一行,而不是在批次行上进行丑陋的跳跃?

这可以转载如下:

  • 制作新表格项目。
  • 将DataGridView控件拖放到表单上。
  • 在设计器中添加DataGridViewTextBoxColumn。
  • 在DataGridView中添加一些行,并添加一些格式,以便在FormLoad事件中为测试提供足够的行:

    private void Form1_Load(object sender, EventArgs e)
    {
        dataGridView1.RowTemplate.Height = 14;
        dataGridView1.Rows.Add(50);
        dataGridView1.Dock = DockStyle.Fill;
    }
    

然后运行程序并按按住向下箭头键,看看蓝色突出显示如何奇怪地向下跳跃,而不是从一行到另一行顺利向下移动。

即使DataGridView是只读的,也存在奇怪的行为。

我已尝试制作网格和DoubleBuffered格式,但没有成功。我也尝试将网格设置为虚拟模式和ReadOnly并更改网格的每个设置,但没有任何作用。

我发现的唯一方法是让光标在没有跳过批量行的情况下平滑地快速向上或向下移动行,一直是不让DataGridView被聚焦。为此,我在窗体上进行另一个控件(例如文本框,并将焦点放在文本框上)。然后我覆盖表单上的processCmdKey方法来捕获键盘输入,如果它检测到箭头键,那么我以编程方式更改DataGridView中的当前单元格(例如,如果在processCmdKey中检测到DOWN键,则更改为下一行)。这会移动当前单元格而不会将实际焦点提供给DataGridView。然后高光的移动似乎均匀地进行,并且不会以奇怪的批次跳下来。

  • 在表单上添加一个文本框
  • 将此代码添加到表单中:

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        int currentRowIndex = dataGridView1.CurrentCell.RowIndex;
        switch (keyData)
        {
            case Keys.Up:
                // Check not already at the first row in the grid before moving up one row
                if (currentRowIndex > 0)
                    dataGridView1.CurrentCell = dataGridView1.Rows[currentRowIndex - 1].Cells[dataGridView1.CurrentCell.ColumnIndex];
                return true;
            case Keys.Down:
                // Check not already at the last row in the grid before moving down one row
                if (currentRowIndex + 1 < dataGridView1.Rows.Count)
                    dataGridView1.CurrentCell = dataGridView1.Rows[currentRowIndex + 1].Cells[dataGridView1.CurrentCell.ColumnIndex];
                return true;
        }
    
        // Line below is reached if we didn't handle the key in this method, it tells the form/control to handle it
        return base.ProcessCmdKey(ref msg, keyData);
    }
    

然后运行程序再次进行测试,如下所示:

  • 单击文本框以使其聚焦(而不是网格)。然后按住DOWN键,可以看到蓝色突出显示的当前单元格在行中顺利进行。释放钥匙。
  • 然后单击网格以使其聚焦,然后按住向上或向下箭头键并看到蓝色突出显示跳过多行而不是顺利进行。

因此,只要DataGridView具有焦点,问题就存在,无论网格是否处理按键,或者我是否在processCmdKey中处理它们。

我不想依赖于将焦点远离网格,因为有时候网格需要有焦点。我还需要为processCmdKey添加更多代码来处理网格的所有其他潜在按键操作,例如tab,page up / down,enter等,这看起来并不合理。< / p>

网格实际上只能在我的应用程序中读取,所以它可能只是我需要使用的平滑移动的能力,但是仍然有一个聚焦的虚拟控件而不是网格不是看起来很明智。

这里提到了一个稍微类似的问题(DataGrid not scrolling smoothly),但它不是Windows Forms,原始海报似乎表明他的问题是通过摆脱所有事件处理和开启虚拟化来解决的,但我和#39;尝试了虚拟模式,我没有处理任何网格事件。他还说他在一个非常繁忙的服务器上。所以我认为这可能值得我将其添加为自己独立的问题。

非常感谢任何帮助。谢谢:))

1 个答案:

答案 0 :(得分:0)

现在可以通过更改计算机上的键盘重复速度设置来解决问题。我去了控制面板|易于访问|改变键盘的工作原理|向下滚动并选择“另请参阅:键盘设置&#39;”。然后,这会显示一个名为“键盘属性”的窗口,我必须降低“重复率”,我将滑块略微移动到最大值(大约距离最大值的四分之一)并且点击申请。

当我重新测试程序时,当我按下并按住向下箭头键时,它正常工作并且光标在网格中平滑移动。

所以我猜我的电脑有一些奇怪的东西使它在使用最大键盘重复率时无法很好地处理,就像DataGridView一样。

在一个理想的世界中,我能够使用一个非常快的键盘重复率设置为最大值,但我很高兴能够解决一个较慢的键盘重复率,以便使用箭头键解决我的问题在DataGridView上顺利进行。

@Sinatr,再次感谢您通过在PC上测试代码来帮助我,只是告诉我您无法重现它并且我可能在我的PC上遇到问题而不是我的代码,这是一个很大的帮助