diff --git a/docs/fundamentals/data-binding/compiled-bindings.md b/docs/fundamentals/data-binding/compiled-bindings.md index 16f73077f..3fa8aa742 100644 --- a/docs/fundamentals/data-binding/compiled-bindings.md +++ b/docs/fundamentals/data-binding/compiled-bindings.md @@ -1,7 +1,7 @@ --- title: "Compiled bindings" description: "Compiled bindings can be used to improve data binding performance in .NET MAUI applications." -ms.date: 09/27/2024 +ms.date: 10/08/2024 --- # Compiled bindings @@ -24,12 +24,12 @@ Compiled bindings improve data binding performance in .NET MAUI applications by ## Compiled bindings in XAML -To use compiled bindings in XAML, set an `x:DataType` attribute on a to the type of the object that the and its children will bind to. It's recommended to set the `x:DataType` attribute at the same level in the view hierarchy as the `BindingContext` is set. However, this attribute can be re-defined at any location in a view hierarchy. +To use compiled bindings in XAML, set an `x:DataType` attribute on a to the type of the object that the and its children will bind to. It's recommended to set the `x:DataType` attribute at the same level in the view hierarchy as the is set. However, this attribute can be re-defined at any location in a view hierarchy. -> [!NOTE] +> [!IMPORTANT] > Compiled bindings require the use of XAML compilation, which is enabled by default in .NET MAUI. If you've disabled XAML compilation, you'll need to enable it. For more information, see [XAML Compilation](~/xaml/xamlc.md). -To use compiled bindings in XAML, the `x:DataType` attribute must be set to a string literal, or a type using the `x:Type` markup extension. At XAML compile time, any invalid binding expressions will be reported as build errors. However, the XAML compiler will only report a build error for the first invalid binding expression that it encounters. Any valid binding expressions that are defined on the or its children will be compiled, regardless of whether the `BindingContext` is set in XAML or code. Compiling a binding expression generates compiled code that will get a value from a property on the *source*, and set it on the property on the *target* that's specified in the markup. In addition, depending on the binding expression, the generated code may observe changes in the value of the *source* property and refresh the *target* property, and may push changes from the *target* back to the *source*. +To use compiled bindings in XAML, the `x:DataType` attribute must be set to a string literal, or a type using the `x:Type` markup extension. At XAML compile time, any invalid binding expressions will be reported as build errors. However, the XAML compiler will only report a build error for the first invalid binding expression that it encounters. Any valid binding expressions that are defined on the or its children will be compiled, regardless of whether the is set in XAML or code. Compiling a binding expression generates compiled code that will get a value from a property on the *source*, and set it on the property on the *target* that's specified in the markup. In addition, depending on the binding expression, the generated code may observe changes in the value of the *source* property and refresh the *target* property, and may push changes from the *target* back to the *source*. ::: moniker range="=net-maui-8.0" @@ -38,14 +38,22 @@ To use compiled bindings in XAML, the `x:DataType` attribute must be set to a st > > In addition, compiled bindings in XAML are currently unsupported on multi-bindings. -::: moniker-end - -By default, .NET MAUI doesn't produce build warnings for bindings that don't use compiled bindings, unless you've enabled NativeAOT for your app. However, you can opt into compiled bindings warnings being produced by setting the `$(MauiStrictXamlCompilation)` build property to `true` in your app's project file (*.csproj): +By default, .NET MAUI doesn't produce build warnings for XAML bindings that don't use compiled bindings. However, you can opt into compiled bindings warnings being produced by setting the `$(MauiStrictXamlCompilation)` build property to `true` in your app's project file (*.csproj): ```xml true ``` +::: moniker-end + +::: moniker range=">=net-maui-9.0" + +By default, .NET MAUI produces build warnings for XAML bindings that don't use compiled bindings. + +::: moniker-end + +For more information about XAML compiled bindings warnings, see [XAML compiled bindings warnings](#xaml-compiled-bindings-warnings). + ### Use compiled bindings in XAML The following example demonstrates using compiled bindings between .NET MAUI views and viewmodel properties: @@ -77,7 +85,7 @@ The following example demonstrates using compiled bindings between .NET MAUI vie ``` -The instantiates the `HslColorViewModel` and initializes the `Color` property within property element tags for the `BindingContext` property. The also defines the `x:DataType` attribute as the viewmodel type, indicating that any binding expressions in the view hierarchy will be compiled. This can be verified by changing any of the binding expressions to bind to a non-existent viewmodel property, which will result in a build error. While this example sets the `x:DataType` attribute to a string literal, it can also be set to a type with the `x:Type` markup extension. For more information about the `x:Type` markup extension, see [x:Type Markup Extension](~/xaml/markup-extensions/consume.md#xtype-markup-extension). +The instantiates the `HslColorViewModel` and initializes the `Color` property within property element tags for the property. The also defines the `x:DataType` attribute as the viewmodel type, indicating that any binding expressions in the view hierarchy will be compiled. This can be verified by changing any of the binding expressions to bind to a non-existent viewmodel property, which will result in a build error. While this example sets the `x:DataType` attribute to a string literal, it can also be set to a type with the `x:Type` markup extension. For more information about the `x:Type` markup extension, see [x:Type Markup Extension](~/xaml/markup-extensions/consume.md#xtype-markup-extension). > [!IMPORTANT] > The `x:DataType` attribute can be re-defined at any point in a view hierarchy. @@ -92,9 +100,24 @@ For more information about this color selector, see [ViewModels and property-cha ### Use compiled bindings in XAML in a DataTemplate -Bindings in a are interpreted in the context of the object being templated. Therefore, when using compiled bindings in a , the needs to declare the type of its data object using the `x:DataType` attribute. +Bindings in a are interpreted in the context of the object being templated. Therefore, when using compiled bindings in a , the needs to declare the type of its data object using the `x:DataType` attribute. Failure to do this could result in the inheriting an incorrect `x:DataType` from its parent scope: + +```xaml + + + + + + + + + + +``` -The following example demonstrates using compiled bindings in a : +The following example demonstrates correctly setting the `x:DataType` on a : ```xaml is po Selecting other items in the updates the color of the . +::: moniker range=">=net-maui-9.0" + +### Compile bindings that define the `Source` property + +Prior to .NET MAUI 9, the XAML compiler would skip compilation of bindings that define the `Source` property instead of the . From .NET MAUI 9, these bindings can be compiled to take advantage of better runtime performance. However, this optimization isn't enabled by default to avoid breaking existing app code. To enable this optimization, set the `$(MauiEnableXamlCBindingWithSourceCompilation)` build property to `true` in your app's project file: + +```xml +true +``` + +Then, ensure that all your bindings are annotated with the correct `x:DataType` and that they don't inherit incorrect data types from their parent scope: + +```xaml + + +``` + +::: moniker-end + ### Combine compiled bindings with classic bindings in XAML Binding expressions are only compiled for the view hierarchy that the `x:DataType` attribute is defined on. Conversely, any views in a hierarchy on which the `x:DataType` attribute is not defined will use classic bindings. It's therefore possible to combine compiled bindings and classic bindings on a page. For example, in the previous section the views within the use compiled bindings, while the that's set to the color selected in the does not. @@ -167,6 +211,65 @@ The root sets the `x:DataType` attrib For more information about the `x:Null` markup expression, see [x:Null Markup Extension](~/xaml/markup-extensions/consume.md#xnull-markup-extension). +### XAML compiled bindings warnings + +The following table lists the compiler warnings for compiled bindings, and how to resolve them: + +::: moniker range="=net-maui-8.0" + +| Code | Message | Fix | +| ---- | ------- | --- | +| `XC0022` | Binding could be compiled to improve runtime performance if `x:DataType` is specified. | Add `x:DataType` to your XAML to specify the type of the current . It's best practice to add `x:DataType` to all elements where the binding context changes. | +| `XC0023` | Binding could be compiled to improve runtime performance if `x:DataType` is not explicitly `null`. | Replace `x:DataType="{x:Null}"` with the right type. | + +::: moniker-end + +::: moniker range=">=net-maui-9.0" + +| Code | Message | +| ---- | ------- | +| `XC0022` | Binding could be compiled to improve runtime performance if `x:DataType` is specified.

