Мы реализовали решение для копирования и вставки данных в Datagrid. Там, где мы получили решение, оно очень хорошо работает для того, что мы пытаемся сделать. Однако мы искали способы ускорить фактическую вставку данных: для небольших объемов данных вставка происходит довольно быстро, но как только набор данных начинает становиться немного больше, мы видим, что скорость замедляется. Итак, я просто ищу способ ускорить функцию вставки, или я знаю, что представления списков иногда в некоторых отношениях работают быстрее, просто не могу придумать, как использовать этот код для разработки нового представления списка копирования/вставки.public class CustomDataGrid : DataGrid
{
public event ExecutedRoutedEventHandler ExecutePasteEvent;
public event CanExecuteRoutedEventHandler CanExecutePasteEvent;
public event CanExecuteRoutedEventHandler CanExecuteDeleteEvent;
private bool ctrlPressed = false;
static CustomDataGrid()
{
CommandManager.RegisterClassCommandBinding(
typeof(CustomDataGrid),
new CommandBinding(ApplicationCommands.Paste,
new ExecutedRoutedEventHandler(OnExecutedPasteInternal),
new CanExecuteRoutedEventHandler(OnCanExecutePasteInternal)));
CommandManager.RegisterClassCommandBinding(
typeof(CustomDataGrid),
new CommandBinding(ApplicationCommands.Delete,
new ExecutedRoutedEventHandler(OnExecutedDeleteInternal),
new CanExecuteRoutedEventHandler(OnCanExecuteDeleteInternal)));
}
public CustomDataGrid()
{
PreviewKeyDown += OnPreviewKeyDown;
PreviewKeyUp += OnPreviewKeyUp;
}
#region Selecting all cells in the clicked column
protected override void OnSorting(DataGridSortingEventArgs eventArgs)
{
SelectColumnCells(eventArgs.Column);
//base.OnSorting(eventArgs);
eventArgs.Handled = true;
}
private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
{
ctrlPressed = true;
}
}
private void OnPreviewKeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.LeftCtrl || e.Key == Key.RightCtrl)
{
ctrlPressed = false;
}
}
private void SelectColumnCells(DataGridColumn column)
{
if (!ctrlPressed)
{
// Clear the selection if Ctrl is not pressed
SelectedCells.Clear();
}
foreach (var item in Items)
{
var cellInfo = new DataGridCellInfo(item, column);
if (!SelectedCells.Contains(cellInfo))
{
SelectedCells.Add(cellInfo);
}
}
}
#endregion
#region Delete Contents in Selected Cells
private static void OnCanExecuteDeleteInternal(object sender, CanExecuteRoutedEventArgs args)
{
((CustomDataGrid)sender).OnCanExecuteDelete(sender, args);
}
private static void OnExecutedDeleteInternal(object sender, ExecutedRoutedEventArgs args)
{
((CustomDataGrid)sender).OnExecutedDelete(sender, args);
}
protected virtual void OnCanExecuteDelete(object sender, CanExecuteRoutedEventArgs args)
{
//Check for External Handlers
if (CanExecuteDeleteEvent != null)
{
CanExecuteDeleteEvent(sender, args);
if (args.Handled)
{
return;
}
}
//Default Delete Event Handler for our CustomDatagrid Class
args.CanExecute = true;
args.Handled = true;
}
protected virtual void OnExecutedDelete(object sender, ExecutedRoutedEventArgs args)
{
var customDataGrid = sender as CustomDataGrid;
if (customDataGrid != null)
{
customDataGrid.DeleteSelectedCells();
}
args.Handled = true;
}
private void DeleteSelectedCells()
{
Mouse.OverrideCursor = Cursors.Wait;
if (SelectedCells.Count == 0)
{
return;
}
//Step 1: To get the selected rows for cases where we need to remove the whole row from the datagrid
List selectedRows = new List();
foreach (DataGridCellInfo cellInfo in SelectedCells)
{
if (cellInfo.IsValid && cellInfo.Item != null && !selectedRows.Contains(cellInfo.Item))
{
selectedRows.Add(cellInfo.Item);
}
}
//Step 2: For each selected row, check if all cells in the row is selected and delete the cell value in a selected cell
foreach (var selectedRow in selectedRows)
{
List AllCellsInARowSelected = new List();
foreach (DataGridColumn column in Columns)
{
bool CurrCellSelected = false;
var cellInfo = new DataGridCellInfo(selectedRow, column);
if (column is DataGridTextColumn && cellInfo.IsValid)
{
var propertyName = column.SortMemberPath; //Assuming SortMemberPath is set to the property name in the column binding
if (SelectedCells.Contains(cellInfo))
{
CurrCellSelected = true;
var dataItem = cellInfo.Item;
var cellValue = dataItem.GetType().GetProperty(propertyName)?.GetValue(dataItem, null);//Get the actual value of the property
var property = cellInfo.Item.GetType().GetProperty(propertyName);
if(property != null)
{
var propertyType = property.PropertyType;
// Type string is a non-generic reference type, but does not need to differenciate nullable since even though it is not nullable, default value is null
// Nullable and non - nullable distinctions are primarily applicable to value types, not reference types
// In this case, IsClass is used instead of (propertyType == typeof(string))
// Nullable value types are represented by the generic type Nullable
// As a result, isNullable is false when the property is a non-nullable value type
//Step 2-1: If the cell contains not null or empty value, delete(null or set default val) the data in the cells
if (!string.IsNullOrWhiteSpace(cellValue?.ToString()))
{
bool isNullable = propertyType.IsClass || (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable));
var emptyValue = isNullable ? null : Activator.CreateInstance(propertyType);
property?.SetValue(cellInfo.Item, emptyValue);
}
}
}
}
//step 2-2: To Chek if all cells in a row are contained in selectedCells
AllCellsInARowSelected.Add(CurrCellSelected);
}
// Step 3: If all cells in the row are contained in selectedCells, except the first column where row select button resides in, delete the row
if (AllCellsInARowSelected.Count(value => !value) == 1)
{
if (ItemsSource is IList itemList)
{
itemList.Remove(selectedRow);
}
}
}
//Step 4: If selectedRow contains not null or Empty values OR selected cells are from different rows, delete the data in the cells
//foreach (DataGridCellInfo cellInfo in SelectedCells)
//{
// if (cellInfo.IsValid && cellInfo.Item != null && cellInfo.Column != null)
// {
// DataGridColumn column = null;
// column = cellInfo.Column as DataGridColumn;
// column?.OnPastingCellClipboardContent(cellInfo.Item, "");
// }
//}
SelectedCells.Clear();
Mouse.OverrideCursor = null;
}
#endregion
// ******************************************************************
#region Clipboard Paste
// ******************************************************************
private static void OnCanExecutePasteInternal(object target, CanExecuteRoutedEventArgs args)
{
((CustomDataGrid)target).OnCanExecutePaste(target, args);
}
// ******************************************************************
///
/// This virtual method is called when ApplicationCommands.Paste command query its state.
///
///
///
protected virtual void OnCanExecutePaste(object target, CanExecuteRoutedEventArgs args)
{
if (CanExecutePasteEvent != null)
{
CanExecutePasteEvent(target, args);
if (args.Handled)
{
return;
}
}
args.CanExecute = CurrentCell != null;
args.Handled = true;
}
// ******************************************************************
private static void OnExecutedPasteInternal(object target, ExecutedRoutedEventArgs args)
{
((CustomDataGrid)target).OnExecutedPaste(target, args);
}
// ******************************************************************
///
/// This virtual method is called when ApplicationCommands.Paste command is executed.
///
///
///
protected virtual void OnExecutedPaste(object target, ExecutedRoutedEventArgs args)
{
this.CanUserResizeColumns = false;
this.AutoGenerateColumns = false;
if (ExecutePasteEvent != null)
{
ExecutePasteEvent(target, args);
if (args.Handled)
{
return;
}
}
Mouse.OverrideCursor = Cursors.Wait;
// parse the clipboard data [row][column]
List clipboardData = ClipboardHelper2.ParseClipboardData();
bool hasAddedNewRow = false;
int minRowIndex = Items.IndexOf(CurrentItem);
int maxRowIndex = Items.Count - 1;
int startIndexOfDisplayCol = (SelectionUnit != DataGridSelectionUnit.FullRow) ? CurrentColumn.DisplayIndex : 0;
//int startIndexOfDisplayCol = CurrentColumn.DisplayIndex;
int clipboardRowIndex = 0;
for (int i = minRowIndex; i
Подробнее здесь: https://stackoverflow.com/questions/793 ... -paste-wpf
Пользовательское копирование/вставка сетки данных WPF ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Обработка данных об буферизации копирование и вставка и очистка данных [закрыто]
Anonymous » » в форуме Html - 0 Ответы
- 9 Просмотры
-
Последнее сообщение Anonymous
-