Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions docs/user-interface/styles/xaml.md
Original file line number Diff line number Diff line change
Expand Up @@ -444,3 +444,30 @@ In this example, the first <xref:Microsoft.Maui.Controls.BoxView> is styled to b

> [!IMPORTANT]
> Multiple style classes can be applied to a control because the `StyleClass` property is of type `IList<string>`. 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 <xref:Microsoft.Maui.Controls.Style> at runtime, controls that use that style don't automatically reflect the changes. The <xref:Microsoft.Maui.Controls.StyleableElement.InvalidateStyle> 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 <xref:Microsoft.Maui.Controls.StyleableElement> and is also available on <xref:Microsoft.Maui.Controls.Span> and <xref:Microsoft.Maui.Controls.ImageSource>.

::: moniker-end
27 changes: 27 additions & 0 deletions docs/user-interface/visual-states.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <xref:Microsoft.Maui.Controls.VisualState> at runtime, the affected control doesn't automatically reflect the changes. The <xref:Microsoft.Maui.Controls.VisualStateManager.InvalidateVisualStates(Microsoft.Maui.Controls.VisualElement)> method forces a <xref:Microsoft.Maui.Controls.VisualElement> 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
144 changes: 135 additions & 9 deletions docs/whats-new/dotnet-11.md
Original file line number Diff line number Diff line change
@@ -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:

<!-- markdownlint-disable-next-line MD042 -->
- [.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 <xref:Microsoft.Maui.Controls.Style>, 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 <xref:Microsoft.Maui.Controls.LongPressGestureRecognizer> 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
<Image Source="dotnet_bot.png">
<Image.GestureRecognizers>
<LongPressGestureRecognizer Duration="500"
LongPressed="OnLongPressed" />
</Image.GestureRecognizers>
</Image>
```

```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 <xref:Microsoft.Maui.Controls.Maps.Map> 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
<maps:Map IsClusteringEnabled="True"
ClusterClicked="OnClusterClicked" />
```

#### 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<Permissions.PostNotifications>();
if (status == PermissionStatus.Granted)
{
// Schedule notifications
}
```

Description...
:::moniker-end

## .NET for Android

Expand Down