在RowHeaderSelect模式下,只复制选中的行,而不复制未选中的行

本文关键字:复制 RowHeaderSelect 模式 | 更新日期: 2023-09-27 18:15:10

我正在寻找一种可能性在c#在Windows窗体应用程序能够:

  1. 一次选择多个完整行。
  2. 在选中的行之间包含未选中的行。
  3. 然后将它们复制到剪贴板上,不留下空白(为未选择的行留下空白)。

DataGridViewSelectionMode.FullRowSelect不能切割它,因为我还需要能够选择独立的细胞。我需要启用与DataGridViewSelectionMode.FullRowSelect相同的行复制行为,但对于DataGridViewSelectionMode.RowHeaderSelect模式。这可能吗?

在RowHeaderSelect模式下,只复制选中的行,而不复制未选中的行

首先,要做到这一点,我们将手动从默认复制结果中删除空行。为此,我们将调用以下方法:

private void StripEmptyFromCopy()
{
    string[] separated = Clipboard.GetText().Split(''n').Where(s => !String.IsNullOrWhiteSpace(s)).ToArray();
    string copy = String.Join("'n", separated);
    if (!String.IsNullOrEmpty(copy))
    {
        Clipboard.SetText(copy);
    }
}

解决方案和缺点

  1. 我最初的想法是通过处理DataGridView.KeyUp事件来做到这一点,检查用户输入Ctrl+C:

    private void dataGridView1_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.C && (Control.Modifiers & Keys.Control) == Keys.Control)
        {
            StripEmptyFromCopy();
            e.Handled = true;
        }
    }
    
      如果先释放C
    • 可以正常工作。如果先释放Ctrl,则空白行仍在剪贴板中。
  2. 创建自己的类继承DataGridView和覆盖ProcessCmdKey:

    public class CopyDataGridView : DataGridView
    {
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == (Keys.Control | Keys.C))
            {
                StripEmptyFromCopy();
                return false;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }
    }
    
    • 调用StripEmptyFromCopy后返回True阻止剪贴板获取副本。返回False works…但随后被默认副本覆盖,我不知道这发生在哪里。
  3. 结合这些想法来捕获Ctrl+C,无论在KeyUp事件处理程序中哪个键先释放:

    public class CopyDataGridView : DataGridView
    {
        public bool Copying { get; set; }
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            Copying = keyData == (Keys.Control | Keys.C);
            return base.ProcessCmdKey(ref msg, keyData);
        }
    }
    // And in the form:
    copyDataGridView1.KeyUp += CopyDataGridView1_KeyUp;
    private void CopyDataGridView1_KeyUp(object sender, KeyEventArgs e)
    {
        if (copyDataGridView1.Copying)
        {
            StripEmptyFromCopy();
            copyDataGridView1.Copying = false;
            e.Handled = true;
        }
    }
    
    • 这是更多的工作,但它提供一致的结果与选项1。