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:
void DataGrid_ColumnHeaderDragDelta(object sender, DragDeltaEventArgs e)
{
currentHorizontalOffset += e.HorizontalChange;
if (currentHorizontalOffset < totalFrozenColumnsWidth && isDraggingNormalColumn)
{
Mouse.OverrideCursor = Cursors.No;
}
else if (currentHorizontalOffset > totalFrozenColumnsWidth && !isDraggingNormalColumn)
{
Mouse.OverrideCursor = Cursors.No;
}
else
{
Mouse.OverrideCursor = Cursors.Arrow;
}
}
void DataGrid_ColumnHeaderDragCompleted(object sender, DragCompletedEventArgs e)
{
totalFrozenColumnsWidth = 0;
currentHorizontalOffset = 0;
Mouse.OverrideCursor = previousCursor;
isDraggingNormalColumn = false;
}
void DataGrid_ColumnHeaderDragStarted(object sender, DragStartedEventArgs e)
{
previousCursor = Mouse.OverrideCursor;
currentHorizontalOffset = e.HorizontalOffset;
if (FrozenColumnCount > 0)
{
totalFrozenColumnsWidth = this.Columns.Take(FrozenColumnCount).Sum(c => c.ActualWidth);
}
isDraggingNormalColumn = (currentHorizontalOffset > totalFrozenColumnsWidth) ? true : false;
}