问题
I'm looking for a possibility in C# in Windows Forms Application to be able to:
- Select multiple, full rows at a time.
- Include unselected rows between the selected ones.
- 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
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.
Create your own class inherting from
DataGridView
and overrideProcessCmdKey
: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 callingStripEmptyFromCopy
prevents the Clipboard from getting the copy. ReturningFalse
works... but then gets overridden by the default copy and I don't know where this occurs.
- Returning
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