2009-04-15 107 views

回答

4

覆蓋SelectionChanged事件是正確的方法。屬性CurrentCell可用於設置當前單元格。你想是這樣的:

private void dataGridView_SelectionChanged(object sender, EventArgs e) 
{ 
    DataGridViewCell currentCell = dataGridView.CurrentCell; 
    if (currentCell != null) 
    { 
     int nextRow = currentCell.RowIndex; 
     int nextCol = currentCell.ColumnIndex + 1; 
     if (nextCol == dataGridView.ColumnCount) 
     { 
      nextCol = 0; 
      nextRow++; 
     } 
     if (nextRow == dataGridView.RowCount) 
     { 
      nextRow = 0; 
     } 
     DataGridViewCell nextCell = dataGridView.Rows[nextRow].Cells[nextCol]; 
     if (nextCell != null && nextCell.Visible) 
     { 
      dataGridView.CurrentCell = nextCell; 
     } 
    } 
} 

你需要添加一個測試當前單元只和循環,而下一個單元格不可見或只讀讀取。如果所有單元格都是隻讀的,您還需要檢查以確保您不會永遠循環。

您必須應對顯示索引與基本索引不同的情況。

要按Tab鍵時,你需要添加的KeyDown處理程序只是讓這種行爲:

private void AlbumChecker_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.KeyCode == Keys.Tab) 
    { 
     SelectNextEditableCell(DataGridView dataGridView); 
    } 
} 

,並把第一個代碼在這個新的方法。

您可能想要檢查DataGridView是否也有焦點。

+0

趕上Tab鍵,但我想這種行爲只是按「TAB」鍵時不是在使用鼠標的時候也是如此 – Cornel 2009-04-15 16:11:08

+2

當單元格處於編輯模式時,最後一個單元不起作用:( – Cornel 2009-04-16 06:30:57

+0

@Cornel - 不知道該怎麼建議,你看到了什麼行爲?我更多地閱讀MSDN文檔中的DataGridView方法。它可能需要一點挖掘,但通常信息在那裏。 – ChrisF 2009-04-16 12:50:48

0

繼承DataGridView並覆蓋ProcessDialogKey(用於編輯時按下的鍵)和ProcessDataGridViewKey(用於未編輯時按下的鍵)。當按下Tab鍵時,將CurrentCell設置爲下一個非只讀單元。

(可選)覆蓋WndProc以過濾只讀單元格上的鼠標點擊。 (請參閱DataGridView.GetColumnDisplayRectangle以查找所點擊的列)。

良好來源從here開始。

0

當細胞是在編輯模式下,你要聽按鍵事件,你可以嘗試處理DataGridView中的EditingControlShowing事件......

Private Sub myDvGrid_EditingControlShowing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles myDvGrid.EditingControlShowing 
    Dim c As DataGridViewTextBoxEditingControl = DirectCast(e.Control, DataGridViewTextBoxEditingControl) 

    RemoveHandler c.PreviewKeyDown, AddressOf edtctrlOn_PreviewKeyDown 
    RemoveHandler c.TextChanged, AddressOf edtctrlOn_TextChanged 

    AddHandler c.TextChanged, AddressOf edtctrlOn_TextChanged 
    AddHandler c.PreviewKeyDown, AddressOf edtctrlOn_PreviewKeyDown 

End Sub 

然後,在edtctrlOn_PreviewKeyDown情況下,你可以泡的參數傳遞到原始數據網格的PreviewKeyDown事件處理程序。

3

我做了一個繼承DataGridView類的例子。該示例適用於TAB和ENTER鍵,因此用戶可以快速插入數據,但仍然可以使用鼠標或上,下,右,左鍵選擇單元格並將其複製到Excel中。它可以模擬幾個TAB,直到Grid到達非ReadOnly Cell。希望它是有用的。

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Windows.Forms; 

namespace System.Windows.Forms 
{ 
    class MyDataGridView : DataGridView 
    { 
    protected override bool ProcessDialogKey(Keys keyData) 
    { 
     if (keyData == Keys.Enter || keyData == Keys.Tab) 
     { 
     MyProcessTabKey(Keys.Tab); 
     return true; 
     } 
     return base.ProcessDialogKey(keyData); 
    } 

    protected override bool ProcessDataGridViewKey(KeyEventArgs e) 
    { 
     if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Tab) 
     { 
     MyProcessTabKey(Keys.Tab); 
     return true; 
     } 
     return base.ProcessDataGridViewKey(e); 
    } 

    protected bool MyProcessTabKey(Keys keyData) 
    { 
     bool retValue = base.ProcessTabKey(Keys.Tab); 
     while (this.CurrentCell.ReadOnly) 
     { 
     retValue = base.ProcessTabKey(Keys.Tab); 
     } 
     return retValue; 
    } 
    } 
} 
11
private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e) 
{ 
    if (dataGridView1.CurrentRow.Cells[e.ColumnIndex].ReadOnly) 
    { 
     SendKeys.Send("{tab}"); 
    } 
} 
0

赫克託 - 我希望你繼續收聽。您的解決方案是我在廣泛搜索中看到的最優雅和直接的解決方案。我已經遇到了重寫關鍵事件的建議,但是您調用base.ProcessTabKey的建議非常簡單,它會在到達dgv結束時處理焦點傳遞到下一個控件。您的解決方案需要的另一件事是在MyProcessTabKey中檢查dgv的最後一個單元格。如果該單元格是隻讀的,並且用戶選項卡在前一個單元格中,則while語句會進入無限循環。添加下面的代碼作爲while循環中的第一條語句似乎解決了這個問題,儘管它將最後一個(只讀)單元保留爲「活動」單元(意味着它看起來好像已被選中)。

if (this.CurrentCell.RowIndex == this.Rows.Count - 1 
       && this.CurrentCell.ColumnIndex == this.Columns.Count - 1) 
       { retValue = false; break; } 

我有一個後續問題。你或其他人知道如何使這種方法與Shift-Tab一起工作,所以dgv跳過只讀單元格以反向方向?由於Shift和Tab是不同的關鍵事件,我不知道如何檢測重寫的ProcessDialogKey和ProcessDataGridViewKey方法中的Shift-Tab。 謝謝。史蒂夫

0

您可以通過這個代碼ProcessDialogKey

Dim uKeyCode As Keys = (keyData And Keys.KeyCode) 
    Dim uModifiers As Keys = (keyData And Keys.Modifiers) 

    (uKeyCode = Keys.Return OrElse uKeyCode = Keys.Tab) AndAlso uModifiers = Keys.Shift 

而且通過這個代碼ProcessDataGridViewKey

(e.KeyCode = Keys.Return OrElse e.KeyCode = Keys.Tab) AndAlso e.Modifiers = Keys.Shift 
-1
if (e.KeyValue == 13) 
     { 
      e = new KeyEventArgs(Keys.Tab); 
     } 
相關問題