我实现了基于WPF DataGrid的自定义控件。 我实现的一件事就是从剪贴板粘贴。
出于某种原因,我采取的方法表现得非常慢。 我做了一些性能评估,似乎BeginEdit()占据了大约80%的独家样本。
任何人都可以提供有关我可能做错的任何见解,或者有不同的方法将数据粘贴到WPF DatagGrid中吗?
这是我开展工作的方法:
private void OnExecutedPaste(object sender, ExecutedRoutedEventArgs e)
{
// get clipboard content
List<object[]> rowData = ClipboardHelper.ParseClipboardDataToTypes();
var selectedCellContent = SelectedCells[0].Column.GetCellContent(SelectedCells[0].Item);
if (selectedCellContent != null)
{
var firstCell = SelectedCells.Count > 0 ? selectedCellContent.Parent as DataGridCell : null;
// Get the start & end rows/columns indexes
int minRowIndex = firstCell != null ? firstCell.GetParentRow().GetIndex() : Items.Count - 1;
int maxRowIndex = minRowIndex + rowData.Count;
int minColumnDisplayIndex = (SelectionUnit != DataGridSelectionUnit.FullRow) && firstCell != null
? firstCell.Column.DisplayIndex
: 0;
int maxColumnDisplayIndex = Columns.Count - 1;
// Go through rows
int rowDataIndex = 0;
for (int i = minRowIndex; i <= maxRowIndex && rowDataIndex < rowData.Count; i++, rowDataIndex++)
{
int columnDataIndex = 0;
// Get row view model bound to the row
var rowVM = Items[i];
// Go through columns
for (int j = minColumnDisplayIndex;
j <= maxColumnDisplayIndex && columnDataIndex < rowData[rowDataIndex].Length;
j++, columnDataIndex++)
{
// Get the column
var column = ColumnFromDisplayIndex(j);
// Get the value to be pasted at the cell
object value = rowData[rowDataIndex][columnDataIndex];
CurrentCell = new DataGridCellInfo(rowVM, column);
BeginEdit();
// If first cell in the row we need to refresh item in case is the newitemplaceholder
// BeginEdit() may have triggered NewItemInitializer
if (j == minColumnDisplayIndex) rowVM = Items[i];
// Paste the value in the cell
column.OnPastingCellClipboardContent(rowVM, value);
//CommitEdit(DataGridEditingUnit.Cell, true);
}
if (!CommitEdit())
{
MessageBox.Show(string.Format("Cannot paste clipboard content at row {0}. Make sure the data is valid.", i), "Can't paste row",
MessageBoxButton.OK, MessageBoxImage.Exclamation);
return;
}
if (i >= Items.Count - 1)
{
if (NewItemInitializer == null)
MessageBox.Show("Cannot add new rows for additional items.", "Can't paste row",
MessageBoxButton.OK, MessageBoxImage.Exclamation);
else
OnInitializingNewItem(new InitializingNewItemEventArgs(NewItemInitializer.Invoke()));
}
}
}
}