Skip to content

Commit 5d8a0c4

Browse files
davidortinauCopilotjfversluis
authored
Add .NET 11 Preview 3 entries to What's New page (#3282)
* 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> * 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> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Gerald Versluis <gerald.versluis@microsoft.com>
1 parent 935e58f commit 5d8a0c4

3 files changed

Lines changed: 186 additions & 6 deletions

File tree

docs/user-interface/styles/xaml.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,3 +444,30 @@ In this example, the first <xref:Microsoft.Maui.Controls.BoxView> is styled to b
444444

445445
> [!IMPORTANT]
446446
> 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.
447+
448+
::: moniker range=">=net-maui-11.0"
449+
450+
## Invalidate and reapply a style
451+
452+
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.
453+
454+
The following example modifies a style's setter value and then calls `InvalidateStyle` on each affected control:
455+
456+
```csharp
457+
// Find the style defined in resources.
458+
var myStyle = (Style)Resources["myLabelStyle"];
459+
460+
// Modify a setter value in-place.
461+
myStyle.Setters[0].Value = Colors.Red;
462+
463+
// Force the controls to pick up the change.
464+
myLabel1.InvalidateStyle();
465+
myLabel2.InvalidateStyle();
466+
```
467+
468+
> [!NOTE]
469+
> `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.
470+
471+
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>.
472+
473+
::: moniker-end

docs/user-interface/visual-states.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,3 +313,30 @@ When using state triggers to control visual states, .NET MAUI uses the following
313313
If multiple triggers are simultaneously active (for example, two custom triggers) then the first trigger declared in the markup takes precedence.
314314

315315
For more information about state triggers, see [State triggers](~/fundamentals/triggers.md#state-triggers).
316+
317+
::: moniker range=">=net-maui-11.0"
318+
319+
## Invalidate and reapply visual states
320+
321+
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.
322+
323+
The following example modifies a visual state's setter value and then calls `InvalidateVisualStates` to refresh the control:
324+
325+
```csharp
326+
// Locate the "Pressed" visual state defined on the button.
327+
var groups = VisualStateManager.GetVisualStateGroups(myButton);
328+
var pressedState = groups
329+
.SelectMany(g => g.States)
330+
.First(s => s.Name == "Pressed");
331+
332+
// Modify a setter value in-place.
333+
pressedState.Setters[0].Value = Colors.Orange;
334+
335+
// Force the control to reapply the current state's setters.
336+
VisualStateManager.InvalidateVisualStates(myButton);
337+
```
338+
339+
> [!NOTE]
340+
> `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.
341+
342+
::: moniker-end

docs/whats-new/dotnet-11.md

Lines changed: 132 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,151 @@ The focus of .NET Multi-platform App UI (.NET MAUI) in .NET 11 is to improve pro
1717
1818
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.
1919

20-
## Feature
20+
## Implicit XAML namespace declarations
2121

22-
This is a description of the feature and essential code snippets to adopt it.
22+
:::moniker range=">=net-maui-11.0"
23+
24+
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).
25+
26+
:::moniker-end
27+
28+
## Lazy ResourceDictionary
29+
30+
:::moniker range=">=net-maui-11.0"
31+
32+
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).
33+
34+
:::moniker-end
35+
36+
## InvalidateStyle and InvalidateVisualStates
37+
38+
:::moniker range=">=net-maui-11.0"
39+
40+
Two new APIs make it easier to reapply styles and visual states that have been mutated in place:
41+
42+
- `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.
43+
- `VisualStateManager.InvalidateVisualStates(VisualElement)` — reapplies the current visual state group setters, useful when visual state property values change at runtime.
44+
45+
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).
46+
47+
```csharp
48+
// Mutate a style in place and force the control to pick up the change
49+
var style = myButton.Style;
50+
style.Setters.Add(new Setter { Property = Button.BackgroundColorProperty, Value = Colors.Red });
51+
myButton.InvalidateStyle();
52+
53+
// Reapply visual states after changing a setter value
54+
VisualStateManager.InvalidateVisualStates(myButton);
55+
```
56+
57+
:::moniker-end
58+
59+
## Trimmable CSS
60+
61+
:::moniker range=">=net-maui-11.0"
62+
63+
.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).
64+
65+
:::moniker-end
2366

2467
## Controls
2568

2669
.NET MAUI in .NET 11 includes control enhancements and deprecations.
2770

28-
### A specific control
71+
### LongPressGestureRecognizer
72+
73+
:::moniker range=">=net-maui-11.0"
74+
75+
.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).
76+
77+
```xaml
78+
<Image Source="dotnet_bot.png">
79+
<Image.GestureRecognizers>
80+
<LongPressGestureRecognizer Duration="500"
81+
LongPressed="OnLongPressed" />
82+
</Image.GestureRecognizers>
83+
</Image>
84+
```
85+
86+
```csharp
87+
void OnLongPressed(object sender, LongPressGestureRecognizerEventArgs e)
88+
{
89+
if (e.State == GestureState.Completed)
90+
{
91+
// Handle completed long press
92+
}
93+
}
94+
```
95+
96+
:::moniker-end
97+
98+
### Map
99+
100+
:::moniker range=">=net-maui-11.0"
101+
102+
The <xref:Microsoft.Maui.Controls.Maps.Map> control receives a significant set of enhancements in .NET 11 Preview 3:
103+
104+
#### Pin clustering
105+
106+
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.
107+
108+
```xaml
109+
<maps:Map IsClusteringEnabled="True"
110+
ClusterClicked="OnClusterClicked" />
111+
```
112+
113+
#### Custom pin icons
114+
115+
Pins can now display a custom image instead of the default marker by setting the `ImageSource` property:
116+
117+
```csharp
118+
var pin = new Pin
119+
{
120+
Label = "Custom pin",
121+
Location = new Location(47.6062, -122.3321),
122+
ImageSource = ImageSource.FromFile("custom_pin.png")
123+
};
124+
```
125+
126+
#### Custom JSON map styling (Android)
127+
128+
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.
129+
130+
#### Map events and element properties
131+
132+
- `MapLongClicked` — fires when the user long-presses on the map.
133+
- `Circle`, `Polygon`, and `Polyline` now raise click events (`MapElementClick`).
134+
- `MapElement.IsVisible` and `MapElement.ZIndex` — control element visibility and draw order.
135+
- `Pin.ShowInfoWindow()` / `Pin.HideInfoWindow()` — programmatically show or hide a pin's info window.
136+
- `UserLocationChanged` event and `LastUserLocation` property — track the user's location in real time.
137+
138+
#### Animated MoveToRegion and MapSpan.FromLocations
29139

30-
What was added, removed, changed.
140+
`MoveToRegion` now supports animated transitions, and the new `MapSpan.FromLocations()` factory method creates a span that encompasses a collection of locations.
141+
142+
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).
143+
144+
:::moniker-end
31145

32146
## Platform features
33147

34148
.NET MAUI's platform features have received some updates in .NET 11.
35149

36-
### Feature description
150+
### iOS PostNotifications permission
151+
152+
:::moniker range=">=net-maui-11.0"
153+
154+
`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).
155+
156+
```csharp
157+
var status = await Permissions.RequestAsync<Permissions.PostNotifications>();
158+
if (status == PermissionStatus.Granted)
159+
{
160+
// Schedule notifications
161+
}
162+
```
37163

38-
Description...
164+
:::moniker-end
39165

40166
## .NET for Android
41167

0 commit comments

Comments
 (0)