Skip to content

fix: [DataGrid] unregister the IKeyCodeService listener on dispose - #5517

Draft
Christian Pradelli (christian-sig) wants to merge 1 commit into
microsoft:devfrom
christian-sig:fix/datagrid-unregister-keycode-listener
Draft

Christian Pradelli (christian-sig) wants to merge 1 commit into
microsoft:devfrom
christian-sig:fix/datagrid-unregister-keycode-listener

Conversation

@christian-sig

@christian-sig Christian Pradelli (christian-sig) commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Pull Request

📖 Description

FluentDataGrid registers OnKeyDownAsync with IKeyCodeService in OnInitialized, but never unregisters it. Since the service is scoped, every grid disposed during the circuit stays referenced and keeps receiving the global key events from FluentKeyCodeProvider.

On - or +, the stale grid calls SetColumnWidthDiscreteAsync, which invokes its JS module after FluentComponentBase.DisposeAsync released it. The console then shows There was an exception invoking 'OnKeyDownRaisedAsync'.

This is a bug fix and not a breaking change: one line in DisposeAsync().

KeyCodeService.UnregisterListener(OnKeyDownAsync);

UnregisterListener(Func<FluentKeyCodeEventArgs, Task>) matches on HandlerKeyDown == handler. Delegates of the same method on the same instance compare equal, so it removes only this grid's listener.

🎫 Issues

Fixes #5516

👩‍💻 Reviewer Notes

  • The unregistration goes in the public DisposeAsync() (the one that already disposes _currentPageItemsChanged, _selfReference and _scope), not in DisposeAsync(IJSObjectReference). That keeps it independent of whether the JS module was ever imported, for example a grid disposed before its first render.
  • Not addressed here (by design, just for context): the grid's shortcuts (-, +, Shift+R, Shift+S) are global to the document and apply to every live grid regardless of focus.

📑 Test Plan

  • New test FluentDataGrid_UnregistersKeyCodeListener_OnDispose in FluentDataGridTests.razor: render a grid, assert one listener; DisposeComponentsAsync(); assert no listeners.
    • It fails on dev without the fix (Assert.Empty() Failure: Collection was not empty) and passes with it.
  • FluentDataGridTests: 171/171 passing locally (net10.0, Linux).
  • The full Components.Tests suite was not run locally; relying on CI for the rest.

✅ Checklist

General

  • I have added tests for my changes.
  • I have tested my changes.
  • I have updated the project documentation to reflect my changes.
  • I have read the CONTRIBUTING documentation and followed the standards for this project.

AI contribution declaration

AI assistance is allowed; fully AI-generated or autonomous pull requests without meaningful human review are not accepted. See the AI contribution policy.

  • I have read and followed the AI contribution policy.
  • I have personally reviewed and understood all changes, tested them, and take responsibility for this contribution.

Component-specific

  • I have added a new component
  • I have added Unit Tests for my new component
  • I have modified an existing component
  • I have validated the Unit Tests for an existing component

⏭ Next Steps

None.

🤖 Generated with Claude Code

FluentDataGrid registers OnKeyDownAsync in OnInitialized but never
unregisters it. The scoped service kept every disposed grid alive for the
whole circuit, and FluentKeyCodeProvider kept invoking it: on '-' or '+'
the stale grid called its released JS module and the console showed
'There was an exception invoking OnKeyDownRaisedAsync'.

Fixes microsoft#5516
Copilot AI balanced review requested due to automatic review settings October 22, 2026 21:28

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.

🟢 Approval recommended

The focused cleanup matches the existing registration contract and includes a direct regression test; tests were not executed during this review.

No open issues 🎉

What changed in this PR

Fixes #5516 by unregistering the DataGrid’s keyboard listener during disposal, preventing disposed grids from remaining referenced and receiving global key events.

Changes:

  • Removes the listener in public DisposeAsync(), independently of JavaScript module initialization.
  • Adds a regression test that verifies disposal removes the registered listener.
File Description
tests/​Core/​Components/​DataGrid/​FluentDataGridTests.razor Adds listener-removal regression coverage.
src/​Core/​Components/​DataGrid/​FluentDataGrid.razor.cs Unregisters the grid’s keyboard handler during disposal.

Review effort: Balanced

@vnbaaij

Copy link
Copy Markdown
Collaborator

Any reason why this is a draft PR still?

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: FluentDataGrid never unregisters its IKeyCodeService listener in DataGrid

3 participants