Copy only selected rows without not-selected rows between in RowHeaderSelect mode

狂风中的少年 提交于 2019-12-24 11:58:09

问题


I'm looking for a possibility in C# in Windows Forms Application to be able to:

  1. Select multiple, full rows at a time.
  2. Include unselected rows between the selected ones.
  3. Then copy them to the clipboard without empty spaces (which are left for the unselected rows).

The DataGridViewSelectionMode.FullRowSelect doesn't cut it as I also need to be able to select independent cells. I need to enable the same behaviour in row copying as the DataGridViewSelectionMode.FullRowSelect has but for the DataGridViewSelectionMode.RowHeaderSelect mode. Would that be possible to do?

Thanks in advanced.


回答1:


First, to do this we will be manually removing the empty lines from the default copy results. We will call the following method to do so:

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);
    }
}

Solutions and Cons

  1. My initial thought was to do this by handling the DataGridView.KeyUp event, checking the user input for 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;
        }
    }
    
    • Works fine if C is released first. If Ctrl is released first, the empty rows are still in the Clipboard.
  2. Create your own class inherting from DataGridView and override 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);
        }
    }
    
    • Returning True after calling StripEmptyFromCopy prevents the Clipboard from getting the copy. Returning False works... but then gets overridden by the default copy and I don't know where this occurs.
  3. Combine these ideas to catch Ctrl+C no matter which key is released first in the KeyUp event handler:

    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;
        }
    }
    
    • It's more work, but it gives consistent results vs. option 1.


来源:https://stackoverflow.com/questions/32863711/copy-only-selected-rows-without-not-selected-rows-between-in-rowheaderselect-mod

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!