Is there an easy way of adding copy-paste for a listview, or should I just switch to DataGridView instead?
My application is kinda like an address book, it contains emails, numbers etc where copy paste would be useful.
Is there an easy way of adding copy-paste for a listview, or should I just switch to DataGridView instead?
My application is kinda like an address book, it contains emails, numbers etc where copy paste would be useful.
The example below handles the Ctrl-C as a copy to the clipboard command, and copies the second column's value from all the selected rows:
private void resultsListView_KeyUp(object sender, KeyEventArgs e)
{
if (sender != resultsListView) return;
if (e.Control && e.KeyCode == Keys.C)
CopySelectedValuesToClipboard();
}
private void CopySelectedValuesToClipboard()
{
var builder = new StringBuilder();
foreach (ListViewItem item in resultsListView.SelectedItems)
builder.AppendLine(item.SubItems[1].Text);
Clipboard.SetText(builder.ToString());
}
Use item.Text
for the first column, and item.SubItems[n].Text
for other columns.
References:
builder.AppendLine(item.SubItems[1].Text);
Instead, I had to use builder.AppendLine(item.Text);
–
Suint It's not very difficult to do manual copy and paste, just put in an event handler for KeyDown
(or maybe it's KeyPress
can't remember but fairly sure it's one of them) and check what key is pressed by looking at e.KeyCode
and check if e.Control
is true. If it's one of x
, c
or v
just call Clipboard.SetText
or Clipboard.GetText
to write/read to/from the clipboard.
See here for the MSDN documentation of the Clipboard
class.
You could add a context menu with Copy and Paste on to the ListView also to make it complete.
ListView
, it might be easier to switch to a DataGridView
. However, if you do want to stick with the ListView
you could do something like handling Click
and MouseDown
events on it to calculate what subitem was clicked and then changing the BackColor
of that subitem to make it look selected and then you could handle copy and paste for just that subitem. You'd have to make sure to set UseItemStyleForSubItems = false;
on the Item though, otherwise the colours won't show on the subitems. –
Through I've made it as method (depending on @brett's top answer), so just execute once on Form initialization: copyableListView(myListView)
and it will do itself.
Code:
private void copyableListView(ListView listView)
{
listView.KeyDown += (object sender, KeyEventArgs e) =>
{
if (!(sender is ListView)) return;
if (e.Control && e.KeyCode == Keys.C)
{
var builder = new StringBuilder();
foreach (ListViewItem item in (sender as ListView).SelectedItems)
builder.AppendLine(item.Text + Environment.NewLine);
Clipboard.SetText(builder.ToString());
}
};
}
Also, on form destroy, you should have method to remove all subscribed-events, i.e.
void myDeinit()
{
myListView=null;
myListView2=null;
...
}
My requirement was to add a button to copy a list of serial numbers to the clipboard. I added the button in the normal fashion and then added the following method:
private void btnClipboard_Click(object sender, EventArgs e)
{
String clipText = string.Empty;
foreach (ListViewItem item in lstSerials.Items)
{
clipText += item.SubItems[0].Text;
clipText += Environment.NewLine;
}
if (!String.IsNullOrEmpty(clipText))
{
Clipboard.SetText(clipText);
}
}
Based on @Brett's answer, I wrote this method that copies the whole selected rows instead of just a single column (Especially good when FullRowSelect = true).
Two more improvements:
1.Ignore any newline - as ListView does.
2.Avoid an exception when no row is selected - Just clear the clipboard.
private void ListViewLogs_KeyDown(object sender, KeyEventArgs e)
{
CopySelectedRowsToClipboard(listViewLogs, e);
}
private void CopySelectedRowsToClipboard(ListView listView, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.C)
{
var builder = new StringBuilder();
foreach (ListViewItem item in listView.SelectedItems)
{
var subItems = item.SubItems.Cast<ListViewItem.ListViewSubItem>()
.Select(subItem => subItem.Text);
builder.AppendLine(string.Join(", ", subItems).Replace(Environment.NewLine, ""));
}
if (builder.Length > 0)
Clipboard.SetText(builder.ToString());
else
Clipboard.Clear();
}
}
© 2022 - 2024 — McMap. All rights reserved.
KeyDown
event.KeyUp
did not work, because when pressing thec
it was auto-selecting the first entry in the ListBox which started with ac
, rendering my multiselection to just a single one. – Lampert