有时键向上不能处理DataGridView

时间:2016-02-18 12:50:39

标签: c# winforms datagridview

有时,向上键不能用于DataGridView

我不知道为什么,特别是它很奇怪,因为没有代码分配给DataGridView ...

的关键事件
  

SelectionMode是FullRowSelect

     

多选是假的

此代码无济于事......

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

有任何线索吗?

P.S。

似乎SelectionChanged方法做了一些努力......所以当我禁用它时,eberything就可以了。

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

所以问题是如何优化它。

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

有关最佳方法的任何线索吗?

2 个答案:

答案 0 :(得分:1)

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

                });
            }
        }

答案 1 :(得分:0)

请注意,当您PopulateTabs()时,您必须再次将焦点设置回DataGridView。这是您使用向上和向下箭头键的问题。密钥的事件被您的自定义控件捕获。至于非常辛苦的工作(PopulateTabs),我注意到你正在使用TPL的异步线程。您是否想过要取消睡眠间隔,因为它似乎是多余的,只需设置您的DoesHardWork变量并将焦点更改为任务外的DataGridView。它正在以它现在的方式工作的原因是SelectionChanged事件第一次触发两次" DoesHardWork"它第二次失败,因为在处理PopulateTabs()时,DoesHardWork仍然是假的。更优雅的解决方案是将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上,或者焦点在需要时不会发生变化。