Compartir a través de


Enlaces compilados

Browse sample. Examinar la muestra.

Los enlaces de datos de.NET Multi-platform App UI (.NET MAUI) tienen dos problemas principales:

  1. No hay ninguna validación de las expresiones de enlace en tiempo de compilación. Alternativamente, los enlaces se resuelven en tiempo de ejecución. Por lo tanto, los enlaces no válidos no se detectan hasta el tiempo de ejecución, cuando la aplicación no se comporta según lo esperado o aparecen mensajes de error.
  2. No son rentables. Los enlaces se resuelven en tiempo de ejecución mediante la inspección de objetos de uso general (reflejo); el trabajo adicional que supone llevarlo a cabo varía en función de la plataforma.

Los enlaces compilados mejoran el rendimiento del enlace de datos en las aplicaciones .NET MAUI mediante la resolución de expresiones de enlace en tiempo de compilación, en lugar de en tiempo de ejecución. Además, esta validación en tiempo de compilación de expresiones de enlace permite una mejor experiencia de solución de problemas, porque los enlaces no válidos se notifican como errores de compilación.

Para usar enlaces vinculados establece un atributo x:DataType en un elemento VisualElement para el tipo del objeto al que VisualElement y sus elementos secundarios se enlazará. Se recomienda establecer el atributo x:DataType en el mismo nivel de la jerarquía de vistas en que está establecido BindingContext. Sin embargo, este atributo puede volver a definirse en cualquier ubicación en una jerarquía de vistas.

Nota:

Los enlaces compilados requieren el uso de la compilación de XAML, que está habilitada de forma predeterminada en .NET MAUI. Si has deshabilitado la compilación de XAML, deberás habilitarla. Para obtener más información, consulte Compilación XAML.

Para usar enlaces compilados, el atributo x:DataType debe establecerse en un literal de cadena o un tipo con la extensión de marcado x:Type. En tiempo de compilación XAML, las expresiones de enlace no válidas se notificarán como errores de compilación. Sin embargo, el compilador XAML solo notificará un error de compilación para la primera expresión de enlace no válida que encuentre. Las expresiones de enlace válidas que se definen en VisualElement o en sus elementos secundarios se compilarán, independientemente de si BindingContext está establecido en XAML o en código. La compilación de una expresión de enlace genera un código compilado que obtendrá un valor de una propiedad en el origen y lo establecerá en la propiedad en el destino que se especifica en el marcado. Además, dependiendo de la expresión de enlace, el código generado puede observar cambios en el valor de la propiedad de origen y actualizar la propiedad de destino, y puede insertar los cambios desde el destino de nuevo al origen.

Importante

Los enlaces compilados están deshabilitados para las expresiones de enlace que definen la propiedad Source. Esto es así porque la propiedad Source siempre se establece mediante la extensión de marcado x:Reference, que no se puede resolver en tiempo de compilación.

Además, actualmente no se admiten enlaces compilados en enlaces múltiples.

Uso de enlaces compilados

En el ejemplo siguiente se muestra el uso de enlaces compilados entre las vistas de .NET MAUI y las propiedades del modelo de vista:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DataBindingDemos"
             x:Class="DataBindingDemos.CompiledColorSelectorPage"
             x:DataType="local:HslColorViewModel"
             Title="Compiled Color Selector">
    <ContentPage.BindingContext>
        <local:HslColorViewModel Color="Sienna" />
    </ContentPage.BindingContext>
    ...
    <StackLayout>
        <BoxView Color="{Binding Color}"
                 ... />
        <StackLayout Margin="10, 0">
            <Label Text="{Binding Name}" />
            <Slider Value="{Binding Hue}" />
            <Label Text="{Binding Hue, StringFormat='Hue = {0:F2}'}" />
            <Slider Value="{Binding Saturation}" />
            <Label Text="{Binding Saturation, StringFormat='Saturation = {0:F2}'}" />
            <Slider Value="{Binding Luminosity}" />
            <Label Text="{Binding Luminosity, StringFormat='Luminosity = {0:F2}'}" />
        </StackLayout>
    </StackLayout>    
</ContentPage>

