Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Improving the drag and drop behaviour of WPF datagrid

0.00/5 (No votes)
20 Nov 2011 1  
Change the visual feed back when dragging a non freezable column in to frozen column or Vice versa
The default behavior of the datagrid is that when the user drags across a non frozen column into a frozen column or the other way around, the cursor seems to disappear which causes confusion among the users. This article demonstrates a way of solving this problem by providing a blocked cursor, which provides a clear indication to the user that the operation is not permitted.

The solution depends on the three main events exposed by the data grid namely ColumnHeaderDragStarted, ColumnHeaderDragCompleted, ColumnHeaderDragDelta.

One another approach would be to use the preview mouse events but it has its problems in that these events are not fired during drag and drop unless you set the PreviewMouseLeftButtonDown as handled. In case PreviewMouseLeftButtonDown is marked as handled, then the whole drag and drop functionality will have to be implemented by the developer.

The solution proposed determines the location of the cursor and changes it appropriately after a few calculations.

The following code shows the key events:

C#
void DataGrid_ColumnHeaderDragDelta(object sender, DragDeltaEventArgs e)
{
    currentHorizontalOffset += e.HorizontalChange;
    // Cannot drag a normal column to a frozen column
    if (currentHorizontalOffset < totalFrozenColumnsWidth && isDraggingNormalColumn)
    {
        Mouse.OverrideCursor = Cursors.No;
 
    }
    // Cannot drag a frozen column inside a normal column
    else if (currentHorizontalOffset > totalFrozenColumnsWidth && !isDraggingNormalColumn)
    {
        Mouse.OverrideCursor = Cursors.No;
    }
    // dragging possible
    else
    {
        Mouse.OverrideCursor = Cursors.Arrow;
    }
}
 
void DataGrid_ColumnHeaderDragCompleted(object sender, DragCompletedEventArgs e)
{
    // Restore everything
    totalFrozenColumnsWidth = 0;
    currentHorizontalOffset = 0;
    Mouse.OverrideCursor = previousCursor;
    isDraggingNormalColumn = false;
}
 
void DataGrid_ColumnHeaderDragStarted(object sender, DragStartedEventArgs e)
{
    // Store the current cursor so we can restore it later
    previousCursor = Mouse.OverrideCursor;
    currentHorizontalOffset = e.HorizontalOffset;
 
    // The frozen columns will be at the top of the collection
    if (FrozenColumnCount > 0)
    {
        totalFrozenColumnsWidth = this.Columns.Take(FrozenColumnCount).Sum(c => c.ActualWidth);
 
    }
            
    isDraggingNormalColumn = (currentHorizontalOffset > totalFrozenColumnsWidth) ? true : false;                                           
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here