有时,向上键在 DataGridView 上不起作用

本文关键字:DataGridView 不起作用 有时 | 更新日期: 2023-09-27 18:35:08

有时向上键不起作用DataGridView .

我不知道为什么,尤其是这很奇怪,因为没有为DataGridView键的事件分配代码......

选择

模式为全行选择

多选为假

这段代码没有帮助...

     private void dataGridView1_PreviewKeyDown(object sender, reviewKeyDownEventArgs e)
            {
                switch (e.KeyCode)
                {
                    case Keys.Down:
                        e.IsInputKey = true;
                        break;
                    case Keys.Up:
                        e.IsInputKey = true;
                        break;
                }
            }
  private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Down)
            {
                e.Handled = true;
            }
            else if (e.KeyData == Keys.Up)
            {
                e.Handled = true;
            }
        }

有什么线索吗?

附言

似乎SelectionChanged方法做了一些艰苦的工作......所以当我禁用它时,一切都很好。

private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
    // Some hard work
}

所以问题是如何优化它。

我假设使用计时器,所以当用户停止选择箭头键 1 秒后应执行SelectionChanged方法的代码。

关于最佳方法的任何线索?

有时,向上键在 DataGridView 上不起作用

在执行SelectionChanged的过程中,网格不知何故失去了焦点。这可能是因为动态创建和插入用户控件而发生的。

所以我做了三个调整,现在很好!

 bool canDoHardWork = true;
 private void dataGridView1_SelectionChanged(object sender, EventArgs e)
        {
            if (canDoHardWork)
            {
                int interval = 2000; // Just 2 seconds
                Task.Factory.StartNew(() =>
                {
                    canDoHardWork= false;
                    Thread.Sleep(interval);
                    this.BeginInvoke((Action)(() =>
                    {                         
                        PopulateTabs(); // Very hard work
                        dataGridView1.Focus();
                        canDoHardWork= true;
                    }), null);
                });
            }
        }

请注意,当您PopulateTabs()时,您必须再次将焦点设置回DataGridView。这是您在向上和向下箭头键方面的问题。自定义控件捕获了键的事件。至于非常艰苦的工作(PopulateTabs),我注意到您正在使用异步线程与TPL。你有没有想过取消睡眠间隔,因为它似乎是多余的,只需设置你的 DoesHardWork 变量并将焦点更改为任务之外的DataGridView。它目前的工作方式的原因是,SelectionChanged事件在第一次"DoesHardWork"第二次失败时触发两次,因为 DoesHardWork 在处理PopulateTabs()时仍然是假的。一个更优雅的解决方案是将PopulateTabs()生成的 CellValue/RowValue/Control 设置为您将使用 IAsyncResult 从 PopulateTabs() 返回的对象。

像这样:

bool canDoHardWork = true;
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
   if (canDoHardWork)
   {
    IAsyncResult result;
    Task.Factory.StartNew(() =>
    {
       canDoHardWork = false;
       result = this.BeginInvoke((Func<Button>)(() =>
       {                         
           canDoHardWork = true;
           return PopulateTabs(); // Very hard work
       }), null);
       this.dataGridView1.Controls.Add((Button)this.EndInvoke(result));
       dataGridView1.Focus();
    });
   }
}

无需等待线程完成,因为它只会将自定义控件添加到 DataGridView 并将控件返回到主线程。示例中的线程睡眠将发生在异步线程上,因此是冗余的。在此示例中,繁重的工作是在另一个线程上执行的,使主线程可以继续接受输入。必须在添加控件后放置 DataGridView 的焦点,否则焦点将在需要时不会更改。

也许晚了,但在我的问题中,使用e.Handled = true是问题所在。明智地放置命令的位置。

例:如果在事件 Key Down 上,并且每个 Key Enter 该用户按您希望所选行不向下移动,并且您使用事件e.Handled 。像这样放置该命令:

if (e.KeyCode == Keys.Enter)
{
   e.Handled = true;
   //Do the command
}

不要在 if 条件之外使用,因为它会冻结所选行,无论用户按什么键。

在您的情况下,在向上和向下按键事件中使用e.Handled只会使情况变得最糟糕,因为每次用户按下键时,所选行都不会向上或向下移动,因为使用命令e.Handled,您命令程序不要将光标从所选行移动。

对不起,我的英语不好...