ContentPage crea una instancia de HslColorViewModel e inicializa la propiedad Color dentro de las etiquetas de elemento de propiedad para la propiedad BindingContext. ContentPage también define el atributo x:DataType como el tipo de modelo de vista, lo que indica que todas las expresiones de enlace en la jerarquía de vistas ContentPage se compilarán. Esto se puede comprobar cambiando cualquiera de las expresiones de enlace para enlazar a una propiedad ViewModel inexistente, lo cual generará a un error de compilación. Aunque en este ejemplo se establece el atributo x:DataType en un literal de cadena, también se puede establecer en un tipo con la extensión de marcado x:Type. Para obtener más información acerca de la extensión de marcado x:Type, consulte x:Type Markup Extension (Extensión de marcado x:Type).

Importante

El atributo x:DataType puede volver a definirse en cualquier punto de una jerarquía de vistas.

Los elementos BoxView, Label y las vistas Slider heredan el contexto de enlace del elemento ContentPage. Todas estas vistas son destinos de enlace que hacen referencia a las propiedades de origen en el modelo de vista. Para la propiedad BoxView.Color y la propiedad Label.Text, los enlaces de datos son OneWay; las propiedades de las vista se establecen a partir de las propiedades en ViewModel. Sin embargo, la propiedad Slider.Value utiliza un enlace TwoWay. Esto permite que cada elemento Slider se establezca a partir del modelo de vista, y también que el modelo de vista se establezca a partir de cada elemento Slider.

Cuando la aplicación se ejecuta por primera vez, los elementos BoxView, Label y los elementos Slider se establecen todos a partir del modelo de vista basado en la propiedad Color inicial establecida cuando se creó una instancia del modelo de vista. A medida que se manipulan los controles deslizantes, los elementos BoxView y Label se actualizan del modo correspondiente:

Compiled color selector.

Para obtener más información acerca de este selector de colores, consulta Modelos de vista y notificaciones de cambio de propiedad.

Uso de enlaces compilados en DataTemplate

Los enlaces en DataTemplate se interpretan en el contexto del objeto del cual se crea la plantilla. Por lo tanto, cuando utilice enlaces de compilación en DataTemplate, DataTemplate debe declarar el tipo de su objeto de datos mediante el atributo x:DataType.

En el ejemplo siguiente se muestra el uso de enlaces compilados en DataTemplate:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DataBindingDemos"
             x:Class="DataBindingDemos.CompiledColorListPage"
             Title="Compiled Color List">
    <Grid>
        ...
        <ListView x:Name="colorListView"
                  ItemsSource="{x:Static local:NamedColor.All}"
                  ... >
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:NamedColor">
                    <ViewCell>
                        <StackLayout Orientation="Horizontal">
                            <BoxView Color="{Binding Color}"
                                     ... />
                            <Label Text="{Binding FriendlyName}"
                                   ... />
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <!-- The BoxView doesn't use compiled bindings -->
        <BoxView Color="{Binding Source={x:Reference colorListView}, Path=SelectedItem.Color}"
                 ... />
    </Grid>
</ContentPage>

La propiedad ListView.ItemsSource está establecida en la propiedad NamedColor.All estática. La clase NamedColor usa la reflexión de .NET para enumerar todos los campos públicos estáticos de la clase Colors, y almacenarlos con sus nombres en una colección accesible desde la propiedad estática All. Por lo tanto, ListView se rellena con todas las instancias de NamedColor. Para cada elemento de ListView, el contexto de enlace para el elemento está establecido en un objeto NamedColor. Los elementos BoxView y Label de ViewCell están enlazados a propiedades NamedColor.

DataTemplate define el atributo x:DataType para que sea del tipo NamedColor, indicando que se compilará cualquier expresión vinculante en la jerarquía de vistas DataTemplate. Esto se puede comprobar cambiando cualquiera de las expresiones de enlace para enlazar a una propiedad NamedColor inexistente, lo cual generará a un error de compilación. Aunque en este ejemplo se establece el atributo x:DataType en un literal de cadena, también se puede establecer en un tipo con la extensión de marcado x:Type. Para obtener más información acerca de la extensión de marcado x:Type, consulte x:Type Markup Extension (Extensión de marcado x:Type).

