2009-12-11 55 views

回答

26

你可以嘗試這樣的事情在GridView鍵按下事件

Private Sub DataGridView1_Keydown (...) Handlers DataGridView1.KeyDown 
    If e.KeyCode = Keys.Enter Then 
     ' Your code here 
     e.SuppressKeyPress = True 
    End If 
End Sub 

另一種選擇是創建一個自定義網格視圖控制

DataGridView.ProcessDataGridViewKey Method

+0

它是這樣工作的魅力 – Ramji 2009-12-11 14:30:53

+0

+1這正是我需要的。謝謝 – gyurisc 2010-03-04 09:28:48

+0

一旦涉及到e.suppressKeyPress = true,應用程序就會終止。 – Kenta 2014-01-17 04:41:06

1

覆蓋DataGridView(編寫自己的繼承自它),並處理OnKe yDown方法。

public partial class UserControl1 : DataGridView 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnKeyDown(KeyEventArgs e) 
    { 
     if (e.KeyCode == Keys.Enter) 
      return; 

     base.OnKeyDown(e); 
    } 
} 
2

你可以使用按鍵事件:

private void dataGridView1_KeyDown(object sender, KeyEventArgs e) 
     { 
      if (e.KeyCode == Keys.Enter) 
      { 
       //You're Code 
      } 
      e.Handled = true; 
      return; 
     } 
+0

這工作就像一個魅力。建議的簡單但唯一的解決方案,它爲我工作。 – Birk 2017-03-10 16:14:37

3

我自己,在DataGridView禁用回車鍵的默認行爲時,要能夠實現以設置DataGridView.StandardTabtrue類似的效果。啓用StandardTab使用戶能夠更輕鬆地在表單中的不同控件之間導航。這使得它的行爲更像ListBox,特別是如果DataGridView只有一列。回車鍵的默認行爲以及我期望將(不存在的)DataGridView.StandardEnter鍵設置爲true的行爲將發送到包含控件的關鍵事件,可能導致Form.AcceptButton被激活。 setting KeyEventArgs.SuppressKeyPress = true in DataGridView.KeyDownnot even firing DataGridView.KeyDown when the input key is Enter建議的方法不啓用「標準」Enter鍵行爲;這些方法反而讓Enter鍵事件被吞噬。

下面顯示了我如何設法從DataGridView中獲得「標準」輸入關鍵行爲(包括適當調用AcceptButton)。這是醜陋的,因爲我不知道更好的方式來運行Control.ProcessDialogKey()(如果沒有Parent,它只是調用Parent(容器)的ProcessDialogKey()或返回false)中的邏輯,而不是將其複製到我自己的派生類中。 (我基本上需要使用invalid/impossible base.base.ProcessDialogKey() syntax以更清晰的方式解決System.Windows.Forms的不可擴展性)。因此,我不得不使用反射來訪問存在時父對象(容器)Control對象的受保護Control.ProcessDialogKey()方法。

DataGridVew.IsInputKey()返回true對於Keys.Enter。這使得它可以看到回車鍵在其DataGridView.OnKeyDown()方法,它最終會調用DataGridView.ProcessEnterKey(),它基於DataGridView.EditMode的設置以不同的方式對輸入鍵作出反應。但是,這也禁止將關鍵事件發送到ProcessDialogKey(),從那裏正常控件將回車鍵事件吹到他們的父母(例如使AcceptButton工作)。因此,我們通過覆蓋IsInputKey()來恢復這種行爲,並且現在DataGridView.ProcessDialogKey()將在按下Enter時被調用。

但這還不夠。 DataGridView.ProcessDialogKey()DataGridView.ProcessEnterKey()進行了硬編碼調用,如果ProcessEnterKey()返回false,則只調用其基址Control.ProcessDialogKey()。在這一點上,將ProcessEnterKey()替換爲當我們需要標準回車鍵行爲時會返回false的東西似乎是常識。但是,唉,這是一種非虛擬方法。因此,我們被迫覆蓋一些我們可以覆蓋的東西,DataGridView.ProcessDialogKey(),並在跳過ProcessEnterKey()的調用時重新實現。這是我們無法直接呼叫Control.ProcessDialogKey()的地方,並且被迫使用反射來調用父/容器對象的ProcessDialogKey()方法。但是,一旦我們成功地打出了這個電話,我們終於有了標準的Enter行爲,即使在DataGridView有焦點的情況下也可以使用AcceptButton

