From 285356e1858d17a4ba4d60ecd5e45c37c69737ec Mon Sep 17 00:00:00 2001 From: David Ortinau Date: Fri, 10 Apr 2026 15:33:14 -0500 Subject: [PATCH 1/2] Document InvalidateStyle and InvalidateVisualStates APIs (.NET 11) Add moniker-gated sections documenting: - StyleableElement.InvalidateStyle() in the XAML styles article - VisualStateManager.InvalidateVisualStates() in the visual states article These caller-driven APIs were added in dotnet/maui#34723 for .NET 11 Preview 3 to support in-place style/visual-state mutation scenarios. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/user-interface/styles/xaml.md | 27 +++++++++++++++++++++++++++ docs/user-interface/visual-states.md | 27 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/docs/user-interface/styles/xaml.md b/docs/user-interface/styles/xaml.md index f8a484b8a8..e7eadc7ace 100644 --- a/docs/user-interface/styles/xaml.md +++ b/docs/user-interface/styles/xaml.md @@ -444,3 +444,30 @@ In this example, the first is styled to b > [!IMPORTANT] > Multiple style classes can be applied to a control because the `StyleClass` property is of type `IList`. When this occurs, style classes are applied in ascending list order. Therefore, when multiple style classes set identical properties, the property in the style class that's in the highest list position will take precedence. + +::: moniker range=">=net-maui-11.0" + +## Invalidate and reapply a style + +When you modify the setter values of a at runtime, controls that use that style don't automatically reflect the changes. The method forces a control to unapply and then reapply its current merged style, which causes the updated setter values to take effect. + +The following example modifies a style's setter value and then calls `InvalidateStyle` on each affected control: + +```csharp +// Find the style defined in resources. +var myStyle = (Style)Resources["myLabelStyle"]; + +// Modify a setter value in-place. +myStyle.Setters[0].Value = Colors.Red; + +// Force the controls to pick up the change. +myLabel1.InvalidateStyle(); +myLabel2.InvalidateStyle(); +``` + +> [!NOTE] +> `InvalidateStyle` is a caller-driven API — .NET MAUI does not automatically detect when setter values change. You must call this method on each control that should reflect the updated style. + +The `InvalidateStyle` method is defined on and is also available on and . + +::: moniker-end diff --git a/docs/user-interface/visual-states.md b/docs/user-interface/visual-states.md index 5f8aa48885..904b7f0083 100644 --- a/docs/user-interface/visual-states.md +++ b/docs/user-interface/visual-states.md @@ -313,3 +313,30 @@ When using state triggers to control visual states, .NET MAUI uses the following If multiple triggers are simultaneously active (for example, two custom triggers) then the first trigger declared in the markup takes precedence. For more information about state triggers, see [State triggers](~/fundamentals/triggers.md#state-triggers). + +::: moniker range=">=net-maui-11.0" + +## Invalidate and reapply visual states + +When you modify the setter values inside a at runtime, the affected control doesn't automatically reflect the changes. The method forces a to unapply and then reapply the setters for the current state across all visual state groups, which causes the updated values to take effect. + +The following example modifies a visual state's setter value and then calls `InvalidateVisualStates` to refresh the control: + +```csharp +// Locate the "Pressed" visual state defined on the button. +var groups = VisualStateManager.GetVisualStateGroups(myButton); +var pressedState = groups + .SelectMany(g => g.States) + .First(s => s.Name == "Pressed"); + +// Modify a setter value in-place. +pressedState.Setters[0].Value = Colors.Orange; + +// Force the control to reapply the current state's setters. +VisualStateManager.InvalidateVisualStates(myButton); +``` + +> [!NOTE] +> `InvalidateVisualStates` is a caller-driven API — .NET MAUI does not automatically detect when visual state setter values change. You must call this method on each element that should reflect the updated visual state. + +::: moniker-end From 19b28325fccc30d683939f7d590b509cc138a42b Mon Sep 17 00:00:00 2001 From: David Ortinau Date: Fri, 10 Apr 2026 15:33:47 -0500 Subject: [PATCH 2/2] Add .NET 11 Preview 3 feature entries to What's New page Add documentation for the following Preview 3 features: - Maps: clustering, custom pins, JSON styling, events, visibility/ZIndex - LongPressGestureRecognizer with duration and state tracking - Implicit XAML namespace declarations (enabled by default) - Lazy ResourceDictionary (~8x faster via factory pattern) - InvalidateStyle() and InvalidateVisualStates() APIs - Trimmable CSS for reduced app size - iOS PostNotifications permission Also updates release notes links and ms.date. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/whats-new/dotnet-11.md | 144 +++++++++++++++++++++++++++++++++--- 1 file changed, 135 insertions(+), 9 deletions(-) diff --git a/docs/whats-new/dotnet-11.md b/docs/whats-new/dotnet-11.md index 46ebc98d40..bf2c005559 100644 --- a/docs/whats-new/dotnet-11.md +++ b/docs/whats-new/dotnet-11.md @@ -1,40 +1,166 @@ --- title: What's new in .NET MAUI for .NET 11 description: Learn about the new features introduced in .NET MAUI for .NET 11. -ms.date: 1/27/2026 +ms.date: 07/14/2025 --- # What's new in .NET MAUI for .NET 11 The focus of .NET Multi-platform App UI (.NET MAUI) in .NET 11 is to improve product quality. For information about what's new in each .NET MAUI in .NET 11 release, see the following release notes: - -- [.NET MAUI in .NET 11 Preview 1]() +- [.NET MAUI in .NET 11 Preview 1](https://github.com/dotnet/core/blob/main/release-notes/11.0/preview/preview1/dotnetmaui.md) +- [.NET MAUI in .NET 11 Preview 3](https://github.com/dotnet/core/blob/main/release-notes/11.0/preview/preview3/dotnetmaui.md) > [!IMPORTANT] > Due to working with external dependencies, such as Xcode or Android SDK Tools, the .NET MAUI support policy differs from the [.NET and .NET Core support policy](https://dotnet.microsoft.com/platform/support/policy/maui). For more information, see [.NET MAUI support policy](https://dotnet.microsoft.com/platform/support/policy/maui). In .NET 11, .NET MAUI ships as a .NET workload and multiple NuGet packages. The advantage of this approach is that it enables you to easily pin your projects to specific versions, while also enabling you to easily preview unreleased or experimental builds. -## Feature +## Implicit XAML namespace declarations -This is a description of the feature and essential code snippets to adopt it. +:::moniker range=">=net-maui-11.0" + +Starting in .NET 11, implicit XAML namespace declarations are enabled by default. XAML files no longer need the standard `xmlns` and `xmlns:x` declarations at the root element — the compiler injects them automatically. Existing explicit declarations still compile and can be used to disambiguate duplicate type names. For more information, see [GitHub PR #33834](https://github.com/dotnet/maui/pull/33834). + +:::moniker-end + +## Lazy ResourceDictionary + +:::moniker range=">=net-maui-11.0" + +XAML Source Generation now registers resource dictionary entries as factories, inflating each resource on demand instead of eagerly loading everything at startup. This can yield up to an ~8× improvement in resource dictionary initialization time for apps with large dictionaries. The optimization is automatic when XAML source generation is enabled — no code changes are required. For more information, see [GitHub PR #33826](https://github.com/dotnet/maui/pull/33826). + +:::moniker-end + +## InvalidateStyle and InvalidateVisualStates + +:::moniker range=">=net-maui-11.0" + +Two new APIs make it easier to reapply styles and visual states that have been mutated in place: + +- `VisualElement.InvalidateStyle()` — forces a control to reapply its current , picking up any property changes made directly on the style object. +- `VisualStateManager.InvalidateVisualStates(VisualElement)` — reapplies the current visual state group setters, useful when visual state property values change at runtime. + +These methods are especially useful for Hot Reload scenarios and dynamic UI updates where styles or visual states are modified without replacing the entire style object. For more information, see [GitHub PR #34723](https://github.com/dotnet/maui/pull/34723). + +```csharp +// Mutate a style in place and force the control to pick up the change +var style = myButton.Style; +style.Setters.Add(new Setter { Property = Button.BackgroundColorProperty, Value = Colors.Red }); +myButton.InvalidateStyle(); + +// Reapply visual states after changing a setter value +VisualStateManager.InvalidateVisualStates(myButton); +``` + +:::moniker-end + +## Trimmable CSS + +:::moniker range=">=net-maui-11.0" + +.NET MAUI CSS support is now fully trimmable. If your app doesn't use CSS stylesheets, the CSS infrastructure is trimmed away during publish, reducing app size. No code changes are needed — the linker removes unused CSS types automatically. For more information, see [GitHub PR #33160](https://github.com/dotnet/maui/pull/33160). + +:::moniker-end ## Controls .NET MAUI in .NET 11 includes control enhancements and deprecations. -### A specific control +### LongPressGestureRecognizer + +:::moniker range=">=net-maui-11.0" + +.NET 11 adds a built-in for handling long-press gestures. It supports a configurable press duration, a movement threshold to cancel the gesture if the user's finger moves too far, state tracking via `GestureState`, and command binding with `Command` and `CommandParameter`. For more information, see [GitHub PR #33432](https://github.com/dotnet/maui/pull/33432). + +```xaml + + + + + +``` + +```csharp +void OnLongPressed(object sender, LongPressGestureRecognizerEventArgs e) +{ + if (e.State == GestureState.Completed) + { + // Handle completed long press + } +} +``` + +:::moniker-end + +### Map + +:::moniker range=">=net-maui-11.0" + +The control receives a significant set of enhancements in .NET 11 Preview 3: + +#### Pin clustering + +Enable pin clustering to group nearby pins at lower zoom levels. Set `IsClusteringEnabled` on the map and optionally assign a `ClusteringIdentifier` to each pin. Handle the `ClusterClicked` event to respond when a user taps a cluster. + +```xaml + +``` + +#### Custom pin icons + +Pins can now display a custom image instead of the default marker by setting the `ImageSource` property: + +```csharp +var pin = new Pin +{ + Label = "Custom pin", + Location = new Location(47.6062, -122.3321), + ImageSource = ImageSource.FromFile("custom_pin.png") +}; +``` + +#### Custom JSON map styling (Android) + +Apply a custom JSON style to the map on Android using the `MapStyle` property. This enables dark mode maps, hiding labels, or any styling supported by the Google Maps Styling API. + +#### Map events and element properties + +- `MapLongClicked` — fires when the user long-presses on the map. +- `Circle`, `Polygon`, and `Polyline` now raise click events (`MapElementClick`). +- `MapElement.IsVisible` and `MapElement.ZIndex` — control element visibility and draw order. +- `Pin.ShowInfoWindow()` / `Pin.HideInfoWindow()` — programmatically show or hide a pin's info window. +- `UserLocationChanged` event and `LastUserLocation` property — track the user's location in real time. + +#### Animated MoveToRegion and MapSpan.FromLocations -What was added, removed, changed. +`MoveToRegion` now supports animated transitions, and the new `MapSpan.FromLocations()` factory method creates a span that encompasses a collection of locations. + +For more information, see GitHub PRs [#29101](https://github.com/dotnet/maui/pull/29101), [#33831](https://github.com/dotnet/maui/pull/33831), [#33950](https://github.com/dotnet/maui/pull/33950), [#33982](https://github.com/dotnet/maui/pull/33982), [#33985](https://github.com/dotnet/maui/pull/33985), [#33792](https://github.com/dotnet/maui/pull/33792), [#33799](https://github.com/dotnet/maui/pull/33799), [#33991](https://github.com/dotnet/maui/pull/33991), and [#33993](https://github.com/dotnet/maui/pull/33993). + +:::moniker-end ## Platform features .NET MAUI's platform features have received some updates in .NET 11. -### Feature description +### iOS PostNotifications permission + +:::moniker range=">=net-maui-11.0" + +`Permissions.PostNotifications` is now implemented on iOS, providing a cross-platform API for requesting notification authorization. Previously this permission was only functional on Android. Use it to request authorization before scheduling local notifications on iOS. For more information, see [GitHub PR #30132](https://github.com/dotnet/maui/pull/30132). + +```csharp +var status = await Permissions.RequestAsync(); +if (status == PermissionStatus.Granted) +{ + // Schedule notifications +} +``` -Description... +:::moniker-end ## .NET for Android