Partilhar via


Ligações compiladas

Browse sample. Navegue pelo exemplo

As associações de dados da Interface do Usuário do Aplicativo Multiplataforma do .NET (.NET MAUI) têm dois problemas principais:

  1. Não há validação em tempo de compilação para expressões de associação. Em vez disso, as associações são resolvidas em runtime. Sendo assim, associações inválidas não são detectadas até o runtime, quando o aplicativo não se comporta conforme esperado ou mensagens de erro são exibidas.
  2. Elas não são econômicas. Associações são resolvidas em runtime usando a inspeção de objeto para uso geral (reflexão), e a sobrecarga de fazer isso varia de uma plataforma para outra.

As associações compiladas melhoram o desempenho da vinculação de dados em aplicativos .NET MAUI resolvendo expressões de vinculação em tempo de compilação em vez de tempo de execução. Além disso, essa validação em tempo de compilação das expressões de associação permite uma melhor experiência de solução de problemas para o desenvolvedor porque associações inválidas são relatadas como erros de build.

Para usar associações compiladas, defina um x:DataType atributo em a VisualElement para o tipo do objeto ao qual o VisualElement e seus filhos se vincularão. É recomendável definir o atributo x:DataType no mesmo nível da hierarquia de exibição em que BindingContext está definido. No entanto, esse atributo pode ser redefinido em qualquer local em uma hierarquia de exibição.

Observação

As associações compiladas exigem o uso da compilação XAML, que é habilitada por padrão no .NET MAUI. Se você tiver desabilitado a compilação XAML, precisará habilitá-la. Para saber mais, consulte XAML Compilation (Compilação de XAML).

Para usar associações compiladas, o x:DataType atributo deve ser definido como um literal de cadeia de caracteres ou um tipo usando a extensão de x:Type marcação. No tempo de compilação de XAML, as expressões de associação inválidas serão relatadas como erros de build. No entanto, o compilador XAML relatará um erro de build somente para a primeira expressão de associação inválida que encontrar. Expressões de associação válidas definidas no VisualElement ou em seus filhos serão compiladas, independentemente de BindingContext estar definido no XAML ou no código. Compilar uma expressão de associação gera o código compilado que obterá um valor de uma propriedade na origem e o definirá na propriedade de destino especificada na marcação. Além disso, dependendo da expressão de associação, o código gerado poderá observar alterações no valor da propriedade de origem e atualizar a propriedade de destino, e pode enviar por push alterações do destino para a origem.

Importante

As associações compiladas são desabilitadas para quaisquer expressões de vinculação que definam a Source propriedade. Isso acontece porque a propriedade Source sempre é definida usando a extensão de marcação x:Reference, que não pode ser resolvida em tempo de compilação.

Além disso, as ligações compiladas não são suportadas atualmente em várias associações.

Usar associações compiladas

O exemplo a seguir demonstra o uso de associações compiladas entre modos de exibição .NET MAUI e propriedades viewmodel:

<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>

O ContentPage instancia o HslColorViewModel e inicializa a propriedade dentro de marcas de elemento de propriedade para a ColorBindingContext propriedade. O ContentPage também define o atributo como o x:DataType tipo viewmodel, indicando que quaisquer expressões de vinculação na ContentPage hierarquia de exibição serão compiladas. Isso pode ser verificado alterando qualquer uma das expressões de vinculação para vincular a uma propriedade viewmodel inexistente, o que resultará em um erro de compilação. Embora este exemplo defina o x:DataType atributo como um literal de cadeia de caracteres, ele também pode ser definido como um tipo com a x:Type extensão de marcação. Para obter mais informações sobre a extensão de x:Type marcação, consulte x:Type Markup Extension.

Importante

O atributo x:DataType pode ser redefinido em qualquer ponto de uma hierarquia de exibição.

Os elementos BoxView, Label e as exibições Slider herdam o contexto de associação da ContentPage. Esses modos de exibição são todos destinos de vinculação que fazem referência às propriedades de origem no viewmodel. Para a propriedade e a propriedade, as associações de dados são – as propriedades no modo de exibição são OneWay definidas a BoxView.ColorLabel.Text partir das propriedades no viewmodel. No entanto, a propriedade Slider.Value usa uma associação TwoWay. Isso permite que cada um seja definido a partir do viewmodel, e também para que o viewmodel seja definido a partir de cada SliderSlider.

Quando o exemplo é executado pela primeira vez, os elementos , e os BoxViewelementos são todos definidos a partir do viewmodel com base no conjunto de propriedades inicial Color quando o viewmodel foi instanciadoSlider. Label À medida que os controles deslizantes são manipulados, os BoxView elementos e Label são atualizados de acordo:

