0
votes

I am implementing a drag and drop solution for re-ordering rows in a WPF DataGrid.

My data grid has grouping implemented using a ListCollectionView. My PreviewMouseMove event is fired by the DataGridRows. However, when a user attempts to drag a group header, the event is also fired and I need a way to determine if this is coming from an actual data row or just a group header.

I have attempted several things from the sender object and MouseButtonEventArgs OriginalSource, but I haven't found anything that indicates what I'm looking for.

XAML for DataGrid Group Style:

<DataGrid.GroupStyle>
    <GroupStyle>
        <GroupStyle.ContainerStyle>
            <Style TargetType="{x:Type GroupItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type GroupItem}">
                            <StackPanel>
                                <TextBlock Text="{Binding Items[0].ScheduledStartDate, StringFormat='MMM dd'}" Style="{StaticResource DateHeader}"/>
                                <ItemsPresenter/>
                            </StackPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </GroupStyle.ContainerStyle>
    </GroupStyle>
</DataGrid.GroupStyle>

The Event Handler:

private void DataGridRow_OnPreviewMouseMove(object sender, MouseEventArgs e)
{
    if (!_isDragging &&
        e.LeftButton == MouseButtonState.Pressed)
    {
        // Get the current mouse position
        Point currentMousePosition = e.GetPosition(null);
        Vector positionDiff = _dragStartPoint - currentMousePosition;

        if ((Math.Abs(positionDiff.X) > SystemParameters.MinimumHorizontalDragDistance ||
             Math.Abs(positionDiff.Y) > SystemParameters.MinimumVerticalDragDistance))
        {
            // Start drag operation
            _isDragging = true;

            // Get item to drag
            DataGridRow dataGridRow = sender as DataGridRow;
            DataGrid dataGrid = UIHelper.FindAncestor<DataGrid>((DependencyObject) sender);

            if (dataGridRow != null &&
                dataGridRow.Item is WorkOrder)
            {
                DataObject dragData = new DataObject("WorkOrder", (WorkOrder) dataGridRow.Item);

                // Initialize drag and drop operation
                DragDrop.DoDragDrop(dataGridRow, dragData, DragDropEffects.All);
            }

            _isDragging = false;
        }
    }
}
1

1 Answers

1
votes

A hack/thought may be to create a special control in the DataGridRowHeader's cell and then to determine if the Mouse is over that. In the drag/drop behaviors I've had to generate, we generally created special columns that a user could click to drag/drop the rows, but to find them, we needed to toss in a special control to be sure. I would think it is mostly the same, just toss the control in the header.