Repository navigation
Releases
v17.0.0: Update to .NET 11
This release updates CommunityToolkit.Maui to .NET 11.
It also enables Runtime Async only on the net11.0-windows TFM. Runtime Async is not enabled on the Mono Runtime and is not recommended for any NuGet library that may be consumed by an app using the Mono Runtime.
We have removed code supporting the Tizen TFM as Tizen was no longer supported in .NET MAUI starting with .NET 10.
We have also removed code supporting CommunityToolkit.Maui.Maps. See the Release Notes for CommunityToolkit.Maui.Maps v5.0.0 for more information.
Breaking Changes
The update to .NET 11 required us to modify some APIs and their underlying behavior. Please find the features you use, below, and update your apps accordingly.
All packages
-
API
- Minimum OS versions in the API. The
AppBuilderExtensionsclasses declare[SupportedOSPlatform]iOS 15.0, Mac Catalyst 17.0 and Android 24.0 (MediaElement: Android 26.0), the .NET MAUI 11 minimums. Attributes that only restated a version below these minimums are removed or made versionless; this only relaxes the analyzer. Feature-specific changes are in the CameraView, FileSaver and FolderPicker, MediaElement, NavigationBar (Android), SemanticOrderView, and StatusBar and StatusBarBehavior sections. - No Tizen API surface. The Tizen
[SupportedOSPlatform]and[UnsupportedOSPlatform]attributes and the Tizen code paths are removed.
Behavior
- Converters use the culture the binding passes. With no
ConverterCulture, .NET MAUI passesCultureInfo.CurrentUICulture, as .NET MAUI 10 did.- These converters used the thread's
CurrentCultureinstead:ColorToCmykStringConverter,ColorToHslStringConverter,ColorToHslaStringConverter,CompareConverter,IsInRangeConverter,ListToStringConverter,MathExpressionConverterandMultiMathExpressionConverter. - Their output changes only when
ConverterCultureis set or when an app's UI language differs from its regional format. TextCaseConverteralways used invariant casing instead, so its output also changes when the binding's culture is Turkish or Azerbaijani (see its section).- A
nullculture (calling a converter directly) keeps the previous behavior. - Each converter's section says what it does with the culture.
ColorToRgbaStringConverter,DateTimeOffsetConverterandDoubleToIntConverterhave separate changes, also in their sections.
- These converters used the thread's
Setup
- .NET 11 only. The libraries target
net11.0and its platforms; .NET 10 apps should stay on the last .NET 10 releases (CommunityToolkit.Maui 15.x, CommunityToolkit.Maui.Camera 6.x, CommunityToolkit.Maui.MediaElement 10.x). The minimum OS versions are .NET MAUI 11's: iOS 15.0, Mac Catalyst 17.0 (macOS 14), Android 7.0 (API 24), Windows 10 1809 (10.0.17763); CommunityToolkit.Maui.MediaElement still requires Android 8.0 (API 26). .NET MAUI 11 itself no longer supports the older versions. - Tizen is no longer supported. The packages already shipped no Tizen target; .NET MAUI 11 dropped Tizen.
- Dependencies: the libraries reference .NET MAUI 11 (
Microsoft.Maui.Controls11.0.0), and CommunityToolkit.Maui.Core referencesSystem.Speech11.0.0 on Windows (pending: RC versions until the last commit).
Smaller changes
- Windows: the async methods of the
net11.0-windowsassemblies are runtime async. No API or functional change: the compiler no longer generates async state machines for these methods (exceptasync voidones), and the runtime handles their suspension instead. - Informational, from .NET MAUI 11: on iOS and Mac Catalyst, .NET MAUI 11 skips animations while the system's Reduce Motion setting is on, so the toolkit's animations (
TouchBehavior,FadeAnimation, the animation behaviors) finish at once for those users. The toolkit doesn't change this.
- Minimum OS versions in the API. The
CameraView
-
API
- CommunityToolkit.Maui.Camera declares
[SupportedOSPlatform]Windows 10.0.17763 (was 10.0.10240), like the other libraries.
- CommunityToolkit.Maui.Camera declares
ColorConversionExtensions
-
API
- New
ToCmykString(CultureInfo?)andToHslString(CultureInfo?)overloads. Anullculture usesCurrentCulture.
Behavior
ToHslaString(CultureInfo?)formats the hue, saturation and lightness with the given culture too, not only the alpha, so the string no longer mixes two cultures. Anullculture still usesCurrentCulture.
- New
ColorToCmykStringConverter, ColorToHslStringConverter and ColorToHslaStringConverter
-
Behavior
- Percentages are formatted with the culture the binding passes (see All packages).
ColorToHslaStringConverter: the string no longer mixes two cultures (see ColorConversionExtensions).
ColorToRgbaStringConverter
-
Behavior
- Converts back its own output in comma-decimal cultures; before,
RGBA(255,0,0,0,5)under de-DE converted back toTransparent. A direct call with anullculture usesCurrentCultureboth ways. (The HSLA and CMYKA converters are one-way.)
- Converts back its own output in comma-decimal cultures; before,
CompareConverter
-
Behavior
- Strings are compared with the culture's collation, using the culture the binding passes (see All packages).
DateTimeOffsetConverter
-
Behavior
- No longer applies the culture's calendar to the date: it produced wrong years under th-TH and fa-IR and threw under ar-SA. It also keeps sub-microsecond ticks.
DoubleToIntConverter
-
Behavior
- Parses a string
ConverterParameterwith the invariant culture first, soConverterParameter=2.5means 2.5 for every user, and falls back to the binding's culture, so2,5still works in comma-decimal cultures. - A parameter with only
.separators is now always a decimal:1.000under de-DE means 1 (it meant 1000).
- Parses a string
DrawingView
-
Behavior
- On iOS and Mac Catalyst, exporting an image off the main thread no longer risks a crash on .NET 11's CoreCLR (the
CGColorof a temporaryUIColorcould be freed while it was read).
- On iOS and Mac Catalyst, exporting an image off the main thread no longer risks a crash on .NET 11's CoreCLR (the
EventToCommandBehavior
-
API
- New
EventToCommandBehavior.EventArgsConverterCultureproperty (CultureInfo?, defaultnull=CultureInfo.InvariantCulture, the previous behavior).
- New
FileSaver and FolderPicker
-
API
- The
[SupportedOSPlatform]attributesiOS14.0/MacCatalyst14.0onFileSaverandFolderPickerare nowiOS/MacCatalyst(see All packages).
Behavior
- On Windows (.NET 11):
- With no visible app window they fail with
FileSaveException/FolderPickerException("No active window found") as on .NET 10, instead of opening a dialog over a hidden window. - An app with no windows no longer gets an
ArgumentOutOfRangeException, and .NET MAUI embedded in a WinUI app no longer gets a false "No active window found". - Canceling the
CancellationTokencloses the open save or folder dialog and returns a canceled result, as on .NET 10, instead of waiting until the person closes the dialog. If the person has the "Confirm Save As" prompt open, the save ends canceled once they answer it, and nothing is written. - Picks on the same window now take turns: a pick that starts while another
FileSaverorFolderPickerdialog is open on that window waits until that dialog closes, and canceling its token ends the wait with a canceled result. - A cancel can still close a dialog that other code opened on the same window during the canceled pick, such as the app's own message box, because nothing marks a picker dialog as the toolkit's.
- With no visible app window they fail with
- The
GravatarImageSource
-
Behavior
- The default-image keyword sent to Gravatar is lowercased with the invariant culture. Under Turkish and Azerbaijani cultures
identiconandmonsteridwere sent asıdenticonandmonsterıd, which Gravatar doesn't recognize.
- The default-image keyword sent to Gravatar is lowercased with the invariant culture. Under Turkish and Azerbaijani cultures
IsInRangeConverter
-
Behavior
- Strings are compared with the culture's collation, using the culture the binding passes (see All packages).
ListToStringConverter
-
Behavior
- Numbers and dates in the list are formatted with the culture the binding passes (see All packages).
- A custom item type whose
ToString()differs from itsIFormattable.ToString(null, provider)changes output even without a culture.
...
MediaElement v12.0.0: Update to .NET 11
This release updates CommunityToolkit.Maui to .NET 11.
It also enables Runtime Async only on the net11.0-windows TFM. Runtime Async is not enabled on the Mono Runtime and is not recommended for any NuGet library that may be consumed by an app using the Mono Runtime.
We have removed code supporting the Tizen TFM as Tizen was no longer supported in .NET MAUI starting with .NET 10.
Breaking Changes
The update to .NET 11 required us to modify some APIs and their underlying behavior.
All packages
-
API
- Minimum OS versions in the API. The
AppBuilderExtensionsclasses declare[SupportedOSPlatform]iOS 15.0, Mac Catalyst 17.0 and Android 24.0 (MediaElement: Android 26.0), the .NET MAUI 11 minimums. Attributes that only restated a version below these minimums are removed or made versionless; this only relaxes the analyzer. Feature-specific changes are in the CameraView, FileSaver and FolderPicker, MediaElement, NavigationBar (Android), SemanticOrderView, and StatusBar and StatusBarBehavior sections. - No Tizen API surface. The Tizen
[SupportedOSPlatform]and[UnsupportedOSPlatform]attributes and the Tizen code paths are removed.
Setup
- .NET 11 only. The libraries target
net11.0and its platforms - Tizen is no longer supported. The packages already shipped no Tizen target; .NET MAUI 11 dropped Tizen.
- Dependencies: the libraries reference .NET MAUI 11 (
Microsoft.Maui.Controls11.0.0)
Smaller changes
- Windows: the async methods of the
net11.0-windowsassemblies are runtime async. No API or functional change: the compiler no longer generates async state machines for these methods (exceptasync voidones), and the runtime handles their suspension instead.
- Minimum OS versions in the API. The
What's Changed
- Update to .NET 11 by @VladislavAntonyuk in #3331
Housekeeping
- Bump actions/setup-java from 6.1.0 to 6.2.0 by @dependabot[bot] in #3376
- [housekeeping] Automated PR to fix formatting errors by @github-actions[bot] in #3386
- Bump actions/setup-dotnet from 6.0.0 to 6.1.0 by @dependabot[bot] in #3377
- Bump the dotnet-tools group with 3 updates by @dependabot[bot] in #3379
- Bump Microsoft.Extensions.Logging.Console from 10.0.11 to 10.0.14 by @dependabot[bot] in #3382
- Bump PolySharp from 1.16.0 to 1.17.0 by @dependabot[bot] in #3389
- Bump xunit.v3 from 4.0.2 to 4.0.3 by @dependabot[bot] in #3390
Full Changelog: 16.0.0...17.0.0
Camera v8.0.0: Update to .NET 11
This release updates CommunityToolkit.Maui.Camera to .NET 11.
It also enables Runtime Async only on the net11.0-windows TFM. Runtime Async is not enabled on the Mono Runtime and is not recommended for any NuGet library that may be consumed by an app using the Mono Runtime.
We have removed code supporting the Tizen TFM as Tizen was no longer supported in .NET MAUI starting with .NET 10.
Breaking Changes
The update to .NET 11 required us to modify some APIs and their underlying behavior. Please find the features you use, below, and update your apps accordingly.
All packages
-
API
- Minimum OS versions in the API. The
AppBuilderExtensionsclasses declare[SupportedOSPlatform]iOS 15.0, Mac Catalyst 17.0 and Android 24.0 (MediaElement: Android 26.0), the .NET MAUI 11 minimums. Attributes that only restated a version below these minimums are removed or made versionless; this only relaxes the analyzer. Feature-specific changes are in the CameraView, FileSaver and FolderPicker, MediaElement, NavigationBar (Android), SemanticOrderView, and StatusBar and StatusBarBehavior sections. - No Tizen API surface. The Tizen
[SupportedOSPlatform]and[UnsupportedOSPlatform]attributes and the Tizen code paths are removed.
Setup
- .NET 11 only. The libraries target
net11.0and its platforms. The minimum OS versions align with .NET MAUI 11's: iOS 15.0, Mac Catalyst 17.0 (macOS 14), Android 7.0 (API 24), Windows 10 1809 (10.0.17763) - Tizen is no longer supported. The packages already shipped no Tizen target; .NET MAUI 11 dropped Tizen.
Smaller changes
- Windows: the async methods of the
net11.0-windowsassemblies are runtime async. No API or functional change: the compiler no longer generates async state machines for these methods (exceptasync voidones), and the runtime handles their suspension instead.
- Minimum OS versions in the API. The
CameraView
-
API
- CommunityToolkit.Maui.Camera declares
[SupportedOSPlatform]Windows 10.0.17763 (was 10.0.10240), like the other libraries.
- CommunityToolkit.Maui.Camera declares
What's Changed
- Update to .NET 11 by @VladislavAntonyuk in #3331
Full Changelog: 16.0.0...17.0.0
v16.0.0 Bug Fix-A-Palooza
v16.0.0 Bug Fix-A-Palooza 🎉
We have FINALLY implemented Device Tests! These are platform-specific unit tests that run on iOS, Android, MacCatalyst and Windows. This allows us to unit test all platform-specific code and has MASSIVELY increased our Unit Test Code Coverage:
- 90.8% Code Coverage on
CommunityToolkit.Maui - 96.7% Code Coverage on
CommunityToolkit.Maui.Camera - 95% Code Coverage on
CommunityToolkit.Maui.Core - 91.8% Code Coverage on
CommunityToolkti.Maui.MediaElement
And thanks to the new Device Tests (along with excellent contributions from the community), this Release contains fixes for a whopping 58 Issues. 💪
Breaking Changes
To fix certain bugs, and re-align features to ensure they behave the same across all platforms, we did have to modify some APIs and the associated underlying behavior. Please find the features you use, below, and update your apps accordingly.
All packages
- API: Null arguments throw
ArgumentNullExceptionat the call. Public and protected members of the five libraries now guard the non-nullable reference parameters they cannot handle (about 275 guards).- A null that used to cause a
NullReferenceExceptionlater (or was stored silently) fails at the call, with aParamName. What to do: fix the caller. - An async member throws from the call itself, before it returns a Task.
- Null arguments that a member handled before are still accepted, for example an
IProgress<double>or aPaintbackground of null. - Feature-specific effects are listed in each feature's section.
BasePlatformBehaviorguards onlybindable. A null platform view passes through, because the AndroidIconTintColorBehavioraccepts it.
- A null that used to cause a
- Setup: CommunityToolkit.Maui.Core on Android adds a
<queries>entry for the launcher (MAIN/HOME) to the app's merged manifest through the package's library manifest (src/CommunityToolkit.Maui.Core/AndroidManifest.xml). Badge needs it on Android 11 and later. If your app or Play listing reviews<queries>, check the merged manifest. - Setup: Dependencies: on Windows, CommunityToolkit.Maui.Core references
System.Speech10.0.11 (it was 10.0.1). No action is needed unless you pin the package. This comes from #3288 on main, not from this PR.
New APIs In This Release
Popupnow declaresIPaddingElement, which it already inherited fromContentViewGravatarImageSourcedeclaresIStreamImageSource, which it already inherited fromStreamImageSource, and overridesCancel()(see GravatarImageSource, after that ApiCompat run);[SupportedOSPlatform("android23.0")]on the AndroidStatusBarBehavior(see StatusBar and StatusBarBehavior).DefaultPopupSettings.BackgroundColorDarkandOnInitializing(#3345)NumericValidationBehavior.Interval(#3329)
AvatarView
-
Behavior
- AvatarView.
HorizontalOptions,VerticalOptions,HeightRequest,WidthRequest,Padding,Stroke,StrokeThicknessandStrokeShapeare no longer local values, so an implicit AvatarView Style applies (and aBorderStyle withApplyToDerivedTypes).- An empty image source shows
Texton every platform; iOS, MacCatalyst and Windows had previously showed an empty circle. SetTexttostring.Emptyor""to display a blank circle. - The text replaces a failed or empty image only once the image has been laid out (about one layout pass later), because a
GravatarImageSourceasks for its picture only after its image has a size. So:- An AvatarView whose Gravatar failed to load while the page opened offline shows the picture again when the
Emailchanges or a new load succeeds. - Such an AvatarView may show an empty circle for that one layout pass before the text.
- An AvatarView whose Gravatar failed to load while the page opened offline shows the picture again when the
- AvatarView.
Badge
-
Setup
- CommunityToolkit.Maui.Core adds a
<queries>entry for the launcher (MAIN/HOME) to Android apps; Badge needs it on Android 11 and later (see All packages).
Behavior
- Badge on Windows without package identity. In an unpackaged app,
Badge.SetCountwrites one trace line and returns, instead of throwing aCOMExceptionthat ended the app. No badge appears, so package the app if you need the taskbar badge.
- CommunityToolkit.Maui.Core adds a
Camera
- See Camera v7.0.0: https://github.com/CommunityToolkit/Maui/releases#release-7.0.0-camera
ColorAnimationExtensions
-
Behavior
BackgroundColorToandTextColorTowith arateof 0 throwArgumentOutOfRangeExceptionfrom the call. Before, the error came later on the animation ticker and ended the app. Pass a rate above 0.
DialogFragment (Android)
-
Behavior
- Android modal pages and the status bar.
DialogFragmentServicelays the dialog of a modal page out like the activity's window, for every status bar color.- On Android 11 and newer, a modal page receives the status bar inset. It must keep clear of the status bar itself, as a page in the activity's window does.
- On Android 10 and older, a modal page also receives window insets with a transparent status bar color, where it received none.
- Android modal pages and the status bar.
DrawingView
-
Behavior
- DrawingView.
- On iOS and Mac Catalyst,
GetImageStreamwith no lines returnsStream.Nullinstead of throwingInvalidOperationException, and a NaN image size, or one that is infinite on both sides, throwsArgumentException. HandleStream.Nullwhere you caught the exception. - An image scaled to
ImageOptions.DesiredSizehas its pixel size rounded half away from zero on Android, iOS and Mac Catalyst, as Windows already did. A 1920 x 1080 target of a 411 DIP canvas gives 1920 x 934 on Android, where it gave 1919 x 934. - On Windows a line captures the pointer, so a line released outside the view completes with
DrawingLineCompleted, a lost capture raisesDrawingLineCancelled, and a second pointer no longer starts or changes a line. No action is needed unless you worked around the old behavior.
- On iOS and Mac Catalyst,
Smaller changes
- An unloaded view keeps its handler and listens again when it is loaded.
DrawActiondraws in a canvas state of its own.
- DrawingView.
Expander
-
Setup
- Windows, iOS and Mac Catalyst:
UseMauiCommunityToolkitregisters the Expander layout handler (see Behavior below), so keep calling it at startup. That handler keeps its own platform view even when the app setsLayoutHandler.PlatformViewFactory.
Behavior
- Expander accessibility.
- On Windows the Expander is a Tab stop that Enter and Space toggle. UI Automation exposes it as a Button with the ExpandCollapse and Invoke patterns.
- On Android, iOS and Mac Catalyst the header is one element for TalkBack and VoiceOver, with expand and collapse actions.
- The Expander's internal layout now resolves to an internal
ExpanderLayoutHandler, so a handler an app registers forGridno longer applies to the Expander's internal Grid;LayoutHandler.Mapperchanges still apply. - On Windows, iOS and Mac Catalyst, an app's
LayoutHandler.PlatformViewFactoryno longer creates the platform view of that layout, so the layout keeps the platform view that gives the header this support. The factory still creates the platform views of the app's other layouts, including the ones in the Expander'sHeaderandContent, and on Android also the platform view of that layout.
Smaller changes
- Expander
Directioncan be changed again by bindings and Styles.
- Windows, iOS and Mac Catalyst:
FileSaver and FolderPicker
-
API
- Null arguments throw
ArgumentNullExceptionat the call;FileSaverandFolderPickerstill return the exception in the result. (see All packages)
Behavior
- FileSaver and FolderPicker.
progressreports percentages from 0 to 100. It reported fractions from 0 to 1 during the copy, then a final 100, so remove any* 100you applied.- A stream that cannot seek no longer fails the save; it gets only the final report.
- On Android, a document whose provider gives no file path, such as a cloud document, is a successful save whose
FilePathis itscontent://URI. It used to fail withFileSaveException. ...
- Null arguments throw
MediaElement v11.0.0 Bug Fix-A-Palooza
MediaElement v11.0.0 Bug Fix-A-Palooza 🎉
We have FINALLY implemented Device Tests! These are platform-specific unit tests that run on iOS, Android, MacCatalyst and Windows. This allows us to unit test all platform-specific code and has MASSIVELY increased our Unit Test Code Coverage to 91.8% Code Coverage on CommunityToolkti.Maui.MediaElement.
Breaking Changes
To fix certain bugs, and re-align features to ensure they behave the same across all platforms, we did have to modify some APIs and the associated underlying behavior. Please find the features you use, below, and update your apps accordingly.
All packages
- API: Null arguments throw
ArgumentNullExceptionat the call. Public and protected members of the five libraries now guard the non-nullable reference parameters they cannot handle (about 275 guards).- A null that used to cause a
NullReferenceExceptionlater (or was stored silently) fails at the call, with aParamName. What to do: fix the caller. - An async member throws from the call itself, before it returns a Task.
- Null arguments that a member handled before are still accepted, for example an
IProgress<double>or aPaintbackground of null. - Feature-specific effects are listed in each feature's section.
BasePlatformBehaviorguards onlybindable. A null platform view passes through, because the AndroidIconTintColorBehavioraccepts it.
- A null that used to cause a
- Setup: CommunityToolkit.Maui.Core on Android adds a
<queries>entry for the launcher (MAIN/HOME) to the app's merged manifest through the package's library manifest (src/CommunityToolkit.Maui.Core/AndroidManifest.xml). Badge needs it on Android 11 and later. If your app or Play listing reviews<queries>, check the merged manifest. - Setup: Dependencies: on Windows, CommunityToolkit.Maui.Core references
System.Speech10.0.11 (it was 10.0.1). No action is needed unless you pin the package. This comes from #3288 on main, not from this PR.
New APIs In This Release
Popupnow declaresIPaddingElement, which it already inherited fromContentViewGravatarImageSourcedeclaresIStreamImageSource, which it already inherited fromStreamImageSource, and overridesCancel()(see GravatarImageSource, after that ApiCompat run);[SupportedOSPlatform("android23.0")]on the AndroidStatusBarBehavior(see StatusBar and StatusBarBehavior).DefaultPopupSettings.BackgroundColorDarkandOnInitializing(#3345)NumericValidationBehavior.Interval(#3329)
MediaElement
-
API
- Null arguments:
FileMediaSourceConverter.ConvertFrom(null)throwsArgumentNullException. - Null arguments:
MediaFailedEventArgsrejects null for its non-nullable members.
Behavior
- An exception thrown by an event handler while
Sourcechanges is reported throughMediaFailed.- Before, an exception from a
StateChanged,PropertyChangedorPropertyChanginghandler reached the code that setSource, or ended the app when MAUI set it from XAML or a binding. - Now it is logged and the change goes on. The first exception is reported once through
MediaFailed:ErrorMessagenames its type and message, andCurrentStateis not set to Failed. - What to do: handle
MediaFailed, and checkErrorMessagebefore treating everyMediaFailedas a failed source.
- Before, an exception from a
- MediaElement playback.
SeekToclamps a position outside the media to its start or end and raisesSeekCompleted. On iOS such a seek never completed.SeekTofails with the platform's exception, for exampleInvalidOperationExceptionbefore the player is ready, where that exception ended the app.Play()at the end of the media starts it again on iOS and Mac Catalyst, as on Android.- On Android,
CurrentStatereportsBufferingwhile buffering (it wasPaused) andStoppedat the end of the media. - A source without data empties the player and reports
None. - What to do: check code that relied on the old states.
- A disconnected handler stops the position timer. The MediaElement no longer keeps its page alive after the page is left. No action is needed.
- Why: the dispatcher timer stops when the handler disconnects, and starts again when a handler connects later.
- Found on iOS: a probe left the Sample's
MediaElementPagealive 3 of 3 times after it was left (0 of 3 with the fix). The same leak is fixed and tested on Android, Mac Catalyst and Windows. - On Windows,
MediaOpenedarrives on the player's worker thread. An open that was still running when the handler disconnected no longer starts the timer again: the timer starts on the UI thread, and only while a handler is attached. - A second leak was in the Sample:
MediaElementFromStreamPagewasIAsyncDisposable, so the window's service scope kept every page that was opened.- iOS: a probe left the page alive 3 of 3 times before the change, 0 of 3 after.
- Windows (the Sample at 4a8d407, 5 visits, a GC dump after the 5th Back): 0 MediaElementFromStreamPage, MediaElement or StreamMediaSource stay alive, GC heap 6.5 MB. With the Sample change reverted: 5 of each, 167.7 MB.
- Also fixed:
FileMediaSourceConverter.ConvertFromhad an inverted condition. A real path threwInvalidOperationException, and an empty or white-space string returned a source. Now a real path returns theFileMediaSource, and an empty or white-space string throwsInvalidOperationException, as documented.
- Null arguments:
What's Changed
- Add Device Tests, Apply Fixes for Bugs Found by @TheCodeTraveler in #3344
- Apply MediaElement.Speed when playback starts on iOS and fix inverted AreFloatingPointNumbersEqual by @ne0rrmatrix in #3327
- Fix iOS MediaElement support for multiple ItemsViews and windows by @ne0rrmatrix in #3222
- Fix ios media element start bug by @ne0rrmatrix in #3281
Camera v7.0.0 Bug Fix-A-Palooza 🎉
We have FINALLY implemented Device Tests! These are platform-specific unit tests that run on iOS, Android, MacCatalyst and Windows. This allows us to unit test all platform-specific code and has MASSIVELY increased our Unit Test Code Coverage to 96.7% Code Coverage on CommunityToolkit.Maui.Camera.
New APIs in This Release
CameraView.ErrorOccurredandErrorOccurredEventArgs(#3299)
Breaking Changes
To fix certain bugs, and re-align features to ensure they behave the same across all platforms, we did have to modify some APIs and the associated underlying behavior. Please find the features you use, below, and update your apps accordingly.
All packages
- API: Null arguments throw
ArgumentNullExceptionat the call. Public and protected members of the five libraries now guard the non-nullable reference parameters they cannot handle (about 275 guards).- A null that used to cause a
NullReferenceExceptionlater (or was stored silently) fails at the call, with aParamName. What to do: fix the caller. - An async member throws from the call itself, before it returns a Task.
- Null arguments that a member handled before are still accepted, for example an
IProgress<double>or aPaintbackground of null. - Feature-specific effects are listed in each feature's section.
BasePlatformBehaviorguards onlybindable. A null platform view passes through, because the AndroidIconTintColorBehavioraccepts it.
- A null that used to cause a
- Setup: CommunityToolkit.Maui.Core on Android adds a
<queries>entry for the launcher (MAIN/HOME) to the app's merged manifest through the package's library manifest (src/CommunityToolkit.Maui.Core/AndroidManifest.xml). Badge needs it on Android 11 and later. If your app or Play listing reviews<queries>, check the merged manifest. - Setup: Dependencies: on Windows, CommunityToolkit.Maui.Core references
System.Speech10.0.11 (it was 10.0.1). No action is needed unless you pin the package. This comes from #3288 on main, not from this PR.
CameraView
-
API
- Null arguments:
ErrorOccurredEventArgs,MediaCaptureFailedEventArgsandCameraInforeject null for their non-nullable members.
Behavior
- Failures are reported through events instead of exceptions.
StartCameraPreview(CancellationToken)no longer throws for a camera that cannot start (except in the Android failed-connection case below). It raisesErrorOccurredon every platform.- A cancelled token still throws
OperationCanceledException. - A view without a handler still throws
InvalidOperationException.
- A cancelled token still throws
- The commands let no exception escape:
CaptureImageCommand,StartVideoRecordingCommandandStopVideoRecordingCommandreport throughMediaCaptureFailed.StartCameraPreviewCommandandStopCameraPreviewCommandreport throughErrorOccurred.
- Failures of the handler's own work (connecting, switching to
SelectedCamera, applyingImageCaptureResolution) raiseErrorOccurredinstead of ending the app. - Android:
- A preview without the camera permission now fails, is reported, and stays stopped until the activity resumes with the permission. iOS and Mac Catalyst report a denied permission the same way.
CaptureImagebefore the camera has started throwsCameraExceptioninstead of waiting until its token is cancelled.
- What to do: subscribe to
ErrorOccurredandMediaCaptureFailedinstead of relying on try/catch.
- Android: one
ErrorOccurredfor a failed connection. AStartCameraPreviewcalled while theCameraViewconnects to its camera waits for the connection.- When the connection fails and raises
ErrorOccurred, thatStartCameraPreviewthrows the same failure to its caller instead of raisingErrorOccurredagain.StartCameraPreviewCommanddoesn't report it again. - What to do: catch the exception where you await such a start.
- When the connection fails and raises
StopCameraPreviewcancels starts that still wait.StopCameraPreviewandStopCameraPreviewCommandnow cancel a pendingStartCameraPreview, a pendingStartVideoRecording(both overloads), the start the view makes when it connects its camera, and a camera switch.- The cancelled start throws
OperationCanceledException, with noErrorOccurredorMediaCaptureFailed. A start that a stop interrupted needs a new start. - What to do: do not treat that exception as a failure.
- On iOS and Mac Catalyst,
StartCameraPreviewwith an already-cancelled token throws and no longer starts the session.
- The cancelled start throws
- Video recording.
- Android: a
StartVideoRecordingduring a recording replaces it: the new stream receives the video, and the earlier recording's video is discarded. Camera 6.1.0 ignored the second start; iOS and Mac Catalyst already replaced it. - Android, iOS, Mac Catalyst and Windows: a start that arrives while an earlier start still waits for the platform joins it. It returns once that recording has started, its stream receives no video, and it throws the earlier start's failure. On iOS and Mac Catalyst this holds for a double tap too, where Camera 6.1.0 replaced the first recording.
StartVideoRecordingreturns only once the platform has started the recording (#3311), soawaitit before relying on the recording. On iOS and Mac Catalyst, a start cancelled while it waits releases the recording state.- Windows, as on Android, iOS and Mac Catalyst:
StopVideoRecordingwaits for a pendingStartVideoRecording.- A
StartVideoRecordingor a secondStopVideoRecordingthat arrives while a stop waits for Media Foundation to finish the recording waits for that stop.
StopVideoRecordingthrowsCameraExceptionon Android, iOS and Mac Catalyst when the platform reports a recording with no playable video. A recording the platform ended early that has usable video is still returned.- Android: when the photo session cannot be restored after a successful export,
StopVideoRecordingstill returns the video, and the failure is raised throughErrorOccurred. Selecting another camera during a recording waits until the recording stops or is replaced. - Windows: a
StopVideoRecordingwhose token is cancelled already or while the stop finishes the video:- It still stops the recording and throws
OperationCanceledException, as on Android, iOS and Mac Catalyst. It used to ignore the token and return the video. - The next
StopVideoRecordingreturns the video. AStartVideoRecordingthat comes first discards it and puts its stream back, as for a replaced recording. - The camera that the recording turned on is off again when the cancelled stop throws.
- A cancelled stop while a start or another stop is still pending throws without stopping anything.
- With no recording, a cancelled
StopVideoRecordingreturnsStream.Nullon every platform. StopVideoRecordingCommandends without an event.- Camera 6.1.0 already handled a cancelled stop this way on Android and iOS; Mac Catalyst follows iOS.
- Catch the
OperationCanceledExceptionand callStopVideoRecordingagain to get the video.
- It still stops the recording and throws
- Windows: a
StartVideoRecordingduring a recording ends and finishes the running recording and discards its video.- The running recording's stream goes back to the length and position it had when that recording started.
- The video goes to the stream of the latest start, as on Android, iOS and Mac Catalyst. The camera stays on in between.
- Camera 6.1.0 prepared a second recording without ending the first, so the first video was left unfinished or the new stream stayed empty.
- If you relied on the first recording continuing, call
StopVideoRecordingbefore a new start.
- What to do: handle
ErrorOccurredandCameraException. On Android, don't rely on a second start being ignored.
- Android: a
- Recording while the preview is stopped starts the camera.
- On Android, iOS, Mac Catalyst and Windows,
StartVideoRecordingafterStopCameraPreview, or beforeStartCameraPreview, starts the camera and then the recording. Android already did; Camera 6.1.0 recorded nothing on iOS, Mac Catalyst and Windows. - A camera that the recording turned on turns off again when the recording ends. After a cancelled
StopVideoRecordingon Android, iOS and Mac Catalyst, it turns off only once the next stop returns the video. - A preview that the app started stays on.
- When the camera can't start, a stopped preview stays stopped. On iOS, Mac Catalyst and Windows,
StartVideoRecordingthrows the failure: for example aCameraExceptionwithout a camera or without the camera permission, or on Windows anUnauthorizedAccessExceptionwhen the privacy settings block the camera.StartVideoRecordingCommandreports it throughMediaCaptureFailed. - On Android, a
StartCameraPreviewafterSetExtensionModeon a stopped previe...
- On Android, iOS, Mac Catalyst and Windows,
- Null arguments:
Maps v5.0.0 - Our Final Maps Release
CommunityToolkit.Maui.Maps v5.0.0 - Our Final Maps Release
The good news is that you no longer need us! In .NET 10, MAUI added Windows support to .NET MAUI's own Map control, meaning CommunityToolkit.Maui.Maps is no longer needed.
We recommend moving to .NET MAUI's official Microsoft.Maui.Controls.Maps package.
What changes in this release
UseMauiCommunityToolkitMaps, itsAppBuilderExtensionsclass and the Windows handlerMapHandlerWindowsare marked[Obsolete].- The
CommunityToolkit.Maui.Mapscode will be removed from our repo when we merge our .NET 11 PR (#3331)
How to migrate
- Remove the
CommunityToolkit.Maui.Mapspackage, itsusing CommunityToolkit.Maui.Maps;directives and theUseMauiCommunityToolkitMaps()call. - Add the
Microsoft.Maui.Controls.Mapspackage. The toolkit package used to reference it for you. - Call
builder.UseMauiMaps()inMauiProgram.cson every platform. - On Windows, also add an Azure Maps key:
builder.ConfigureEssentials(essentials => essentials.UseMapServiceToken("YOUR_AZURE_MAPS_SUBSCRIPTION_KEY")). Without a valid key the Windows map shows no map data. See Manage authentication in Azure Maps to get one.
What to expect on Windows
.NET MAUI's Windows map is the WinUI 3 MapControl backed by Azure Maps.
- Supported:
MoveToRegion, theStreet,SatelliteandHybridmap types, traffic, scrolling, zooming and pins. - Not supported yet:
IsShowingUser, polygons, polylines and circles inMapElements, pin labels and info windows, andMapClicked.
Learn more
- .NET MAUI Map documentation
- Deprecation discussion: CommunityToolkit/Maui#3190
- CommunityToolkit.Maui Map documentation
What's Changed
- Add Device Tests, Apply Fixes for Bugs Found by @TheCodeTraveler in #3344
v15.0.1 Fix WindowsAppSDK Compatibility, Remove Remaining .NET MAUI Internal API Usage
v15.0.1 Fix Crashes on Windows
This release removes the WindowsAppSDK v2.2.0 dependency that was causing apps to crash on Windows. Long story short, .NET 10 MAUI currently expects Windows App SDK 1.8.x, while .NET 11 expects 2.3.1.
We also found a few more internal .NET MAUI APIs that we missed in the CommunityToolkti.Maui v15.0.0 Release used by FileSaver, FolderPicker, Snackbar, Toast, Expander and TouchBehavior that we have now removed. In .NET 11. CommunityToolkit.Maui will no longer have access to internal .NET MAUI APIs. We have updated our .NET 11 Migration guidance to use CommunityToolkit.Maui v15.0.1 or later to ensure compatibility with .NET 11. Specifically,
Important
We recommend every .NET MAUI app preparing for .NET 11 install this release, v15.0.1 (or later), before .NET 11 is released in November. Apps running CommunityToolkit.Maui v14.2.2 and earlier will not be compatible with .NET 11.
What's Changed
- Align Windows App SDK version with .NET MAUI by @jfversluis in #3282
- Remove all usage of .NET MAUI internal APIs by @jfversluis in #3273
Housekeeping
- [housekeeping] Automated PR to fix formatting errors by @github-actions[bot] in #3286
- Bump Microsoft.Testing.Extensions.CodeCoverage from 18.9.0 to 18.10.0 by @dependabot[bot] in #3285
- Bump actions/checkout from 7.0.0 to 7.0.1 by @dependabot[bot] in #3275
- Bump Microsoft.Testing.Extensions.CodeCoverage from 18.8.0 to 18.9.0 by @dependabot[bot] in #3262
- Bump actions/setup-java from 5.6.0 to 5.7.0 by @dependabot[bot] in #3278
Full Changelog: 15.0.0...15.0.1
v15.0.0 Prevent Breaking Changes in .NET 11
.NET 11 Compatibility
This release provides compatibility with the upcoming release of .NET 11.
In .NET 11, CommunityToolkit.Maui will no longer have access to internal .NET MAUI APIs. This release removes our use of internal .NET MAUI APIs to ensure compatibility with .NET 11.
Important
We recommend every .NET MAUI app preparing for .NET 11 install v15.0.1 (or later), before .NET 11 is released in November. Apps running CommunityToolkit.Maui v14.2.2 and earlier will not be compatible with .NET 11.
What's Changed
- Remove MAUI internal API usage by @jfversluis in #3251
- Hardcode NuGet trusted publishing user by @jfversluis in #3266
Housekeeping
- Bump actions/setup-dotnet from 5.4.0 to 6.0.0 by @dependabot[bot] in #3268
- Bump actions/setup-java from 5.5.0 to 5.6.0 by @dependabot[bot] in #3267
Full Changelog: 14.2.2...14.2.3
14.2.2: Prevent Popup Race Conditions, (Windows) Folder Picker Initial Path
Note: 14.2.2 supersedes 14.2.1, which was not published to NuGet.org due to an expired publishing credential.
Just a couple bug fixes in this one!
- Prevent Race Conditions when closing a Popup
- Set initial folder for FilePicker and FolderPicker on Windows
What's Changed
- Prevent Race Condition Allowing Simultaneous Calling of
Navigation.PushModalAsync()/Shell.GotoAsync()inPopupExtensionsby @TheCodeTraveler in #3234 - Add
SemaphoreSlimSupport forPopupCloseAsyncto Avoid Race Conditions by @TheCodeTraveler in #3235 - Set Windows Folder Picker Initial Path by @TheCodeTraveler in #3078
Housekeeping
- Bump actions/checkout from 6.0.2 to 6.0.3 by @dependabot[bot] in #3236
- Bump Microsoft.Testing.Extensions.CodeCoverage from 18.7.0 to 18.8.0 by @dependabot[bot] in #3237
- Bump System.Formats.Asn1 from 10.0.8 to 10.0.9 by @dependabot[bot] in #3238
- Bump actions/checkout from 6.0.3 to 7.0.0 by @dependabot[bot] in #3245
- Bump actions/setup-java from 5.2.0 to 5.3.0 by @dependabot[bot] in #3246
- Bump actions/setup-java from 5.3.0 to 5.4.0 by @dependabot[bot] in #3256
- Bump actions/setup-dotnet from 5.3.0 to 5.4.0 by @dependabot[bot] in #3257
- Bump actions/setup-java from 5.4.0 to 5.5.0 by @dependabot[bot] in #3264
- Use trusted publishing for NuGet release by @jfversluis in #3261
Full Changelog: 14.2.0...14.2.2