Usar associações de dados em XAML

Concluído

As associações de dados podem ser declaradas em código ou em XAML usando extensões de marcação. Esta unidade discute este último como é a maneira mais comum de criar associações. Há alguns motivos para preferir XAML. Primeiro, a maioria das pessoas considera as associações como parte do código da interface do usuário porque elas obtêm dados para a interface do usuário exibir. Em segundo lugar, há uma extensão de marcação chamada Binding que facilita a tarefa.

O que são ligações de dados

Uma ligação une duas propriedades. Uma propriedade está em sua interface do usuário e a outra está em seu objeto de modelo de dados. Se o valor de qualquer propriedade for alterado, o objeto de vinculação poderá atualizar o outro. Em outras palavras, as associações são objetos intermediários que sincronizam a interface do usuário e os dados. Usamos os termos origem e destino para identificar os dois objetos envolvidos:

  • Fonte: Uma fonte pode ser um objeto de qualquer tipo. Na prática, você normalmente usa um objeto de dados como fonte. Você precisa identificar a propriedade nesse objeto de origem para participar da associação. Você identifica a propriedade definindo a Path propriedade na associação.

  • Destino: O destino é uma propriedade que é implementada usando uma propriedade especial chamada BindableProperty. O objeto com o BindableProperty deve derivar de BindableObject. Todos os controles fornecidos no .NET MAUI derivam de BindableObject e a maioria de suas propriedades são BindableProperties.

O diagrama a seguir ilustra como uma ligação é um objeto intermediário entre duas propriedades:

Um diagrama que ilustra uma associação como um intermediário entre uma propriedade de objeto de origem e uma propriedade vinculável de objeto de destino.

Como criar uma associação de dados em XAML

Vamos examinar uma associação simples criada em XAML usando a extensão de {Binding} marcação. Ele está vinculando a WeatherService.Humidity propriedade da origem à Text propriedade do controle da interface do usuário.

<VerticalStackLayout Margin="10">
    <VerticalStackLayout.Resources>
        <ResourceDictionary>
            <services:WeatherService x:Key="myWeatherService" />
        </ResourceDictionary>
    </VerticalStackLayout.Resources>

    <Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
</VerticalStackLayout>

A fonte de ligação é:

  • Uma instância de objeto do WeatherService tipo. A instância é referenciada por meio da {StaticResource ...} extensão XAML, que aponta para um objeto no dicionário de recursos do layout de pilha.

  • Os Path pontos para uma propriedade nomeada Humidity no WeatherService tipo.

    O Path é o primeiro parâmetro sem nome na {Binding} sintaxe, e a Path= sintaxe pode ser omitida. Estas duas ligações são equivalentes:

    <Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
    <Label Text="{Binding Humidity, Source={StaticResource myWeatherService}}" />
    

O objetivo vinculativo é:

  • O Label controlo.
  • A propriedade do Text controle.

Quando a interface do usuário é exibida, a {Binding} extensão XAML cria uma associação entre o WeatherService e Label. A associação lê o WeatherService.Humidity valor da propriedade na Label.Text propriedade.

Usar outro controle como uma fonte de vinculação

Uma característica útil da ligação é ser capaz de ligar a outros controles. O seguinte XAML é uma demonstração simples:

<VerticalStackLayout HorizontalOptions="Center" VerticalOptions="Center">
    <Label x:Name="TargetLabel" Text="TEXT TO ROTATE" BackgroundColor="Yellow" />
    <Slider WidthRequest="100" Maximum="360"
            Value="{Binding Rotation, Mode=OneWayToSource, Source={x:Reference TargetLabel}}" />
</VerticalStackLayout>

A Slider.Value propriedade está vinculada à Label.Rotation propriedade, mas de uma forma diferente da explicada anteriormente. Esta propriedade está usando o modo OneWayToSourcede vinculação , que reverte o mecanismo de vinculação típico. Em vez de a Origem atualizar o Destino, OneWayToSource atualiza a Origem quando o Destino é alterado. Neste exemplo, quando o controle deslizante se move, ele atualiza a rotação do rótulo com base no valor do controle deslizante, conforme ilustrado na animação a seguir:

