Skip to content

Conversation

@StephaneDelcroix
Copy link
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
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 from d06e865 to c344859 Compare January 5, 2026 10:08
- Replace existing *ToAsync animation methods with new overloads that accept CancellationToken
- All parameters remain optional (length=250, easing=null, cancellationToken=default)
- When cancelled, animations are properly aborted via AbortAnimation()
- Remove old overloads without CancellationToken (breaking binary change)

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. Source compatibility is maintained due to optional default parameter.
@StephaneDelcroix StephaneDelcroix force-pushed the feature/animation-cancellation-token branch from c344859 to 37affb5 Compare January 5, 2026 10:10
@dotnet-policy-service
Copy link
Contributor

🚨 API change(s) detected @davidortinau FYI

@dotnet dotnet deleted a comment from dotnet-policy-service bot Jan 5, 2026
jfversluis
jfversluis previously approved these changes Jan 5, 2026
- Test pre-canceled tokens return immediately for all animation methods
- Test animations complete normally without cancellation
- Cover FadeToAsync, RotateToAsync, RotateXToAsync, RotateYToAsync
- Cover ScaleToAsync, ScaleXToAsync, ScaleYToAsync
- Cover TranslateToAsync, RelRotateToAsync, RelScaleToAsync
Comment on lines +432 to +436
}.Commit(view, nameof(TranslateToAsync), 16, length, null, (f, a) =>
{
registration.Dispose();
tcs.SetResult(a);
});
Copy link
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
Member

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

Copy link
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.

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.

5 participants