带有和不带有数据的 DataGridView 中的按键修饰符

Posted

技术标签:

【中文标题】带有和不带有数据的 DataGridView 中的按键修饰符【英文标题】:Keypress modifiers in a DataGridView with and without data 【发布时间】:2016-12-01 23:30:59 【问题描述】:

我正在尝试在派生自 DataGridView 的用户控件中实现 CTRL+C 复制操作。

我希望 Ctrl+C 复制 datagridview 中选定的单元格,Ctrl+Shift+C 复制选定的单元格单元格列标题文本。

我已经设置了两个复制程序,它们工作正常。我遇到的问题是分配 key_down 处理程序。

这是我的 keyDown 代码:

 protected virtual void DataGridViewEx_KeyDown(object sender, KeyEventArgs e)
    
        System.Diagnostics.Debug.WriteLine("-------------------------------");
        System.Diagnostics.Debug.WriteLine("KeyCode = " + e.KeyCode.ToString());
        System.Diagnostics.Debug.WriteLine("KeyValue = " + e.KeyValue.ToString());
        System.Diagnostics.Debug.WriteLine("KeyData = " + e.KeyData.ToString());
        System.Diagnostics.Debug.WriteLine("Modifiers = " + e.Modifiers.ToString());
        System.Diagnostics.Debug.WriteLine("-------------------------------");


        if ((e.Control & e.Shift) && e.KeyCode == Keys.C)
        
            System.Diagnostics.Debug.WriteLine("CTRL+SHIFT+C Pressed");
            CopyToClipboard(CopyMode.SelectedCellsWithHeaders);
            e.Handled = true;
        
        if (e.Control && e.KeyCode == Keys.C)
        
            System.Diagnostics.Debug.WriteLine("CTRL+C Pressed");
            CopyToClipboard(CopyMode.SelectedCellsOnly);
            e.Handled = true;
        

        else if (e.Control && e.KeyCode == Keys.V)
        
            PasteClipboard();
            e.Handled = true;
        
    

现在:这是我不明白的一点: 当我在空网格(即没有数据、列等)上尝试此操作时,我得到以下信息:

Ctrl+C:

键码 = C 键值 = 67 KeyData = C、Shift、Control 修饰符 = Shift、Control

Ctrl+Shift+C

键码 = C 键值 = 67 KeyData = C、Shift、Control 修饰符 = Shift、Control

但是:一旦我将数据粘贴到网格中,完全相同的 keydown 操作会产生:

Ctrl+C

键码 = C 键值 = 67 KeyData = C,控制 修饰符 = 控制

Ctrl+Shift+C

KeyCode = ShiftKey 键值 = 16 KeyData = ShiftKey、Shift、Control 修饰符 = Shift、Control

当网格中有数据时,不再识别“C”键,我只得到 Ctrl+Shift。

单元格未处于编辑模式(您可以看到 Ctrl+C 工作正常)。我可以将其更改为 Ctrl+K 之类的东西,但我想了解这里可能发生的情况。有什么想法吗?

【问题讨论】:

【参考方案1】:

键修饰符在KeyDown 事件处理程序中有一些特殊的行为。为了处理您特殊复制需求的修饰符检查,我建议关注the 3rd part of my solution here,并进行修改。即,创建一个继承自DataGridView的类:

public class CopyDataGridView : DataGridView

    public bool ProcessShiftCopy  get; set; 

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    
        ProcessShiftCopy = keyData == (Keys.Control | Keys.Shift | Keys.C);
        return base.ProcessCmdKey(ref msg, keyData);
    

然后按照以下步骤操作:

    将您的DataGridView 替换为CopyDataGridView 的实例。 处理CopyDataGridView.KeyUp 事件而不是DataGridView.KeyDown。这是因为KeyDown 不会按我们想要的方式触发键修饰符,但KeyUp 会。

    替换:

    if ((e.Control & e.Shift) && e.KeyCode == Keys.C)
    

    与:

    if (yourCopyDataGridView.ProcessShiftCopy)
    

    处理Ctrl+Shift+C

【讨论】:

谢谢!它有效,我想我知道发生了什么。我从这里查看了 ProcessCmdKey 的作用:link。我看到它检查控件是否有上下文菜单。好吧,我的控件确实有一个上下文菜单,但它只显示 Datagridview 中是否有数据。我认为这就是我的示例中发生的情况,它在没有加载数据的情况下工作 - 即不会显示上下文菜单。

以上是关于带有和不带有数据的 DataGridView 中的按键修饰符的主要内容,如果未能解决你的问题,请参考以下文章

如何在 vb.net 中打印带有标题的 datagridview 表?

带有和不带有聚合的 sql 查询

C# winform datagridview中如何实现鼠标右键点击一行数据出现一个带有删除的菜单,并能执行删除操作?

每个单元格内带有自定义对象的 DataGridView

错误:当传递带有修改行的 DataRow 集合时,更新需要有效的 UpdateCommand

访问控制允许带有和不带有 www 的来源