2016-02-18 29 views
4

有時鍵自上而下不能在DataGridView上工作。有時鍵不起作用DataGridView

我不知道爲什麼,特別很是怪異,因爲沒有分配到DataGridView關鍵的事件代碼...

selectionMode是FullRowSelect

多選是假

此代碼dos沒有幫助...

 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方法應該執行。

任何關於最好的辦法線索?

+0

使用PreviewKeyUp/PreviewKeyDown事件。 –

+0

@MitraM你會不介意解釋爲什麼我必須使用它們以及它應該如何完成? –

+0

請參閱[本](https://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown(v = vs.110).aspx)和[this](http: /stackoverflow.com/questions/31673415/cancel-previewkeydown)。 –

回答

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

       }); 
      } 
     } 
0

注意,當你PopulateTabs()你就必須重新設置對焦回DataGridView。這是您使用向上和向下箭頭鍵的問題。密鑰的事件正在被您的自定義控件捕獲。至於非常努力的工作(PopulateTabs),我注意到您正在使用TPL的異步線程。你有沒有想過放棄睡眠間隔時間,因爲它似乎是多餘的,只需設置你的DoesHardWork變量並將焦點改爲DataGridView以外的任務。之所以按照現在的方式工作,是因爲在處理PopulateTabs()時,DoesHardWork仍然是假,因此SelectionChanged事件在第一次遇到「DoesHardWork」時第一次觸發兩次。更優雅的解決方案是將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上,否則焦點在需要時不會改變。

+0

您的評論對我而言很好。你介意添加一個代碼示例,以便我可以測試它,並可能標記爲答案是正確的,請嗎? –