Skip to content

Add CancellationToken support to animation methods in ViewExtensions#33372

Open
StephaneDelcroix wants to merge 9 commits intonet11.0from
feature/animation-cancellation-token
Open

Add CancellationToken support to animation methods in ViewExtensions#33372
StephaneDelcroix wants to merge 9 commits intonet11.0from
feature/animation-cancellation-token

Conversation

@StephaneDelcroix
Copy link
Copy Markdown
Contributor

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Description

This PR adds CancellationToken support to all animation methods in ViewExtensions, allowing developers to cancel running animations programmatically.

Changes

  • Replaced existing *ToAsync animation methods with new overloads that accept an optional CancellationToken parameter
  • All parameters remain optional with defaults: length = 250, easing = null, cancellationToken = default
  • When a CancellationToken is cancelled, animations are properly aborted via AbortAnimation()
  • Removed old overloads without CancellationToken

Affected Methods

  • FadeToAsync
  • LayoutToAsync
  • RelRotateToAsync
  • RelScaleToAsync
  • RotateToAsync
  • RotateXToAsync
  • RotateYToAsync
  • ScaleToAsync
  • ScaleXToAsync
  • ScaleYToAsync
  • TranslateToAsync

⚠️ Breaking Change

Binary compatibility is broken for existing code compiled against the old method signatures. The old overloads (without CancellationToken) have been removed and are marked with *REMOVED* in the PublicAPI files.

Source compatibility is maintained - existing source code will continue to compile without changes due to the optional default parameter value (CancellationToken cancellationToken = default).

Migration

No source code changes required. However, projects compiled against older versions of MAUI will need to be recompiled.

Usage Example

// Cancel an animation after 1 second
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1));
await view.FadeToAsync(0, 2000, cancellationToken: cts.Token);

// Or cancel manually
var cts = new CancellationTokenSource();
var animationTask = view.RotateToAsync(360, 5000, cancellationToken: cts.Token);
// ... later
cts.Cancel(); // Animation stops immediately

Testing

  • ✅ All 5,434 Controls.Core.UnitTests pass
  • ✅ Builds successfully for netstandard2.0 and net10.0-android

Copilot AI review requested due to automatic review settings January 5, 2026 10:01
@StephaneDelcroix StephaneDelcroix added this to the .NET 11 Planning milestone Jan 5, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds CancellationToken support to all animation methods in ViewExtensions, allowing developers to cancel running animations programmatically. The changes replace existing animation method overloads with new versions that accept an optional CancellationToken parameter (defaulting to default). While this maintains source compatibility, it breaks binary compatibility as the old overloads without CancellationToken have been removed and marked with *REMOVED* in the PublicAPI files.

Key Changes

  • Added CancellationToken parameter to 11 animation methods (FadeToAsync, LayoutToAsync, RelRotateToAsync, etc.)
  • Old overloads removed and marked as *REMOVED* in PublicAPI tracking files
  • Removed duplicate [Category] attributes from numerous UI test files for cleaner test organization
  • Multiple new test cases and test infrastructure improvements added

Reviewed changes

Copilot reviewed 284 out of 420 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/*.cs (100+ files) Removed duplicate [Category] attributes from UI tests (e.g., removed UITestCategories.Compatibility, UITestCategories.Navigation where tests already had more specific categories)
src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/*.cs (40+ files) Refactored test classes to inherit from _GalleryUITest instead of UITest, added GalleryPageName property, removed manual FixtureSetup methods
src/Controls/tests/TestCases.HostApp/Issues/*.cs/.xaml Added new test pages for issues (Issue28557, Issue28201, Issue22719, Issue13537, Issue33130, Issue30366)
src/Controls/tests/TestCases.HostApp/MauiProgram.cs Added MacCatalyst-specific test startup logic to directly navigate to test pages via environment variable
src/Controls/tests/TestCases.HostApp/CoreViews/CorePageView.cs Added TryToGetGalleryPage method to retrieve gallery pages by title
src/Controls/tests/TestCases.HostApp/TestCases.cs Added TryToGetTestPage method and PageFactory property to support programmatic test page retrieval
src/Controls/src/Xaml/SimplifyOnPlatformVisitor.cs Fixed OnPlatform with abstract types - marks nodes as IsOnPlatformDefaultValue when no platform matches
src/Controls/src/SourceGen/Visitors/CreateValuesVisitor.cs Generates default(T) for OnPlatform nodes marked as IsOnPlatformDefaultValue instead of trying to instantiate abstract types
src/Controls/tests/Core.UnitTests/ShellParameterPassingTests.cs Added tests verifying ApplyQueryAttributes is triggered during TabBar/FlyoutItem navigation (Issue #13537)
src/Controls/tests/SourceGen.UnitTests/InitializeComponent/*.cs Added tests for OnPlatform with abstract types, RelativeSource bindings, and RelayCommand support

@StephaneDelcroix StephaneDelcroix force-pushed the feature/animation-cancellation-token branch 2 times, most recently from c344859 to 37affb5 Compare January 5, 2026 10:10
@dotnet dotnet deleted a comment from dotnet-policy-service Bot Jan 5, 2026
jfversluis
jfversluis previously approved these changes Jan 5, 2026
Comment on lines +432 to +436
}.Commit(view, nameof(TranslateToAsync), 16, length, null, (f, a) =>
{
registration.Dispose();
tcs.SetResult(a);
});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What happens to animations attached to visuals which are removed from the UI tree? Do they get finished/cancelled?
Newbie question: It just feels weird to attach lifetime to animation finishing. Also from a naming perspective, for example I would not be surprised if finish action didn't fire for cancelled animation (I know it does).

@rmarinho
Copy link
Copy Markdown
Member

@copilot can you resolve the conflicts on this branch rebase on net11.0 ?

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 16, 2026

@rmarinho I've opened a new pull request, #33568, to work on those changes. Once the pull request is ready, I'll request review from you.

@rmarinho
Copy link
Copy Markdown
Member

/rebase

@vitek-karas
Copy link
Copy Markdown
Member

Just asking (I don't know our rules in MAUI around this): If there's a NuGet with animations code, this will effectively make it impossible to use that NuGet on .NET 11 - and it will force the NuGet to implement multi-targeting as there's no single binary which can be used on .NET 10 and .NET 11 at the same time.

Personally, I don't see why we can't keep the existing overloads and let them just call the new ones without cancellation token. Yes, it makes the API bigger, but the above risk doesn't feel worth it. If we want to, we can mark the old APIs Obsolete and remove them once .NET 10 goes out of support.

Additionally, this would allow us to ship this in .NET 10 SR and not have to wait for .NET 11.

@StephaneDelcroix StephaneDelcroix force-pushed the feature/animation-cancellation-token branch 2 times, most recently from 1f0432f to ba277d2 Compare February 27, 2026 15:20
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 27, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 33372

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 33372"

@StephaneDelcroix StephaneDelcroix force-pushed the feature/animation-cancellation-token branch from ba277d2 to 80e022f Compare March 2, 2026 08:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants