Skip to content

[syncfusion_flutter_datagrid] Column dragging becomes unresponsive and enters frozen state when combining drag & drop with column resizing #2480

@EduardoYamauchi

Description

@EduardoYamauchi

Bug description

### Bug Description

When both allowColumnsDragging and allowColumnsResizing are enabled, the DataGrid enters an inconsistent state during column reordering operations. The column dragging functionality becomes intermittently unresponsive and sometimes enters a completely frozen state that cannot be recovered without restarting the application.

This behavior is critical as it renders the grid unusable in production environments where users frequently interact with column ordering and sizing.

### Expected Behavior

  • Users should be able to drag columns to reorder them smoothly
  • Column resize handles should remain functional during and after drag operations
  • The grid should maintain a consistent interactive state regardless of how many times columns are dragged or resized
  • No frozen or unresponsive states should occur

### Actual Behavior

  • Intermittent freezing: Sometimes when dragging a column, the drag operation becomes unresponsive mid-drag
  • Permanent frozen state: In certain cases, the grid enters a state where:
    • Columns cannot be dragged anymore
    • The drag indicator remains visible even when not dragging
    • The only recovery is to restart the application
  • Inconsistent behavior: The issue is not deterministic - it occurs randomly after several drag operations
  • Severity increases with interaction: The more the user reorders columns, the higher the probability of encountering the frozen state

### Environment

  • Syncfusion Flutter DataGrid version: 31.2.18 (latest as of this report)
  • Flutter version: stable, 3.35.4
  • Platform tested: web
  • Dart SDK: Compatible with Flutter stable

### Additional Context

Video demonstration: A video showing the bug in action will be attached to this issue, demonstrating:

  • Normal drag behavior initially
  • The progressive degradation of responsiveness
  • The final frozen state where the grid becomes completely unresponsive

Impact

This bug has critical production impact:

  • User experience: Users lose confidence in the application when the grid freezes
  • Data integrity concerns: Users may worry about data loss when the UI becomes unresponsive
  • Workaround limitations: No known workaround exists other than disabling one of the features (either drag or resize)

### Request

Please investigate the interaction between allowColumnsDragging and allowColumnsResizing to identify and resolve this state management issue. Both features are essential for production applications and
need to work reliably together.

Steps to reproduce

### Steps to Reproduce

  1. Run the minimal reproduction code provided below
  2. Drag a column header to reorder it (e.g., drag "Name" column to a different position)
  3. Resize a column by dragging its border
  4. Repeat steps 2-3 multiple times, alternating between dragging and resizing
  5. Issue will occur: After several interactions, one of the following will happen:
    - Column drag will stop responding mid-operation
    - Grid will enter a frozen state where no drag operations work

Code sample