Uma imagem animada de um controle deslizante sendo arrastado com um mouse. À medida que o controle deslizante se move, um pedaço de texto gira para corresponder à posição do controle deslizante.

O cenário típico para vincular controles uns aos outros é quando um controle, geralmente um controle de coleção, como um ListView ou CarouselView, tem um item selecionado que você deseja usar como fonte de dados. No exemplo de uma página que exibe a previsão do tempo, você pode ter um ListView presente uma previsão de cinco dias. Quando o usuário seleciona um dia na lista, os detalhes dessa previsão do tempo são exibidos em outros controles. Se o usuário selecionar outro dia, os outros controles serão atualizados novamente com os detalhes do dia selecionado.

Use a mesma fonte em várias associações

O exemplo anterior demonstrou o uso de um recurso estático como fonte para uma única ligação. Essa fonte pode ser usada em várias ligações. Aqui está um exemplo de declaração de uma ligação em três controles diferentes, todos vinculando ao mesmo objeto e propriedade Path, embora alguns omitam a Path propriedade:

<VerticalStackLayout Margin="10">
    <VerticalStackLayout.Resources>
        <vm:SimpleWeatherServiceObject x:Key="myWeatherService" />
    </VerticalStackLayout.Resources>
    <Entry Text="{Binding Humidity, Source={StaticResource myWeatherService}}" />
    <Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
</VerticalStackLayout>

Você não precisa usar o mesmo Path ao usar o mesmo Source:

<VerticalStackLayout Margin="10">
    <VerticalStackLayout.Resources>
        <vm:SimpleWeatherServiceObject x:Key="myWeatherService" />
    </VerticalStackLayout.Resources>
    <Entry Text="{Binding Temperature, Source={StaticResource myWeatherService}}" />
    <Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
</VerticalStackLayout>

Raramente você apresenta um único dado de uma fonte, embora isso possa acontecer. Normalmente, você tem vários controles usando diferentes partes de dados da mesma fonte. Essa situação é tão comum que a BindableObject classe tem uma propriedade chamada BindingContext que funciona como uma fonte para vinculação de dados. Lembre-se de que os controles .NET MAUI herdam da BindableObject classe, portanto, os controles .NET MAUI têm a BindingContext propriedade.

A definição Source da vinculação é opcional. Uma associação que não tenha Source definido procura automaticamente na árvore visual XAML um BindingContext, que é definido no XAML ou atribuído a um elemento pai por código. As ligações são avaliadas seguindo este padrão:

  1. Se a associação definir um Source, essa fonte será usada e a pesquisa será interrompida. A vinculação Path é aplicada ao Source para obter um valor. Se Source não estiver definida, a pesquisa por uma fonte de vinculação será iniciada.

  2. A pesquisa começa com o próprio objeto de destino. Se o objeto BindingContext de destino não for nulo, a pesquisa será interrompida e a associação será Path aplicada ao BindingContext para obter um valor. Se o BindingContext for nulo, a pesquisa continuará.

  3. Esse processo continua até atingir a raiz XAML. A pesquisa termina verificando a BindingContext raiz para um valor não nulo. Se nenhum válido BindingContext foi encontrado, a ligação não tem nada contra o qual se vincular e não faz nada.

É comum definir o BindingContext no nível do objeto raiz, para aplicar a todo o XAML.

Há um último recurso conveniente que vale a pena mencionar. As ligações observam as alterações na referência de objeto de sua origem. Isso funciona até mesmo para ligações que usam BindingContext como fonte. Se o Source ou BindingContext for reatribuído a outro objeto, as associações pegarão os dados da nova fonte e atualizarão seu destino.

Verifique o seu conhecimento

1.

O que é verdadeiro para o objeto de origem em uma associação .NET MAUI?

2.

O que é verdadeiro para a propriedade de destino na vinculação .NET MAUI?

3.

Se todas as ligações em controles dentro de um Grid precisam do mesmo objeto de origem, qual é a estratégia mais segura para definir o objeto de origem apenas uma vez?