Compiled color selector.

Para obter mais informações sobre esse seletor de cores, consulte ViewModels e notificações de alteração de propriedade.

Usar associações compiladas em um DataTemplate

Associações em um DataTemplate são interpretadas no contexto do objeto que está sendo modelado. Portanto, ao usar associações compiladas em um DataTemplate, o DataTemplate precisa declarar o tipo de seu objeto de dados usando o atributo x:DataType.

O exemplo a seguir demonstra o uso de associações compiladas em um 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>

A propriedade ListView.ItemsSource é definida como a propriedade estática NamedColor.All. A NamedColor classe usa a reflexão .NET para enumerar todos os campos públicos estáticos na Colors classe e armazená-los com seus nomes em uma coleção que é acessível a partir da propriedade estática All . Portanto, o ListView é preenchido com todas as instâncias de NamedColor. Para cada item em ListView, o contexto de associação para o item é definido como um objeto NamedColor. Os elementos BoxView e Label no ViewCell estão associados às propriedades em NamedColor.

O DataTemplate define o atributo para ser o NamedColorx:DataType tipo, indicando que quaisquer expressões de vinculação na hierarquia de DataTemplate exibição serão compiladas. Isso pode ser verificado alterando qualquer uma das expressões de associação para se associar a uma propriedade NamedColor inexistente, o que causará um erro de build. Embora este exemplo defina o x:DataType atributo como um literal de cadeia de caracteres, ele também pode ser definido como um tipo com a x:Type extensão de marcação. Para obter mais informações sobre a extensão de x:Type marcação, consulte x:Type Markup Extension.

Quando o exemplo é executado pela primeira vez, o é preenchido ListView com NamedColor instâncias. Quando um item no ListView é selecionado, a propriedade BoxView.Color é definida como a cor do item selecionado no ListView:

Compiled color list.

Selecionar outros itens no ListView atualiza a cor do BoxView.

Combinar ligações compiladas com associações clássicas

Expressões de associação são compiladas apenas para a hierarquia de exibição em que o atributo x:DataType está definido. Por outro lado, exibições em uma hierarquia na qual o atributo x:DataType não está definido usarão associações clássicas. Portanto, é possível combinar associações compiladas e associações clássicas em uma página. Por exemplo, na seção anterior, os modos de exibição dentro do DataTemplate usam associações compiladas, enquanto o BoxView definido como a cor selecionada no ListView não faz isso.

Estruturar cuidadosamente os atributos x:DataType, portanto, pode levar a uma página que usa associações compiladas e clássicas. Como alternativa, o atributo x:DataType pode ser redefinido a qualquer momento em uma hierarquia de exibição como null usando a extensão de marcação x:Null. Fazer isso indica que qualquer expressão de associação de dentro da hierarquia de exibição usará associações clássicas. O exemplo a seguir demonstra essa abordagem:

<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>   

O StackLayout raiz define o atributo x:DataType como o tipo HslColorViewModel, indicando que as expressões de associação na hierarquia de exibição StackLayout raiz serão compiladas. No entanto, o StackLayout interno redefine o atributo x:DataType como null com a expressão de marcação x:Null. Portanto, as expressões de associação no StackLayout interno usam associações clássicas. Somente o BoxView, dentro da hierarquia de exibição StackLayout raiz, usa associações compiladas.

Para obter mais informações sobre a expressão de marcação x:Null, confira Extensão de marcação x:Null.

Desempenho

As associações compiladas melhoram o desempenho da vinculação de dados, com o benefício do desempenho variando:

  • Uma associação compilada que usa notificação de alteração de propriedade (ou seja, uma associação OneWay, OneWayToSource ou TwoWay) é resolvida aproximadamente oito vezes mais rápido do que uma associação clássica.
  • Uma associação compilada que não usa notificação de alteração de propriedade (ou seja, uma associação OneTime) é resolvida aproximadamente vinte vezes mais rápido do que uma associação clássica.
  • Definir o BindingContext em uma associação compilada que usa notificação de alteração de propriedade (ou seja, uma associação OneWay, OneWayToSource ou TwoWay) é aproximadamente cinco vezes mais rápido do que definir o BindingContext em uma associação clássica.
  • Definir o BindingContext em uma associação compilada que não usa notificação de alteração de propriedade (ou seja, uma associação OneTime), é aproximadamente sete vezes mais rápido do que definir o BindingContext em uma associação clássica.

Essas diferenças de desempenho podem aumentar em dispositivos móveis, dependendo da plataforma usada, da versão do sistema operacional usado e do dispositivo no qual o aplicativo está em execução.