Code sample
 import 'package:flutter/material.dart'; import 'package:syncfusion_flutter_datagrid/datagrid.dart'; void main() { runApp(const TestGridDragResize()); } class TestGridDragResize extends StatefulWidget { const TestGridDragResize({super.key}); @override State<TestGridDragResize> createState() => _TestGridDragResizeState(); } class _TestGridDragResizeState extends State<TestGridDragResize> { late _TestDataSource _dataSource; late List<GridColumn> _columns; @override void initState() { super.initState(); _columns = _buildColumns(); _dataSource = _TestDataSource(); } List<GridColumn> _buildColumns() { return <GridColumn>[ GridColumn( columnName: 'id', width: 80, label: Container( alignment: Alignment.center, padding: const EdgeInsets.all(8), child: const Text('ID', overflow: TextOverflow.ellipsis), ), ), GridColumn( columnName: 'name', width: 140, label: Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.all(8), child: const Text('Name', overflow: TextOverflow.ellipsis), ), ), GridColumn( columnName: 'designation', width: 140, label: Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.all(8), child: const Text('Designation', overflow: TextOverflow.ellipsis), ), ), GridColumn( columnName: 'department', width: 130, label: Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.all(8), child: const Text('Department', overflow: TextOverflow.ellipsis), ), ), GridColumn( columnName: 'email', width: 200, label: Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.all(8), child: const Text('Email', overflow: TextOverflow.ellipsis), ), ), GridColumn( columnName: 'phone', width: 130, label: Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.all(8), child: const Text('Phone', overflow: TextOverflow.ellipsis), ), ), GridColumn( columnName: 'salary', width: 110, label: Container( alignment: Alignment.centerRight, padding: const EdgeInsets.all(8), child: const Text('Salary', overflow: TextOverflow.ellipsis), ), ), GridColumn( columnName: 'experience', width: 100, label: Container( alignment: Alignment.center, padding: const EdgeInsets.all(8), child: const Text('Exp (Yrs)', overflow: TextOverflow.ellipsis), ), ), GridColumn( columnName: 'location', width: 130, label: Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.all(8), child: const Text('Location', overflow: TextOverflow.ellipsis), ), ), GridColumn( columnName: 'status', width: 100, label: Container( alignment: Alignment.center, padding: const EdgeInsets.all(8), child: const Text('Status', overflow: TextOverflow.ellipsis), ), ), ]; } @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( appBar: AppBar( title: const Text('Test Drag & Drop + Resize'), ), body: Padding( padding: const EdgeInsets.all(16), child: Column( children: [ const Card( child: Padding( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Bug Reproduction Steps:', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), ), SizedBox(height: 8), Text('1. Try dragging column headers to reorder them'), Text('2. Try dragging column borders to resize them'), Text('3. Try combining both operations'), SizedBox(height: 8), Text('Settings:', style: TextStyle(fontWeight: FontWeight.bold)), Text('• allowColumnsDragging: true'), Text('• allowColumnsResizing: true'), ], ), ), ), const SizedBox(height: 16), Expanded( child: SfDataGrid( source: _dataSource, columns: _columns, // Enable column drag and drop allowColumnsDragging: true, // Enable column resizing allowColumnsResizing: true, // Callback for drag and drop onColumnDragging: (DataGridColumnDragDetails details) { if (details.action == DataGridColumnDragAction.dropped) { if (details.to == null) return true; final movedColumn = _columns[details.from]; _columns ..removeAt(details.from) ..insert(details.to!, movedColumn); setState(() {}); } return true; }, // Grid lines for better visualization gridLinesVisibility: GridLinesVisibility.both, headerGridLinesVisibility: GridLinesVisibility.both, ), ), ], ), ), ), ); } } // Simple Data Source for testing class _TestDataSource extends DataGridSource { _TestDataSource() { _buildDataRows(); } List<DataGridRow> _dataRows = []; void _buildDataRows() { final departments = ['Engineering', 'Sales', 'Marketing', 'HR', 'Finance']; final locations = ['New York', 'San Francisco', 'London', 'Tokyo', 'Berlin']; final statuses = ['Active', 'On Leave', 'Remote']; _dataRows = List<DataGridRow>.generate( 25, (index) { final name = 'Employee ${index + 1}'; final designation = index % 3 == 0 ? 'Manager' : index % 3 == 1 ? 'Developer' : 'Designer'; return DataGridRow( cells: [ DataGridCell<int>(columnName: 'id', value: 1000 + index), DataGridCell<String>(columnName: 'name', value: name), DataGridCell<String>(columnName: 'designation', value: designation), DataGridCell<String>( columnName: 'department', value: departments[index % departments.length], ), DataGridCell<String>( columnName: 'email', value: 'employee${index + 1}@company.com', ), DataGridCell<String>( columnName: 'phone', value: '+1 555-${1000 + index}', ), DataGridCell<int>( columnName: 'salary', value: 50000 + (index * 2500), ), DataGridCell<int>( columnName: 'experience', value: 1 + (index % 15), ), DataGridCell<String>( columnName: 'location', value: locations[index % locations.length], ), DataGridCell<String>( columnName: 'status', value: statuses[index % statuses.length], ), ], ); }, ); } @override List<DataGridRow> get rows => _dataRows; @override DataGridRowAdapter buildRow(DataGridRow row) { return DataGridRowAdapter( cells: row.getCells().map<Widget>((dataGridCell) { final columnName = dataGridCell.columnName; final alignment = columnName == 'id' || columnName == 'salary' || columnName == 'experience' || columnName == 'status' ? Alignment.center : Alignment.centerLeft; return Container( alignment: alignment, padding: const EdgeInsets.all(8), child: Text( dataGridCell.value.toString(), overflow: TextOverflow.ellipsis, ), ); }).toList(), ); } } 

Screenshots or Video

Screenshots / Video demonstration
Screen.Recording.2025-12-12.at.18.12.26.mov

Stack Traces

Stack Traces

No stack trace detected.

On which target platforms have you observed this bug?

Web

Flutter Doctor output

Doctor output
Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 3.35.4, on macOS 26.1 25B78 darwin-arm64, locale en-BR) [✓] Chrome - develop for the web [✓] IntelliJ IDEA Community Edition (version 2023.2.8) [✓] VS Code (version 1.104.2) [✓] Network resources

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions