Repository navigation
·
5 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
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. Open such a path with the ContentResolver. - A null
fileNameorstream(and a nullinitialPathfor FolderPicker) comes back as anArgumentNullExceptionin the result, without showing the picker.
- Null arguments throw
GravatarImageSource
-
Behavior
- GravatarImageSource.
- The email is trimmed and lower-cased before hashing, as Gravatar requires, so mixed-case addresses now load their real image.
- The download is fully read into a seekable stream, so on Windows the picture shows again.
HttpClient.Timeoutlimits the whole download, and a body that fails halfway givesStream.Null. - One load no longer cancels another.
- A load that you start with
CancellationToken.Nonenever throws. Only a token that you pass and cancel makesGetStreamAsyncand the defaultStreamfunction throwOperationCanceledException, instead of returningStream.Null. .NET MAUI catches it for the loads that it cancels itself, so a view keeps the picture of the load that replaced it. Cancel()ends only the loads started without a cancelable token, which then returnStream.Null. Its task always completes withtrue.- What to do: catch the exception where you call
StreamorGetStreamAsyncwith your own token.
- GravatarImageSource in a Button.
- The picture is requested at the smaller of the
WidthRequestandHeightRequestthat the Button sets, or at Gravatar's default 80 pixels, and again when those requests change. It was requested at the Button's laid-out size, so on iOS and Mac Catalyst each picture made the Button larger until it was as wide as the screen (older than this PR). Image,ImageButtonandAvatarViewstill request the size they are laid out at.- A
Buttonwithout size requests now gets an 80-pixel picture instead of one the size of the laid-out Button: on a 420 dpi Android screen, a 30 dp icon instead of 15 dp. SetHeightRequeston the Button for a smaller picture. - Windows: the picture is drawn whole, at most at its natural size, and scaled down to the room the Button has for it. The Button no longer grows for it.
- Before this change, the picture loaded on Windows only with this PR's download fix (see the GravatarImageSource change above). It was then stretched to the Button's width, and the Button clipped it to a thin band.
- A Button whose image is above or below its text (
ContentLayoutTop or Bottom) needs aHeightRequestthat leaves room for the picture. - A Button without
Textneeds aHeightRequestorMinimumHeightRequest. The .NET MAUI app template's Button style setsMinimumHeightRequestto 44. - This works around a .NET MAUI behavior: on Windows, MAUI limits a Button's picture to its natural size only when it sees the BitmapImage's
ImageOpenedevent, which a picture decoded from a stream has already raised.
- The picture is requested at the smaller of the
- GravatarImageSource.
KeyboardExtensions
-
Smaller changes
- KeyboardExtensions on iOS and Windows call the platform on the UI thread.
IsSoftKeyboardShowingcalled from another thread blocks until the UI thread answers. The tasks ofHideKeyboardAsyncandShowKeyboardAsynccomplete once the UI thread has done the work.
- KeyboardExtensions on iOS and Windows call the platform on the UI thread.
Maps
- See Maps v5.0.0: https://github.com/CommunityToolkit/Maui/releases#release-5.0.0-mapsMaxLengthReachedBehavior
-
API
- Null arguments:
MaxLengthReachedEventArgsrejects null for its non-nullable members.
Behavior
- Keyboard dismissal.
MaxLengthReachedBehaviorhides the keyboard only while its own InputView has the focus, and through the view's own window. So Android no longer hides the keyboard of the view the user moved to, and the keyboard goes away in a modal page or a Popup too. No action is needed.
- Null arguments:
MediaElement
- See MediaElement v11.0.0: https://github.com/CommunityToolkit/Maui/releases#release-11.0.0-mediaelement
NavigationBar (Android)
-
Behavior
- NavigationBar (Android). The default
Coloris still transparent, but it is now a plain default value, so reading the color no longer makesIsSettrue. As a result:- A page that never set a color no longer gets one applied.
- Clearing
ColororStylegives the window back its original color. - From Android 15 the color is drawn as a view over the navigation bar.
- What to do: check pages that relied on the old default.
- NavigationBar (Android). The default
Popup
-
API
- Null arguments:
Options.SetPopupDefaults(null)andSetPopupOptionsDefaults(null)no longer store null. - Null arguments: The
async voidPopupExtensions.ShowPopupoverloads throw to the caller instead of posting the exception to theSynchronizationContext.
Behavior
BackgroundColoris null by default, and Styles now apply.Margin,Padding,HorizontalOptions,VerticalOptions,CanBeDismissedByTappingOutsideOfPopupandBackgroundColorare now default values. 15.0.1 set them as local values in the constructor.- A Style can set them, and
Popup.BackgroundColorreads null until something sets it. - A popup without a background shows
DefaultPopupSettings.BackgroundColor, or in the dark themeBackgroundColorDark: black with #3345 in this release, where 15.0.1 showed white. - What to do: set
BackgroundColorwhere a fixed color is needed, and check popups in the dark theme.
- A Style can set them, and
- Navigation that removes a popup page ends
ShowPopupAsync. When navigation removes the popup page withoutCloseAsync,ShowPopupAsynccompletes andClosedis raised exactly once. Before, neither happened, and code that awaited it stayed suspended.- Such navigation: Shell switching to another Shell element,
PopModalAsyncorPopAsynccalled by other code,Window.Pagebeing replaced, or Shell popping the popup out of a modalNavigationPage. - Both happen one dispatcher cycle after .NET MAUI has removed the popup page, so a
Closedhandler can show another popup. - The result is the existing "closed without a result" shape:
WasDismissedByTappingOutsideOfPopupis true. It now means "closed without a result: by tapping outside the popup, or because navigation removed it"; it is false only afterCloseAsync.- For
ShowPopupAsync<TResult>,Resultis null for a reference or nullable type. Reading it for a value type such asintthrowsPopupResultException, as after a tap outside.
- What to do: check
WasDismissedByTappingOutsideOfPopupfirst. Subscribe toClosedif you must tell a tap from a navigation removal. - If navigation removes the page before .NET MAUI reports that it was navigated to,
Closedis raised without a precedingOpened. - A
CancellationTokenused as a timeout keeps working. - With a Shell as the root page,
CloseAsyncandClosePopupAsyncof a popup shown on a modalNavigationPageclose only the popup.CloseAsyncused to pop the whole page and never complete, andClosePopupAsyncthrewPopupBlockedException. - A close that finds another page on top when it runs throws
PopupBlockedExceptionand pops nothing:CloseAsync,Popup.CloseAsyncandClosePopupAsync(also throughIPopupService) wait for earlier popup operations. When the close finally runs, they check again that the popup is still the page on top.- This applies when another page was pushed above the popup in the meantime, for example a popup that
ShowPopupAsyncwas showing, or a modal page your code pushed. They already threwPopupBlockedExceptionand popped nothing when that page was on top at the call. - Before, including in 15.0.1, they popped that other page and then never completed, so no popup in the app could open or close again. In some layouts they reported the popup closed while it stayed on screen.
ClosePopupAsyncstill targets the popup that was the most recent when you called it, not the newer one. Call it again to close the newer one.- A tap outside the popup or the Android Back button does nothing in this case. It no longer crashes the app if that other page is already on top when the tap runs.
- A tap outside the popup, or the Android Back button:
- no longer crashes the app (through
async void) when an earlier tap, Back or navigation has already closed the popup; - ignores a pop that .NET MAUI canceled, where it crashed the app (on iOS and Mac Catalyst a
NavigationPagecancels aPopAsyncthat waited behind a navigation that failed). The popup stays open, and a later tap closes it.
- no longer crashes the app (through
- Such navigation: Shell switching to another Shell element,
ShowPopupAsync,CloseAsyncandClosePopupAsyncthrowOperationCanceledExceptionwhen the app cancels the navigation.- When the app cancels the navigation that removes a popup (a
Window.ModalPoppingorApplication.ModalPoppinghandler that setse.Cancel, or aShell.Navigatinghandler that cancels),Popup.CloseAsync,Popup<T>.CloseAsync,ClosePopupAsyncandIPopupService.ClosePopupAsyncthrowOperationCanceledException. The popup stays open and usable,Closedis not raised, and the navigation lock is released. - When a
Shell.Navigatinghandler cancels the navigation that shows a popup (ShowPopupAsyncof a Shell, or of a page orINavigationunder a Shell root), everyShowPopupAsyncoverload, also throughIPopupService, throwsOperationCanceledExceptionand nothing is shown. - Before, these calls never completed. A close that the app canceled also held the navigation lock, so no popup in the app could open or close again, and the tap outside the popup stopped working.
ShowPopupand the tap outside or Android Back show nothing, or do nothing, and throw nothing.- To tell this from your own token, catch
OperationCanceledException when (!token.IsCancellationRequested). - A .NET MAUI limitation that this PR does not change: in a Shell whose current tab has a page pushed below the popup, a
ModalPoppinghandler that cancels makes .NET MAUI retry the pop in a loop, soCloseAsynccannot return. Cancel inShell.Navigatingthere instead.
- When the app cancels the navigation that removes a popup (a
Smaller changes
- A popup shown from
OnDisappearingof a modal page that is closing appears on the page below. - A
WidthRequestorHeightRequestlarger than the window is limited to the window. Openedis raised once per show.PopupClosedandClosedare raised after the navigation lock is released, in the same order as before.
- Null arguments:
RatingView
-
Smaller changes
- RatingView redraws when
FillOptionchanges.
- RatingView redraws when
SelectAllTextBehavior
-
API
- Null arguments:
SelectAllTextBehavioron Windows throwsArgumentNullExceptioninstead ofInvalidOperationExceptionfor a null platform view (only a derived class can reach it).
- Null arguments:
SemanticOrderView
-
Behavior
- SemanticOrderView on Windows sets the Tab order. Check the Tab order of screens that use it.
- The views of
ViewOrderthat the container holds are listed first in its tab focus children, followed by the rest of its content. - A
TabIndexthat the app set is no longer overwritten. The exception: views ofViewOrderthat a control within the container (aScrollView, for example) holds, or that are outside the container, still get aTabIndexfrom the order. - It does not change Narrator's scan order, which follows the visual tree.
- The views of
Smaller changes
- An app's
ContentViewHandler.PlatformViewFactoryno longer creates the SemanticOrderView's platform view, soViewOrderapplies.- The factory still creates the platform views of the other content views and pages.
- To customize that view, override
CreatePlatformViewin a handler derived fromSemanticOrderViewHandler, and register it afterUseMauiCommunityToolkit.
- SemanticOrderView on Windows sets the Tab order. Check the Tab order of screens that use it.
Snackbar and Toast
-
Behavior
- Windows Toast and Snackbar remove only their own notification. Each removes its notification by Id. No action is needed unless the app relied on the old clear-all (below).
- Before, a
Toast.ShoworToast.Dismissafter an earlier toast, and aSnackbar.ShoworSnackbar.Dismisswhile a snackbar was shown, removed every notification of the app (AppNotificationManager.RemoveAllAsync). That included the other alert and the notifications the app shows itself, on screen and in the Action Center. - Since a
Showno longer clears the app's other notifications, a Toast or Snackbar shown while another notification banner of the app is on screen waits behind that banner, as Windows queues banners. Shownow returns once Windows lists the new notification. That takes up to 1 s longer when Windows lists nothing for the app, for example while its notifications are off. A Snackbar whoseDurationis zero or less does not wait.- Overlapping
ShowandDismisscalls now take effect in call order. A call whose token is cancelled before its turn removes nothing and throwsOperationCanceledException. - Do not block on a
ShoworDismissTask inside aShownorDismissedhandler:.Wait()and.Resultdeadlock there.
- Before, a
Smaller changes
- Snackbar on Windows:
- It is dismissed at the end of
Duration, raisesDismissedonce and runs its action on the UI thread. Showcan take up to 1 s longer while the app's notifications are off (see Behavior above).Showno longer throws for aDurationsuch asTimeSpan.MaxValueorTimeSpan.MinValue.
- It is dismissed at the end of
- Snackbar on Android: a
Durationbelow 1 ms shows it for 1 ms, andDismissedis raised once. - Toast on Windows is removed at the end of
Duration.
- Windows Toast and Snackbar remove only their own notification. Each removes its notification by Id. No action is needed unless the app relied on the old clear-all (below).
SpeechToText
-
Setup
- CommunityToolkit.Maui.Core references
System.Speech10.0.11 on Windows (see All packages).
Smaller changes
StartListenAsyncwith null options throwsArgumentNullExceptionfrom the call (see All packages: null arguments). With valid options, a canceled token still returns a canceled Task, so awaiting it throwsOperationCanceledException.- On Windows, and for a start from a background thread on iOS and Mac Catalyst, an interrupted
StartListenAsynccompletes without an exception and without listening, even if its token is canceled afterwards.- Here "interrupted" means
StopListenAsyncorDisposeAsync(on Windows, also a newerStartListenAsync) is called while the start waits for the platform.
- Here "interrupted" means
- CommunityToolkit.Maui.Core references
StateContainer
-
Behavior
- StateContainer. A
StateKeythat is not defined throwsStateContainerExceptionwith its own message and no inner exception. It used to throw the "assigned to multiple StateViews" message, so change any code that matches the message text.
- StateContainer. A
StatusBar and StatusBarBehavior
-
API
StatusBarBehaviorrequires Android 6.0 (API 23). The Android type is now[SupportedOSPlatform("android23.0")], likeStatusBaralready was.- C# code that uses it in a project with a lower minimum Android version (the .NET MAUI templates use 21) gets warning CA1416, which fails builds that treat warnings as errors.
- What to do: raise the minimum Android version to 23, or create the behavior inside
if (OperatingSystem.IsIOS() || OperatingSystem.IsAndroidVersionAtLeast(23)). NotIsAndroidVersionAtLeast(23)alone: it is false on iOS. - A
StatusBarBehaviordeclared in XAML gets no warning. - Nothing changes at run time: on Android 5.0 and 5.1 it did nothing before and still does nothing.
- CommunityToolkit.Maui's minimum Android version stays 5.0 (API 21), the same as .NET MAUI 10's.
Setup
- iOS: remove
UIViewControllerBasedStatusBarAppearancefrom Info.plist if you set it to false forStatusBar.SetStyle(see Behavior below). - Android:
StatusBarBehaviorneeds a minimum Android version of 23 or a guard (see API above). CommunityToolkit.Maui's minimum Android version stays 5.0 (API 21), the same as .NET MAUI 10's.
Behavior
- iOS, .NET 10:
StatusBar.SetStyleandStatusBarBehavior.SetStyleno longer needsUIViewControllerBasedStatusBarAppearanceset to false in Info.plist.- The first
LightContentorDarkContentreplacespreferredStatusBarStyleuntil the app ends, for every view controller that does not choose its own style (the system pickers included).Defaultgives each view controller its own style back. - With the key set to false, the style still applies in apps built with an iOS SDK before 27, but not with the iOS 27 SDK (Xcode 27): the app keeps its status bar style and the call writes a trace message. So remove the key from Info.plist.
SetStylecalled off the main thread throwsUIKitThreadAccessException, in Release builds too, so call it on the main thread.
- The first
Smaller changes
- On Android 15+, colors without alpha no longer paint the bars black. On iOS, the status bar color view follows rotation and lets touches through, and on iOS 26 it comes back after an iPhone turns back to portrait.
StringToListConverter
-
Smaller changes
- StringToListConverter splits at the entry of a one-entry
Separatorslist, as documented; before, it split atSeparator.
- StringToListConverter splits at the entry of a one-entry
TouchBehavior
-
Smaller changes
- Windows selects the tapped CollectionView item. On Android and Windows, a tap on a header, footer or empty view selects nothing.
- The state events are raised at once with the new value.
ShouldMakeChildrenInputTransparenttakes effect when it changes.- A NaN
DefaultOpacity,HoveredOpacityorPressedOpacitythrowsArgumentOutOfRangeException, where 15.0.1 accepted it. - On Windows, a release now ends every press, as on Android (iOS also cancels a touch for good once it has left the element). Whatever
CurrentHoverStatussays, a release over the element completes the tap (Command,TouchGestureCompleted), and a release outside it cancels.- Before, a Windows release completed only while the hover status was
Entered. So a release outside the element could complete, and one over it could leave the press running.
- Before, a Windows release completed only while the hover status was
UserStoppedTypingBehavior
-
API
- Null arguments: The
async voidoverrides ofUserStoppedTypingBehaviorthrow to the caller instead of posting the exception to theSynchronizationContext.
Behavior
- Keyboard dismissal.
UserStoppedTypingBehaviorhides the keyboard only while its own InputView has the focus, and through the view's own window. So Android no longer hides the keyboard of the view the user moved to, and the keyboard goes away in a modal page or a Popup too. No action is needed. UserStoppedTypingBehavior.StoppedTypingTimeThresholdrejects a negative value. A negative value is ignored and the previous value is kept (MAUI logs a warning). Before, it failed insideTask.Delay. Use 0 or more.
- Null arguments: The
Validation behaviors
-
API
- Null arguments: The
async voidoverrides ofValidationBehaviorthrow to the caller instead of posting the exception to theSynchronizationContext.
Smaller changes
- Validation behaviors validate again when a rule changes.
Errorsis set on the UI thread, andIsRunningis reset after a cancel.
- Null arguments: The
What's Changed
- Add Device Tests, Apply Fixes for Bugs Found by @TheCodeTraveler in #3344
- Handle missing Windows notification runtime module by @jfversluis in #3301
- Restore Windows notification registration compatibility by @jfversluis in #3303
- Fix iOS video recording delegate lifetime by @austinbhale in #3309
- Add video capture and image capture to Android manifest in sample app by @matt-goldman in
- Add interval validation to NumericValidationBehavior by @meyerdominik in #3329
#3330 - Fix AppThemeResource updates in trimmed Release builds by @jfversluis in #3334
- Clarify required Windows Toast notification configuration by @jfversluis in #3333
- Fix Android FileSaver null initialPath handling by @snydcol in #3340
- Fix UseCommunityToolkitInitializationAnalyzer code fix inserting UseMauiCommunityToolkit() after Build() by @alexh30486-ui in #3343
- Add
Popupsupport forAppTheme, IntroduceDefaultPopupSettings.OnInitializingby @stephenquan in #3345 - Fix: [BUG] StatusBarBehavior is causing Android layouts to go behind status bar and navigation bar buttons on launch #2351 by @Pastajello in #3189
- Add SoftInputKeyboardPopup and integrate keyboard handling for popups by @FabriBertani in #3117
- Await native video recording start acknowledgment by @austinbhale in #3311
- Fix: Popup unlabeled outer element using android talkback by @IeuanWalker in #3367
- [iOS] StatusBar: apply the color only to the app windows by @marcelomoresco in #3373
Housekeeping
- Update Unit Tests Packages by @dependabot[bot] in #3288
- [housekeeping] Automated PR to fix formatting errors by @github-actions[bot] in #3370
- [housekeeping] Automated PR to fix formatting errors by @github-actions[bot] in #3350
- Bump System.Security.Cryptography.Pkcs from 9.0.21 to 10.0.13 by @dependabot[bot] in #3352
- Bump actions/setup-java from 6.0.1 to 6.1.0 by @dependabot[bot] in #3357
- Bump System.Security.Cryptography.Pkcs from 10.0.13 to 10.0.14 by @dependabot[bot] in #3358
- Bump Microsoft.Testing.Extensions.TrxReport from 2.5.1 to 2.5.2 by @dependabot[bot] in #3362
- Bump Microsoft.Testing.Extensions.GitHubActionsReport from 2.5.1 to 2.5.2 by @dependabot[bot] in #3361
- Bump xunit.v3 from 4.0.1 to 4.0.2 by @dependabot[bot] in #3346
- Bump dependabot/fetch-metadata from 2 to 3 by @dependabot[bot] in #3348
- Bump actions/upload-artifact from 7.0.1 to 7.0.2 by @dependabot[bot] in #3347
- Bump actions/download-artifact from 8.0.1 to 8.0.2 by @dependabot[bot] in #3349
- Bump actions/setup-java from 5.7.0 to 6.0.0 by @dependabot[bot] in #3298
- Bump Microsoft.Testing.Extensions.CodeCoverage from 18.10.0 to 18.11.0 by @dependabot[bot] in #3302
- Bump actions/setup-java from 6.0.0 to 6.0.1 by @dependabot[bot] in #3314
- Bump Microsoft.Testing.Extensions.GitHubActionsReport from 2.4.0 to 2.4.1 by @dependabot[bot] in #3318
- Bump xunit.v3 from 4.0.0 to 4.0.1 by @dependabot[bot] in #3316
- Bump Microsoft.Testing.Extensions.TrxReport from 2.4.0 to 2.4.1 by @dependabot[bot] in #3319
- [housekeeping] Automated PR to fix formatting errors by @github-actions[bot] in #3335
- Bump Microsoft.Testing.Extensions.CodeCoverage from 18.11.0 to 18.12.0 by @dependabot[bot] in #3336
- Bump Microsoft.Testing.Extensions.GitHubActionsReport from 2.4.1 to 2.5.0 by @dependabot[bot] in #3337
- Bump Microsoft.Testing.Extensions.TrxReport from 2.4.1 to 2.5.0 by @dependabot[bot] in #3338
- Bump Microsoft.Testing.Extensions.TrxReport from 2.5.0 to 2.5.1 by @dependabot[bot] in #3342
- Bump Microsoft.Testing.Extensions.GitHubActionsReport from 2.5.0 to 2.5.1 by @dependabot[bot] in #3341
- [housekeeping] Automated PR to fix formatting errors by @github-actions[bot] in #3320
- [housekeeping] Automated PR to fix formatting errors by @github-actions[bot] in #3332
New Contributors
- @austinbhale made their first contribution in #3309
- @meyerdominik made their first contribution in #3329
- @snydcol made their first contribution in #3340
- @alexh30486-ui made their first contribution in #3343
- @marcelomoresco made their first contribution in #3373
Full Changelog: 15.0.1...16.0.0