.net 在datagridview中禁用默认的Enter/Return键行为

.net 在datagridview中禁用默认的Enter/Return键行为,.net,vb.net,winforms,datagridview,.net,Vb.net,Winforms,Datagridview,在vb.net datagridview中,默认的Enter/Return键行为是移动到下一行。是否有一种快速简便的方法可以避免这种情况 欢迎您提供任何建议您可以在gridview键关闭事件中尝试类似的方法 Private Sub DataGridView1_Keydown (...) Handlers DataGridView1.KeyDown If e.KeyCode = Keys.Enter Then ' Your code here e.Suppress

在vb.net datagridview中,默认的Enter/Return键行为是移动到下一行。是否有一种快速简便的方法可以避免这种情况


欢迎您提供任何建议

您可以在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(编写您自己从中继承的数据),并处理OnKeyDown方法


您可以只使用按键事件:

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

我本人在
DataGridView
上禁用Enter键的默认行为时,希望能够实现与设置为
true
类似的效果。启用
StandardTab
使用户能够更轻松地在表单中的不同控件之间导航。这使得它的行为更像一个
列表框
,特别是当
DataGridView
只有一列时。Enter键的默认行为,以及将(不存在的)
DataGridView.StandardEnter
键设置为
true
时所期望的行为,是将键事件发送到包含控件,可能会导致被激活。建议的方法或不启用“标准”输入键行为;相反,这些方法让Enter键事件被吞没

下面显示了如何从DataGridView中获取“标准”输入键行为(包括适当地调用
AcceptButton
)。这很难看,因为我不知道运行
Control.ProcessDialogKey()
中的逻辑(这只是调用父(容器)的
ProcessDialogKey()
或返回
false
,如果没有父对象)比将其复制到我自己的派生类中更好的方法。(我基本上需要使用来以更干净的方式解决
System.Windows.Forms
的不可扩展性)。因此,当父对象(容器)
Control
对象存在时,我被迫使用反射来访问受保护的
Control.ProcessDialogKey()
方法

DataGridVew.IsInputKey()
键返回
true
。输入
。这使它能够在其
DataGridView.OnKeyDown()
方法中查看Enter键,并最终调用该方法,该方法根据的设置以不同的方式对Enter键作出反应。但这也会禁用将键事件发送到
ProcessDialogKey()
,正常控件会从该位置将Enter键事件冒泡发送到其父控件(例如,启用
AcceptButton
)。因此,我们通过重写
IsInputKey()
来恢复此行为,现在
DataGridView.ProcessDialogKey()
将在按下Enter键时被调用

但这还不够
DataGridView.ProcessDialogKey()
DataGridView.ProcessEnterKey()
有一个硬编码调用,并且只调用其基
控件。如果
ProcessEnterKey()
返回false,则ProcessDialogKey()
。在这一点上,当我们需要标准的输入键行为时,用返回值
false
的内容覆盖
ProcessEnterKey()
似乎是常识。但是,唉,这是一种非虚拟的方法。因此,我们被迫重写一些可以重写的内容,
DataGridView.ProcessDialogKey()
,并在跳过调用
ProcessEnterKey()
的同时重新实现它。这也是我们无法直接调用Control.ProcessDialogKey()
的地方,我们被迫使用反射来调用父/容器对象的
ProcessDialogKey()
方法。但是,一旦我们成功地进行了调用,我们终于有了标准的Enter行为,
AcceptButton
即使在
DataGridView
有焦点的时候也可以访问

//
///具有StandardEnter属性的DataGridView,其行为
///比如标准标签。
/// 
类StandardEnterDataGridView
:DataGridView
{
/// 
///与StandardTab类似,但用于Enter键。
/// 
[类别(“行为”),描述(“禁用默认编辑/前进到回车键的下一行行为”)]
公共bool标准输入{get;set;}
/// 
///实现标准输入。
/// 
受保护的覆盖布尔IsInputKey(Keys keyData)
{
if(StandardEnter&&keyData==Keys.Enter)
//强制将此密钥视为要传递的对象
//要处理DialogKey()(通常与Enter键类似
//将用于非DataGridView的控件)。
返回false;
返回base.IsInputKey(keyData);
}
私有静态MethodInfo _Control _ProcessDialogKey=typeof(Control).GetMethod(“ProcessDialogKey”,BindingFlags.Instance | BindingFlags.NonPublic);
受保护的覆盖布尔ProcessDialogKey(Keys keyData)
{
if(StandardEnter&&keyData==Keys.Enter)
//复制的默认实现
//Control.ProcessDialogKey()。因为我们无法访问
//基类(DataGridView)的基类
//直接实施,因为我们不能
//其他服务器上的合法访问控制.ProcessDialogKey()
//控制对象时,我们被迫使用反射。
返回Parent==null?false:(bool)_Control_ProcessDialogKey.Invoke(Parent,新对象[]{keyData,});
返回base.ProcessDialogKey(keyData);
}
}

接受的解决方案对我不起作用。下面的代码没有。发件人:(来源不明)


我对这篇文章非常感兴趣,因为它与我在DataGridView中遇到的另一个问题非常接近。这是因为Enter键会将您带到下面的单元格,从而阻止用户对单元格中的文本进行简单编辑。重写该类并在这方面花费了大量时间后,我终于找到了以下文章:

如果这是你唯一的问题,那么t
 private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                //You're Code
            }
            e.Handled = true;
            return;
        }
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