Benutzerdefiniertes Datagrid WPF kopieren/einfügenC#

Ein Treffpunkt für C#-Programmierer
Guest
 Benutzerdefiniertes Datagrid WPF kopieren/einfügen

Post by Guest »

Wir haben eine Lösung zum Kopieren und Einfügen von Daten in ein Datagrid implementiert. Wo wir die Lösung haben, funktioniert diese Lösung sehr gut für das, was wir zu tun versuchen. Wir haben jedoch nach Möglichkeiten gesucht, das eigentliche Einfügen von Daten zu beschleunigen. Bei kleinen Datenmengen geht das Einfügen ziemlich schnell, aber sobald der Datensatz etwas größer wird, stellen wir fest, dass die Geschwindigkeit nachlässt. Ich suche also nur nach einer Möglichkeit, die Einfügefunktion möglicherweise zu beschleunigen, oder ich weiß, dass Listenansichten manchmal in mancher Hinsicht schneller sind. Mir fällt einfach keine Möglichkeit ein, diesen Code zum Entwickeln einer neuen Listenansicht zum Kopieren/Einfügen zu verwenden.

Code: Select all

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

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post