2
votes

I'm trying to drag multiple selected rows from one DataGrid to another. For this I am using a handler for the MouseMove event like this:

    private void Distribution_MouseMove(object sender, MouseEventArgs e)
    {
        base.OnMouseMove(e);
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            var dg = sender as DataGrid;
            if (dg == null) return;
            if (dg.SelectedItems.Count == 0) return;

            Point p = e.GetPosition(this);
            HitTestResult result = VisualTreeHelper.HitTest(this, p);
            var obj = result.VisualHit;

            while (VisualTreeHelper.GetParent(obj) != null && !(obj is DataGridRow))
            {
                obj = VisualTreeHelper.GetParent(obj);
            }
            if (obj == null) return;

            var row = obj as DataGridRow;
            if (row == null) return;

            if (dg.SelectedItems.Contains(row.DataContext))
            {
                e.Handled = true;

                DataObject data = new DataObject();
                data.SetData("registries", dg.SelectedItems.Cast<Registry>().ToList());
                DragDrop.DoDragDrop(this, data, DragDropEffects.Move);
            }
        }
    }

The problem is, having multiple rows selected, clicking to drag and drop makes the clicked row become the only selected row and only that row gets moved.

How can I keep the multiple selection or what other event should I use to start dragging before the selection is changed?

1
What about PreviewMouseMove event, you should try that instead of MouseMove. - King King
@KingKing using PreviewMouseMove shows the same problem. I was trying to do it in [Preview]MouseLeftButtonDown but I can not get it to work without breaking the normal selection behavior. - user3557327

1 Answers

1
votes

I found the answer thanks to this post.

First I added a PreviewMouseLeftButtonDown handler that would add all the selected items to another list:

    private List<Registro> _selected = new List<Registry>();
    private void Distribution_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var dg = sender as DataGrid;
        if (dg == null) return;
        _selected.Clear();
        _selected.AddRange(dg.SelectedItems.Cast<Registry>());
    }

And then on the MouseMove handler added the following after e.Handled = true; and before creating the DataObject:

                foreach (var registry in _selected)
                {
                    if (!dg.SelectedItems.Contains(registry))
                    {
                        dg.SelectedItems.Add(registry);
                    }
                }

It shows visibly the elements being deselected and selected again in the grid, but it works as expected.