wpf drag-and-drop wpfdatagrid

WPF Datagrid arrastrar y soltar preguntas



drag-and-drop wpfdatagrid (2)

Tengo una WPF Datagrid y estoy implementando la funcionalidad de arrastrar y soltar.
La cuadrícula de datos tiene una lista de "archivos" y el usuario puede arrastrarlos y copiar el archivo al escritorio.
Esto se hace así:

string[] files = new String[myDataGrid.SelectedItems.Count]; int ix = 0; foreach (object nextSel in myDataGrid.SelectedItems) { files[ix] = ((Song)nextSel).FileLocation; ++ix; } string dataFormat = DataFormats.FileDrop; DataObject dataObject = new DataObject(dataFormat, files); DragDrop.DoDragDrop(this.myDataGrid, dataObject, DragDropEffects.Copy);

Tengo dos preguntas:
1. Cuando quiero arrastrar varios elementos, esto es un problema porque después de seleccionar un par y comenzar a hacer clic en uno para comenzar a arrastrar, solo se selecciona eso y los demás elementos se anulan. Probé la solución que se da aquí, pero por alguna razón no funciona.
2. Deseo eliminar el elemento arrastrado de la cuadrícula de datos después de que se haya copiado. El problema es que no sé cómo verificar si el archivo fue copiado o si el usuario simplemente lo arrastró en la pantalla sin copiarlo.

Espero que me puedas ayudar a resolver estos problemas.
¡Gracias!


Creo que esto es lo que estás buscando:

agregue este código al controlador de eventos DataGrid__PreviewMouseLeftButtonDown:

private void DataGrid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { this.startingPosition = e.GetPosition(null); DependencyObject dep = (DependencyObject)e.OriginalSource; // iteratively traverse the visual tree until get a row or null while ((dep != null) && !(dep is DataGridRow)) { dep = VisualTreeHelper.GetParent(dep); } //if this is a row (item) if (dep is DataGridRow) { //if the pointed item is already selected do not reselect it, so the previous multi-selection will remain if (songListDB.SelectedItems.Contains((dep as DataGridRow).Item)) { // now the drag will drag all selected files e.Handled = true; } } }

y ahora el arrastre no cambiará tu selección.

¡Ten buena suerte!

Usé ese artículo para escribir mi respuesta


Mejorado al encontrar la fila. También se agrega la selección de la fila cliqueada cuando no se está arrastrando. Esto ahora se comporta exactamente como otros selectores de Microsoft (por ejemplo, Outlook)

public TreeDataGrid() { Loaded += TreeDataGrid_Loaded; LoadingRow += new EventHandler<DataGridRowEventArgs>(TreeDataGrid_LoadingRow); } #region MultiSelect Drag object toSelectItemOnMouseLeftButtonUp; void TreeDataGrid_LoadingRow(object sender, DataGridRowEventArgs e) { e.Row.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(Row_PreviewMouseLeftButtonDown); e.Row.PreviewMouseLeftButtonUp += new MouseButtonEventHandler(Row_PreviewMouseLeftButtonUp); } void Row_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { DataGridRow row = (DataGridRow)sender; toSelectItemOnMouseLeftButtonUp = null; // always clear selecteditem if (SelectedItems.Contains(row.Item)) //if the pointed item is already selected do not reselect it, so the previous multi-selection will remain { e.Handled = true; // this prevents the multiselection from disappearing, BUT datagridcell still gets the event and sets DataGrid''s private member _selectionAnchor toSelectItemOnMouseLeftButtonUp = row.Item; // store our item to select on MouseLeftButtonUp } } void Row_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { DataGridRow row = (DataGridRow)sender; if (row.Item == toSelectItemOnMouseLeftButtonUp) // check if it''s set and concerning the same row { if (SelectedItem == toSelectItemOnMouseLeftButtonUp) SelectedItem = null; // if the item is already selected whe need to trigger a change SelectedItem = toSelectItemOnMouseLeftButtonUp; // this will clear the multi selection, and only select the item we pressed down on typeof(DataGrid).GetField("_selectionAnchor", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this, new DataGridCellInfo(row.Item, ColumnFromDisplayIndex(0))); // we need to set this anchor for when we select by pressing shift key toSelectItemOnMouseLeftButtonUp = null; // handled } } #endregion