To fix this warning, add `x:DataType` to your XAML to specify the type of the current . It's best practice to add `x:DataType` to all elements where the binding context changes. | +| `XC0023` | Binding could be compiled to improve runtime performance if `x:DataType` is not explicitly `null`.

To fix this warning, replace `x:DataType="{x:Null}"` with the right type. | +| `XC0024` | Binding might be compiled incorrectly since the `x:DataType` annotation comes from an outer scope. Make sure you annotate all `DataTemplate` XAML elements with the correct `x:DataType`.

To fix this warning, ensure that all `DataTemplate` elements are annotated with the correct `x:DataType`. | +| `XC0025` | Binding was not compiled because it has an explicitly set `Source` property and compilation of bindings with `Source` is not enabled. Consider enabling this optimization by setting the `true` in your project file and make sure the correct `x:DataType` is specified for this binding.

To fix this warning, enable the `$(MauiEnableXamlCBindingWithSourceCompilation)` build property in your project file, and annotate all your bindings with the appropriate `x:DataType`. | + +::: moniker-end + +To ensure these warnings aren't ignored, consider changing specific warnings to build errors with the `$(WarningsAsErrors)` build property: + +```xml +$(WarningsAsErrors);XC0022;XC0023 +``` + +To ignore these warnings, use the `$(NoWarn)` build property with specific warning codes: + +```xml +$(NoWarn);XC0022;XC0023 +``` + +::: moniker range="=net-maui-8.0" + +> [!IMPORTANT] +> `XC0022` and `XC0023` warnings will always be suppressed unless the `$(MauiStrictXamlCompilation)` build property is set to `true`. + +::: moniker-end + +If you set the `$(TreatWarningsAsErrors)` build property to `true` in your app's project file, but you want to ignore certain XAML compiler warnings, use either the `$(NoWarn)` build property to silence these warnings or the `$(WarningsNotAsErrors)` build property to reduce the severity of some specific codes. + +::: moniker range=">=net-maui-9.0" + +By default, .NET MAUI produces build warnings for XAML bindings that don't use compiled bindings. You can opt into compiled bindings warnings being treated as errors by setting the `$(MauiStrictXamlCompilation)` and `$(TreatWarningsAsErrors)` build properties to `true` in your app's project file (*.csproj): + +```xml +true +true +``` + +> [!NOTE] +> By default, the `$(MauiStrictXamlCompilation)` build property is `false` unless you are publishing your app using full trimming or NativeAOT. + +::: moniker-end + ::: moniker range=">=net-maui-9.0" ## Compiled bindings in code @@ -230,7 +333,7 @@ Compiled bindings improve data binding performance, with the performance benefit - A compiled binding that uses property-change notification (i.e. a `OneWay`, `OneWayToSource`, or `TwoWay` binding) is resolved approximately 8 times quicker than a classic binding. - A compiled binding that doesn't use property-change notification (i.e. a `OneTime` binding) is resolved approximately 20 times quicker than a classic binding. -- Setting the `BindingContext` on a compiled binding that uses property change notification (i.e. a `OneWay`, `OneWayToSource`, or `TwoWay` binding) is approximately 5 times quicker than setting the `BindingContext` on a classic binding. -- Setting the `BindingContext` on a compiled binding that doesn't use property change notification (i.e. a `OneTime` binding) is approximately 7 times quicker than setting the `BindingContext` on a classic binding. +- Setting the on a compiled binding that uses property change notification (i.e. a `OneWay`, `OneWayToSource`, or `TwoWay` binding) is approximately 5 times quicker than setting the on a classic binding. +- Setting the on a compiled binding that doesn't use property change notification (i.e. a `OneTime` binding) is approximately 7 times quicker than setting the on a classic binding. These performance differences can be magnified on mobile devices, dependent upon the platform being used, the version of the operating system being used, and the device on which the application is running. diff --git a/docs/whats-new/dotnet-9.md b/docs/whats-new/dotnet-9.md index 1d39c0229..c7156ee2a 100644 --- a/docs/whats-new/dotnet-9.md +++ b/docs/whats-new/dotnet-9.md @@ -1,7 +1,7 @@ --- title: What's new in .NET MAUI for .NET 9 description: Learn about the new features introduced in .NET MAUI for .NET 9. -ms.date: 10/04/2024 +ms.date: 10/08/2024 --- # What's new in .NET MAUI for .NET 9 @@ -274,13 +274,9 @@ myEntry.SetBinding(Entry.TextProperty, new MultiBinding ## Compiled bindings in XAML -In .NET MAUI 8, compiled bindings are disabled for any XAML binding expressions that define the `Source` property, and are unsupported on multi-bindings. These restrictions have been removed in .NET MAUI 9. +In .NET MAUI 8, compiled bindings are disabled for any XAML binding expressions that define the `Source` property, and are unsupported on multi-bindings. These restrictions have been removed in .NET MAUI 9. For information about compiling XAML binding expressions that define the `Source` property, see [Compile bindings that define the `Source` property](~/fundamentals/data-binding/compiled-bindings.md?view=net-maui-9.0&preserve-view=true#compile-bindings-that-define-the-source-property). -By default, .NET MAUI doesn't produce build warnings for bindings that don't use compiled bindings, unless you've enabled NativeAOT for your app. However, you can opt into compiled bindings warnings being produced by setting the `$(MauiStrictXamlCompilation)` build property to `true` in your app's project file (*.csproj): - -```xml -true -``` +By default, .NET MAUI 9 produces build warnings for bindings that don't use compiled bindings. For more information about XAML compiled bindings warnings, see [XAML compiled bindings warnings](~/fundamentals/data-binding/compiled-bindings.md?view=net-maui-9.0&preserve-view=true#xaml-compiled-bindings-warnings). ## Handler disconnection @@ -409,6 +405,10 @@ Several areas of .NET MAUI come with trimmer directives, known as feature switch To consume a feature switch you should put the corresponding MSBuild property into your app's project file (*.csproj), which causes the related code to be trimmed from the .NET MAUI assemblies. Disabling features an app doesn't require can help reduce the app size when combined with the `Full` trimming mode. +## XAML compiler + +In .NET MAUI 9, the XAML compiler error codes have changed their prefix from `XFC` to `XC`. Ensure that you update the `$(WarningsAsErrors)`, `$(WarningsNotAsErrors)`, and `$(NoWarn)` build properties in your app's project files, if used, to reference the new prefix. + ## XAML markup extensions All classes that implement , , , and need to be annotated with either the or . This is required due to a XAML compiler optimization introduced in .NET MAUI 9 that enables the generation of more efficient code, which helps reduce the app size and improve runtime performance.