/// <summary> 
/// A DataGridView with a StandardEnter property which behaves 
/// like StandardTab. 
/// </summary> 
class StandardEnterDataGridView 
: DataGridView 
{ 
    /// <summary> 
    /// Like StandardTab but for the Enter key. 
    /// </summary> 
    [Category("Behavior"), Description("Disable default edit/advance to next row behavior of of the Enter key.")] 
    public bool StandardEnter { get; set; } 

    /// <summary> 
    /// Implement StandardEnter. 
    /// </summary> 
    protected override bool IsInputKey(Keys keyData) 
    { 
     if (StandardEnter && keyData == Keys.Enter) 
      // Force this key to be treated like something to pass 
      // to ProcessDialogKey() (like the Enter key normally 
      // would be for controls which aren’t DataGridView). 
      return false; 

     return base.IsInputKey(keyData); 
    } 

    private static MethodInfo _Control_ProcessDialogKey = typeof(Control).GetMethod("ProcessDialogKey", BindingFlags.Instance|BindingFlags.NonPublic); 

    protected override bool ProcessDialogKey(Keys keyData) 
    { 
     if (StandardEnter && keyData == Keys.Enter) 
      // Copy the default implementation of 
      // Control.ProcessDialogKey(). Since we can’t access 
      // the base class (DataGridView)’s base class’s 
      // implementation directly, and since we cannot 
      // legally access Control.ProcessDialogKey() on other 
      // Control object, we are forced to use reflection. 
      return Parent == null ? false : (bool)_Control_ProcessDialogKey.Invoke(Parent, new object[] {keyData, }); 

     return base.ProcessDialogKey(keyData); 
    } 
} 
+0

我只是將我的Gride的聲明更改爲這個新類,但沒有任何反應,ENTER KEY仍會進入下一行: -/ this.dbGride = new StandardEnterDataGridView(); – duardbr 2016-03-15 19:43:46

+0

@duardbr我在很長一段時間沒有看過這段代碼,但考慮到你在你的評論中寫了'this.dbGride = new StandardEnterDataGridView();',你是否記得將'StandardEnter'屬性設置爲'true' ?也許'this.dbGride = new StandardEnterDataGridView {StandardEnter = true,};'。或者,如果您使用VS Designer,請嘗試在Designer的屬性網格視圖中啓用'StandardEnter'屬性。 – binki 2016-03-15 19:49:30

+0

感謝您的回覆,是的,StandardEnter是真實的,沒有任何反應 – duardbr 2016-03-16 13:30:25

0

接受的解決方案對我無效。 DID下面的代碼。從http://www.vbforums.com/showthread.php?603242-Block-enter-key-in-datagridview-in-vb-net:(原始來源未知)

Public Class clsDataGridView 
Inherits System.Windows.Forms.DataGridView 

Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, ByVal keyData As System.Windows.Forms.Keys) As Boolean 

    If keyData = Keys.Return Or keyData = Keys.Tab Then 
     If CurrentCellAddress.X = ColumnCount - 1 Then 
      keyData = Keys.Cancel 
      With msg 
       .WParam = CType(Keys.Cancel, IntPtr) 
      End With 
     Else 
      keyData = Keys.Tab 
      With msg 
       .WParam = CType(Keys.Tab, IntPtr) 
      End With 
     End If 
    End If 

    If keyData = (Keys.Shift Or Keys.Tab) Then 
     If CurrentCellAddress.X = 0 Then 
      keyData = Keys.Cancel 
      With msg 
       .WParam = CType(Keys.Cancel, IntPtr) 
      End With 
     End If 
    End If 
    Return MyBase.ProcessCmdKey(msg, keyData) 

End Function 

Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean 

    If keyData = Keys.Return Or keyData = Keys.Tab Then 
     If CurrentCellAddress.X = ColumnCount - 1 Then 
      keyData = Keys.Cancel 
     Else 
      keyData = Keys.Tab 
     End If 
    End If 

    If keyData = (Keys.Shift Or Keys.Tab) Then 
     If CurrentCellAddress.X = 0 Then 
      keyData = Keys.Cancel 
     End If 
    End If 
    Return MyBase.ProcessDialogKey(keyData) 

End Function 

End Class 
相關問題