Click here to Skip to main content
15,884,986 members
Articles / Desktop Programming / WPF
Tip/Trick

Improving the drag and drop behaviour of WPF datagrid

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
20 Nov 2011CPOL 16.9K  
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Venteq Inc
United States United States
I am Vasudevan Kannan ,currently working on a project for a reputed health care organization in Greater Salt Lake Area.

I got addicted to computers and programming from my child hood.My key skills include WPF and Silverlight and enjoy reading and writing technical articles during my free time

Comments and Discussions

 
-- There are no messages in this forum --