winforms 有时上下键在DataGridView上不起作用

1dkrff03  于 2022-11-17  发布在  其他
关注(0)|答案(3)|浏览(140)

有时,DataGridView上的键up down不起作用。
我不知道为什么,特别是它是奇怪的,因为没有代码分配给关键的事件DataGridView ...
选择模式为整行选择
多选为False
此代码没有帮助...

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方法做了一些艰苦的工作...所以当我禁用它时,eberything是好的。

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

因此,如何优化它是一个问题。
我假设使用计时器,因此当用户停止选择箭头键1秒后,应该执行SelectionChanged方法的代码。
有什么最好的方法吗?

yrdbyhpb

yrdbyhpb1#

在执行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);

                });
            }
        }
uubf1zoe

uubf1zoe2#

请注意,当您执行PopulateTabs()时,您必须再次将Focus设置回DataGridView。这是您使用向上和向下箭头键时遇到的问题。这些键的事件被您的自定义控件捕获(s).至于非常艰苦的工作(填充选项卡),我注意到您在TPL中使用了异步线程。您是否考虑过取消睡眠间隔,因为它似乎是多余的,只需设置DoesHardWork变量并将焦点更改为Task外部的DataGridView。它现在这样工作的原因是,SelectionChanged事件在第一次“DoesHardWork”时触发两次,第二次触发时失败,因为在处理PopulateTabs()时DoesHardWork仍然为false。更好的解决方案是将PopulateTabs()生成的CellValue/RowValue/Control设置为使用IAsyncResult从PopulateTabs()返回的Object。
类似于以下内容:

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,否则焦点在需要时不会改变。

wtlkbnrh

wtlkbnrh3#

也许是太晚了,但在我的问题中,使用e.Handled = true是问题所在。明智地把命令放在应该放置的地方。
例如:如果在Key Down事件中,用户每按一次Enter键,您就希望选定的行不向下移动,并使用事件e.Handled。将该命令如下所示:

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

不要在if条件之外使用,因为无论用户按什么键,它都将冻结选定的行。
在您的情况下,在Up和Down Key Press事件中使用e.Handled只会使情况变得更糟,因为每次用户按下该键时,所选行都不会向上或向下移动,因为使用命令e.Handled,您命令程序不要将光标从所选行移动。
抱歉我的英语不好...

相关问题