【问题标题】:override DataGridView Shift+Space覆盖 DataGridView Shift+Space
【发布时间】:2012-12-26 20:27:45
【问题描述】:

在 DataGridView 中,按 SHIFT 和 SPACE 将默认选择整行。我找到的唯一解决方案(参考vb.net DataGridView - Replace Shortcut Key with typed character)是关闭行选择功能。虽然这样可行,但并不理想,因为我仍然希望能够使用行选择器选择整行(例如,删除行),并将SelectionMode 属性更改为RowHeaderSelect 以外的任何属性我失去了这种能力。有没有办法只捕获 SHIFT+SPACE 组合并用简单的 SPACE 替换它?当控件的MutiSelect 属性设置为True 并且SelectionMode 属性设置为RowHeaderSelect 时,似乎没有一个键事件甚至可以识别击键,所以我不能使用这些。

ETA:我想也许可以关闭MultiSelect 并将选择模式更改为CellSelect,然后为RowHeaderMouseClick 事件添加一个事件处理程序会起作用......不。

【问题讨论】:

    标签: vb.net datagridview


    【解决方案1】:

    我想出如何做到这一点的最佳方法是从 DataGridView 继承并覆盖 ProcessCmdKey 方法。然后你可以拦截 Shift+Space 并在 Space 上发送。只需将此类添加到您的项目中,然后将所有 DataGridViews 切换到 MyDataGridViews。我的解决方案从DataGridView keydown event not working in C# SO 问题(这也解释了为什么 Zaggler 的解决方案不起作用)和SendKeys in ProcessCmdKey: change Shift-Space to just a Space Bytes.com 帖子中汲取灵感。抱歉,它是用 C# 编写的。

    class MyDataGridView : System.Windows.Forms.DataGridView
    {
        protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
        {
            if (keyData == (System.Windows.Forms.Keys.Space | System.Windows.Forms.Keys.Shift))
            {
                // DataGridView is dumb and will select a row when the user types Shift+Space 
                // if you have the DGV set so that you can click a row header to select a row (for example, to delete the row)
                // this method will intercept Shift+Space and just send on Space so that the DGV properly handles this. 
                // For example, if I type "ME TYPING IN ALL CAPS" it ends up looking like "METYPINGINALLCAPS".
                // Or if I type "Note: I have some OS thing to talk about" it looks like "Note:Ihave some OSthing to talk about"
    
                byte[] keyStates = new byte[255];
                UnsafeNativeMethods.GetKeyboardState(keyStates);
                byte shiftKeyState = keyStates[16];
                keyStates[16] = 0; // turn off the shift key
                UnsafeNativeMethods.SetKeyboardState(keyStates);
    
                System.Windows.Forms.SendKeys.SendWait(" ");
    
                keyStates[16] = shiftKeyState; // turn the shift key back on
                UnsafeNativeMethods.SetKeyboardState(keyStates);
                return true;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }
    
        [System.Security.SuppressUnmanagedCodeSecurity]
        internal static class UnsafeNativeMethods
        {
    
            [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
            public static extern int GetKeyboardState(byte[] keystate);
    
    
            [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
            public static extern int SetKeyboardState(byte[] keystate);
        }
    }
    

    【讨论】:

      【解决方案2】:

      这是我的解决方案:

      private void dataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
      {
          dataGridView.SelectionMode = DataGridViewSelectionMode.CellSelect;
      }
      
      private void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
      {
          dataGridView.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
      }
      

      【讨论】:

        【解决方案3】:

        这对我来说很好用....

        Private Sub DataGridView1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyDown
            'Lets see what keys we have down shall we?'
            If My.Computer.Keyboard.ShiftKeyDown And e.KeyCode = Keys.Space Then
                DataGridView1.CurrentCell.Selected = False
            End If
        End Sub
        

        这是另一种方式..

        Private Sub DataGridView1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles DataGridView1.KeyDown
            'Lets see what keys we have down shall we?'
            If My.Computer.Keyboard.ShiftKeyDown And e.KeyCode = Keys.Space Then
                'SendKeys.Send(Keys.Space)
                DataGridView1.CurrentCell.Selected = False
            End If
        End Sub
        

        只是对它们进行试验,希望对你有用?

        【讨论】:

        • 由于某种原因,KeyDown 事件从未触发。
        • 你有没有在 sub 上设置一个断点,看看它是否击中它?还要确保您的对象名称对于处理程序是正确的...
        • 是的,断点设置,我使用 IDE 创建存根,所以我知道它指向正确的控件和正确的事件。刚想到点什么...这个窗体是一个MDI子窗体,它的父窗体覆盖了ProcessCmdKey函数,但最后函数将控制权返回给MyBase.ProcessCmdKey。这应该允许其他基于键的事件触发,对吧?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-02
        • 1970-01-01
        • 1970-01-01
        • 2014-05-17
        • 2012-01-31
        相关资源
        最近更新 更多