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.
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
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]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;
//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; }
// ****************************************************************** /// /// This virtual method is called when ApplicationCommands.Paste command query its state. /// /// ///
// ****************************************************************** /// /// 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
Ich implementieren die Filterung mithilfe einer Open-Source-Bibliothek namens DataGridExtensions .
Ich möchte die Filterung für Spalten mit mehreren Beschriftungen in Kombination mit anderen...
Hallo, ich muss eine Liste der Lieferungen in DataGrid anzeigen, indem ich MVVM und Entity Framework in einer WPF-Anwendung verwende. Jeder Lieferung ist ein Kurier zugeordnet, der über den Dialog...
Ich implementieren die Filterung mithilfe einer Open-Source-Bibliothek namens DataGridExtensions .
Ich möchte die Filterung für Spalten mit mehreren Beschriftungen in Kombination mit anderen...
Ich bin neu bei WPF, ich verwende das MVVM-Muster in WPF und erzeuge zur Laufzeit eine Datatable-Struktur und binde dann Datatable mit DataGrid/RadGridView, was wie erwartet funktioniert.
Ich stehe vor einem Problem und komme nicht weiter.
Ich hoffe, Sie können mir helfen.
Kurze Erklärung:
Ich habe ein DataGrid (VirtualizingPanel.IsVirtualizing= true ) und eine Suchleiste. Wenn ich...