Column Drag and Drop in MAUI DataGrid (SfDataGrid)

7 Jul 20269 minutes to read

The SfDataGrid allows you to drag and drop a column header by setting the SfDataGrid.AllowDraggingColumn property to true. A drag view is displayed while dragging a column header. You can handle drag and drop operations based on your requirements by using the SfDataGrid.QueryColumnDragging event.

To quickly get started with column drag and drop in .NET MAUI DataGrid, watch this video:

To enable column drag and drop functionality, use the following code example:

<syncfusion:SfDataGrid x:Name="dataGrid"
                           ItemsSource="{Binding OrderInfoCollection}"
                           AllowDraggingColumn="True">
    </syncfusion:SfDataGrid>
dataGrid.AllowDraggingColumn = true;

DataGrid column drag and drop

Column drag and drop events

The QueryColumnDragging event is fired continuously while dragging and dropping a column. By handling this event, you can cancel the dragging of a particular column header.

The QueryColumnDragging event provides the following properties in the DataGridQueryColumnDraggingEventArgs:

  • From: Returns the index of the currently dragging column.
  • To: Returns the index where you are trying to drop the column.
  • DraggingAction: Returns the column dragging status as a DataGridDragAction enum value. Possible values are DragStarted, Dragging, and DragEnded.
  • DraggingPosition: Returns the position (as a Point) of the drag view relative to the SfDataGrid during column drag and drop operations.
  • CanAutoScroll: Returns whether auto-scrolling should happen when the column drag view reaches the left or right ends of the SfDataGrid.
  • Cancel: Set to true to cancel the current drag or drop action. When set during DragStarted, it prevents the column from being dragged. When set during Dragging or DragEnded, it prevents the column from being dropped at the target position.

Control drag and drop behavior

Use the QueryColumnDragging event to restrict or modify column drag and drop operations. The following table shows common scenarios and how to implement them:

Scenario Condition Code Example
Prevent dragging a specific column Check DragStarted action and column index if (e.From == 1 && e.DraggingAction == DataGridDragAction.DragStarted) e.Cancel = true;
Prevent dropping in a specific range Check Dragging or DragEnded and target index if ((e.To > 3 && e.To < 6) && (e.DraggingAction == DataGridDragAction.DragEnded)) e.Cancel = true;
Prevent dropping of a specific column Check DragEnded action and source column if (e.From == 1 && e.DraggingAction == DataGridDragAction.DragEnded) e.Cancel = true;
Prevent dropping at specific positions Check target index if ((e.To == 3 \|\| e.To == 5) && e.DraggingAction == DataGridDragAction.DragEnded) e.Cancel = true;
Prevent dropping at specific coordinates Check DraggingPosition if (e.DraggingPosition == new Point(100, 100) && e.DraggingAction == DataGridDragAction.DragEnded) e.Cancel = true;