Cuando el ejemplo se ejecuta por primera vez, el ListView se rellena con instancias NamedColor. Cuando un elemento de ListView está seleccionado, la propiedad BoxView.Color se establece en el color del elemento seleccionado en ListView:

Compiled color list.

Al seleccionar otros elementos de ListView se actualiza el color de BoxView.

Combinación de enlaces compilados con enlaces clásicos

Las expresiones de enlace solo se compilan para la jerarquía de vistas en la cual está definido el atributo x:DataType. Por contra, todas las vistas en una jerarquía en la cual el atributo x:DataType no esté definido utilizarán enlaces clásicos. Por lo tanto, es posible combinar enlaces compilados y enlaces clásicos en una página. Por ejemplo, en la sección anterior, las vistas dentro de DataTemplate utilizan enlaces compilados, mientras que el elemento BoxView que se establece en el color seleccionado en ListView, no lo hace.

Una estructuración cuidadosa de atributos x:DataType, por lo tanto, puede conseguir que una página utilice enlaces compilados y clásicos. De forma alternativa, el atributo x:DataType se puede volver a definir en cualquier punto en una jerarquía de vistas para null utilizando la extensión de marcado x:Null. Esto indica que las expresiones de enlace dentro de la jerarquía de vistas utilizarán enlaces clásicos. El siguiente ejemplo demuestra este enfoque:

<StackLayout x:DataType="local:HslColorViewModel">
    <StackLayout.BindingContext>
        <local:HslColorViewModel Color="Sienna" />
    </StackLayout.BindingContext>
    <BoxView Color="{Binding Color}"
             VerticalOptions="FillAndExpand" />
    <StackLayout x:DataType="{x:Null}"
                 Margin="10, 0">
        <Label Text="{Binding Name}" />
        <Slider Value="{Binding Hue}" />
        <Label Text="{Binding Hue, StringFormat='Hue = {0:F2}'}" />
        <Slider Value="{Binding Saturation}" />
        <Label Text="{Binding Saturation, StringFormat='Saturation = {0:F2}'}" />
        <Slider Value="{Binding Luminosity}" />
        <Label Text="{Binding Luminosity, StringFormat='Luminosity = {0:F2}'}" />
    </StackLayout>
</StackLayout>   

El elemento StackLayout raíz establece el atributo x:DataType para ser del tipo HslColorViewModel, lo cual indica que todas las expresiones de enlace en la jerarquía de vistas StackLayout se compilarán. Sin embargo, el StackLayout interno redefine el atributo x:DataType en null con la expresión de marcado x:Null. Por lo tanto, las expresiones de enlace dentro del StackLayout interno usan enlaces clásicos. Solo BoxView, dentro de la jerarquía de vistas StackLayout raíz, utiliza enlaces compilados.

Para obtener más información acerca de la expresión de marcado x:Null, consulte x:Null Markup Extension (Extensión de marcado x:Null).

Rendimiento

Los enlaces compilados mejoran el rendimiento de los enlaces de datos, aunque la ventaja de rendimiento varía:

  • Un enlace compilado que utiliza la notificación de cambio de propiedad (es decir, un enlace OneWay, OneWayToSource o TwoWay) se resuelve aproximadamente 8 veces más rápidamente que un enlace clásico.
  • Un enlace compilado que no utiliza la notificación de cambio de propiedad (es decir, un enlace OneTime) se resuelve aproximadamente 20 veces más rápidamente que un enlace clásico.
  • El establecimiento de BindingContext en un enlace compilado que utiliza la notificación de cambio de propiedad (es decir, un enlace OneWay, OneWayToSource o TwoWay) se resuelve aproximadamente 5 veces más rápidamente que el establecimiento de BindingContext en un enlace clásico.
  • El establecimiento de BindingContext en un enlace compilado que no utiliza la notificación de cambio de propiedad (es decir, un enlace OneTime) se resuelve aproximadamente 7 veces más rápidamente que el establecimiento de BindingContext en un enlace clásico.

Estas diferencias de rendimiento se pueden ampliar en dispositivos móviles, dependiendo de la plataforma que se utilice, la versión del sistema operativo que se utilice y el dispositivo en el que se ejecute la aplicación.