I'm having trouble pasting from a csv into the wpf datagrid - I have followed the suggestions here
and the code exectues with no problem - however, it seems that all the new rows are created but only the first row gets populated with data. The data seems to be constantly overwritten so that the last item that is in the clipboard data is populated in the first row and all other rows are blank. I know this must be an index issue or something but I cannot track it down.
Also when I have a look at the objects in the grid's bindable collection none of them have any data in. Is there something in the OnPastingCellClipboardContent of the column that is going wrong (data conversion perhaps)?
Any ideas (see the code below)
protected virtual void OnExecutedPaste(object sender, ExecutedRoutedEventArgs args)
{
// parse the clipboard data
List<string[]> rowData = ClipboardHelper.ParseClipboardData();
bool hasAddedNewRow = false;
// call OnPastingCellClipboardContent for each cell
int minRowIndex = Math.Max(Items.IndexOf(CurrentItem), 0);
int maxRowIndex = Items.Count - 1;
int minColumnDisplayIndex = (SelectionUnit != DataGridSelectionUnit.FullRow) ? Columns.IndexOf(CurrentColumn) : 0;
int maxColumnDisplayIndex = Columns.Count - 1;
int rowDataIndex = 0;
for (int i = minRowIndex; i <= maxRowIndex && rowDataIndex < rowData.Count; i++, rowDataIndex++)
{
if (CanUserAddRows && i == maxRowIndex)
{
// add a new row to be pasted to
ICollectionView cv = CollectionViewSource.GetDefaultView(Items);
IEditableCollectionView iecv = cv as IEditableCollectionView;
if (iecv != null)
{
hasAddedNewRow = true;
iecv.AddNew();
if (rowDataIndex + 1 < rowData.Count)
{
// still has more items to paste, update the maxRowIndex
maxRowIndex = Items.Count - 1;
}
}
}
else if (i == maxRowIndex)
{
continue;
}
int columnDataIndex = 0;
for (int j = minColumnDisplayIndex; j < maxColumnDisplayIndex && columnDataIndex < rowData[rowDataIndex].Length; j++, columnDataIndex++)
{
DataGridColumn column = ColumnFromDisplayIndex(j);
column.OnPastingCellClipboardContent(Items[i], rowData[rowDataIndex][columnDataIndex]);
}
}
}
If I'm right you should also need a range check for variable j:
Otherwise you get an ArgumentOutOfRangeException when pasting content with more columns your grid actually can hold.
Thanks,
The post is very good by Vincent but KlausG Added some corrections in it that should also be considered to work with FrameWork 4.0. Very important
Original Web Site post from Vincent: http://blogs.msdn.com/b/vinsibal/archive/2008/09/25/pasting-content-to-new-rows-on-the-wpf-datagrid.aspx
Note: If you can't add row ensure that you have a default constructor for your item.
Updated 2018-03-06 (to support DataGrid with columns re-ordered by user)
Usage
CustomDataGrid
Also: Clipboard Helper:
CsvHelper.cs
ClipboardHelper2.cs
Small correction in CsvHelper.cs from @eric-ouellet answer. When copying from Excel with any blank cell, the data mapping doesn't apply correctly. I modified the Regex for ParseLineTabSeparated method.
For those interested - there does seem to be something going wrong with the columns attempt to update the value of the bindable object - possible data type conversion so i have implemented this myself and it works like a charm now.
}