The following code example demonstrates implementing drag and drop restrictions:

  • C#
  • dataGrid.QueryColumnDragging += SfDataGrid_QueryColumnDragging;
    
    private void SfDataGrid_QueryColumnDragging(object? sender, DataGridQueryColumnDraggingEventArgs e)
    {
        // Prevent dragging the column at index 1
        if (e.From == 1 && e.DraggingAction == DataGridDragAction.DragStarted)
        {
            e.Cancel = true;
        }
        
        // Prevent dropping in the range between indices 3 and 5
        if ((e.To > 3 && e.To < 6) && e.DraggingAction == DataGridDragAction.DragEnded)
        {
            e.Cancel = true;
        }
    }

    Restrict drag and drop between frozen and non-frozen columns

    Frozen columns can be restricted from being dragged to non-frozen areas or vice versa. The following code example demonstrates how to prevent dragging and dropping between frozen and non-frozen column regions:

  • C#
  • dataGrid.FrozenColumnCount = 2;  // First 2 columns are frozen
    dataGrid.QueryColumnDragging += SfDataGrid_QueryColumnDragging;
    
    private void SfDataGrid_QueryColumnDragging(object? sender, DataGridQueryColumnDraggingEventArgs e)
    {
        int frozenCount = dataGrid.FrozenColumnCount;
        
        // Prevent dragging frozen columns out of the frozen region
        if (e.From < frozenCount && e.To >= frozenCount && 
            e.DraggingAction == DataGridDragAction.DragStarted)
        {
            e.Cancel = true;
        }
        
        // Prevent dragging non-frozen columns into the frozen region
        if (e.From >= frozenCount && e.To < frozenCount && 
            e.DraggingAction == DataGridDragAction.DragStarted)
        {
            e.Cancel = true;
        }
    }

    Note: Frozen columns can be reordered among themselves, and non-frozen columns can be reordered among themselves, but dragging between the two regions is prevented by the code above.

    Customize the appearance

    Customize column drag and drop indicator color

    The SfDataGrid allows customizing the column drag and drop indicators using the SfDataGrid.DefaultStyle.ColumnDraggingIndicatorLineColor property.

  • XAML
  • <syncfusion:SfDataGrid x:Name="dataGrid"
                               ItemsSource="{Binding OrderInfoCollection}"
                               AllowDraggingColumn="True">
            <syncfusion:SfDataGrid.DefaultStyle>
                <syncfusion:DataGridStyle ColumnDraggingIndicatorLineColor="DeepPink"/>
            </syncfusion:SfDataGrid.DefaultStyle>
        </syncfusion:SfDataGrid>

    DataGrid column drag indicator color

    Customize drag view text and background color

    The SfDataGrid allows customizing the drag view text and background color using the SfDataGrid.DefaultStyle.ColumnDragViewTextColor and SfDataGrid.DefaultStyle.ColumnDragViewBackgroundColor properties, respectively.

  • XAML
  • <syncfusion:SfDataGrid x:Name="dataGrid"
                               ItemsSource="{Binding OrderInfoCollection}"
                               AllowDraggingColumn="True">
            <syncfusion:SfDataGrid.DefaultStyle>
                <syncfusion:DataGridStyle ColumnDragViewTextColor="#FFFFFF"
                                  ColumnDragViewBackgroundColor="#FFBF69"/>
            </syncfusion:SfDataGrid.DefaultStyle>
        </syncfusion:SfDataGrid>

    DataGrid column drag view background and text color

    Column drag-and-drop template

    The SfDataGrid allows you to load specific content into the column drag-and-drop template using the SfDataGrid.ColumnDragDropTemplate. The content can be provided through either a DataTemplate or a DataTemplateSelector.

    The template’s data context provides access to the dragged column information through the DataGridColumn binding context, allowing you to display the column header text or other properties.

    The following code snippet demonstrates how to load a data template into the column drag-and-drop view:

    <syncfusion:SfDataGrid x:Name="dataGrid"
                           ItemsSource="{Binding OrderInfoCollection}"
                           AllowDraggingColumn="True">
        <syncfusion:SfDataGrid.ColumnDragDropTemplate>
            <DataTemplate>
                <Grid BackgroundColor="LightBlue" Padding="10">
                    <Label Text="{Binding HeaderText}"
                           TextColor="Orange"
                           FontAttributes="Bold"
                           HorizontalTextAlignment="Center"
                           VerticalTextAlignment="Center" />
                </Grid>
            </DataTemplate>
        </syncfusion:SfDataGrid.ColumnDragDropTemplate>
    </syncfusion:SfDataGrid>

    Column drag and drop template

    Cancel auto scrolling

    Auto-scrolling during column dragging can be disabled using the CanAutoScroll argument in the QueryColumnDragging event.

  • C#
  • dataGrid.QueryColumnDragging += SfDataGrid_QueryColumnDragging;
    
    private void SfDataGrid_QueryColumnDragging(object? sender, DataGridQueryColumnDraggingEventArgs e)
    {
        // Disable scroll while dragging the columns.   
        e.CanAutoScroll = false;
    }