Skip to content

T1329677 DataGrid - Column width changes are not applied immediately - #34818

Open
nightskylark wants to merge 12 commits into
DevExpress:mainfrom
nightskylark:T1329677-fix
Open

T1329677 DataGrid - Column width changes are not applied immediately#34818
nightskylark wants to merge 12 commits into
DevExpress:mainfrom
nightskylark:T1329677-fix

Conversation

@nightskylark

@nightskylark nightskylark commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Issue

When columnAutoWidth is enabled, DataGrid calculates and caches rendered column widths in the internal visibleWidth field.

A subsequent programmatic width update, for example:

dataGrid.columnOption('Task_Assigned_Employee_ID', 'width', 700);

updated the column's width option, but the stale calculated visibleWidth continued to take precedence during rendering. As a result, the new width was not reflected until a later layout recalculation or repaint.

Resolution

The columns controller now invalidates stale calculated widths when a column width changes through the public columnOption API. This lets the new explicit width participate in layout immediately.

The invalidation distinguishes between:

  • public or otherwise independent width updates, which must invalidate obsolete calculated widths;
  • internal layout operations, which apply already resolved dimensions through updateColumnDimensions and preserve calculated widths for unaffected columns.

Edge Cases Covered

  • A width change invalidates calculated widths for the changed column and related auto-width columns.
  • Internal resolved-dimension updates preserve calculated widths of unrelated columns.
  • A mixed update batch no longer mistakes a change to another option on a column for a pending visibleWidth update on that column.
  • Multiple columns with actual pending visibleWidth updates in the same batch retain their calculated widths.
  • Pending calculated-width tracking is cleared after the outer update batch, so it cannot affect later independent width changes.
  • Command columns with calculated visibleWidth values are also invalidated when their width is changed programmatically, preventing stale cached widths from overriding the new width.

@nightskylark nightskylark self-assigned this Aug 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a DataGrid column sizing issue where, with columnAutoWidth enabled, setting a column’s width at runtime could be ignored due to a stale cached visibleWidth value. The changes introduce a controlled invalidation of cached visibleWidth when width is explicitly set, while preserving internal resize flows that intentionally update visibleWidth and width together.

Changes:

  • Add ColumnsController.updateColumnDimensions() to apply internally-computed sizing updates without triggering visibleWidth invalidation.
  • Invalidate stale visibleWidth values when width changes via columnOptionCore, avoiding stale best-fit widths.
  • Add integration + TestCafe coverage for immediate application of runtime columnOption(..., 'width', ...) changes.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/devextreme/testing/tests/DevExpress.ui.widgets.dataGrid/columnsController.tests.js Minor formatting-only change in existing QUnit tests (removed an empty line).
packages/devextreme/testing/helpers/gridBaseMocks.js Adds updateColumnDimensions to mocks to support new internal sizing update API in tests/mocks.
packages/devextreme/js/__internal/grids/grid_core/columns_resizing_reordering/m_columns_resizing_reordering.ts Refactors resizing to compute dimension updates and apply them via updateColumnDimensions.
packages/devextreme/js/__internal/grids/grid_core/columns_controller/m_columns_controller.ts Introduces ColumnDimensionsUpdate and updateColumnDimensions, and adapts columnOptionCore invocation signature.
packages/devextreme/js/__internal/grids/grid_core/columns_controller/m_columns_controller_utils.ts Adds visibleWidth invalidation logic on width changes and a “pending batch” guard.
packages/devextreme/js/__internal/grids/grid_core/columns_controller/tests/columns_controller.integration.test.ts Adds Jest coverage for stale visibleWidth invalidation and for updateColumnDimensions behavior.
e2e/testcafe-devextreme/tests/dataGrid/common/columnResizing/functional.ts Adds end-to-end tests validating immediate column width application without repaint and related column width updates.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +725 to +726
return columnChanges.columnIndex === columnIndex
|| !!columnChanges.columnIndices?.includes(columnIndex);
@nightskylark
nightskylark marked this pull request as ready for review August 25, 2026 14:48
@nightskylark
nightskylark requested a review from a team as a code owner August 25, 2026 14:48
Copilot AI review requested due to automatic review settings August 25, 2026 14:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

changedColumn.visibleWidth = null;
}

that._columns.forEach((column) => {
Copilot AI review requested due to automatic review settings August 25, 2026 15:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment on lines +731 to +735
const invalidateStaleVisibleWidths = (that: ColumnsController, changedColumn): void => {
if (isDefined(changedColumn.visibleWidth)
&& !isVisibleWidthChangePendingForColumn(that, changedColumn.index)) {
changedColumn.visibleWidth = null;
}
Copilot AI review requested due to automatic review settings August 25, 2026 15:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

e2e/testcafe-devextreme/tests/dataGrid/common/columnResizing/functional.ts:84

  • This test asserts an exact 700px column width (±1) but the widget/container width is not fixed, so the resulting layout can depend on the runner viewport size and make the assertion flaky. Set an explicit dxDataGrid width in createWidget to make the measured column width deterministic.
  await createWidget('dxDataGrid', {
    dataSource: [{ Task_Subject: 'Test' }],
    columnAutoWidth: true,
    columns: [

Copilot AI review requested due to automatic review settings August 25, 2026 15:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

packages/devextreme/js/__internal/grids/grid_core/columns_controller/m_columns_controller_utils.ts:674

  • fireColumnsChanged clears _pendingVisibleWidthColumnIndices before calling the onColumnsChanging callback. If the callback calls columnOption('visibleWidth', ...) (even accidentally), the pending set can be repopulated while _updateLockCount is artificially incremented and then will persist after the callback completes, potentially preventing later width changes from invalidating stale visibleWidth values. Consider clearing _pendingVisibleWidthColumnIndices again after the callback returns when _updateLockCount drops back to 0.
export const fireColumnsChanged = function (that: ColumnsController) {
  if (!that._updateLockCount) {
    that._pendingVisibleWidthColumnIndices = undefined;
  }

  const onColumnsChanging: any = that.option('onColumnsChanging');
  const columnChanges = that._columnChanges;
  const reinitOptionNames = ['dataField', 'lookup', 'dataType', 'columns'];
  const needReinit = (options) => options && reinitOptionNames.some((name) => options[name]);

  if (that.isInitialized() && !that._updateLockCount && columnChanges) {
    if (onColumnsChanging) {
      that._updateLockCount++;
      onColumnsChanging(extend({ component: that.component }, columnChanges));
      that._updateLockCount--;
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants