Compartilhar via


Associações básicas

Procurar amostra. Procurar no exemplo

A associação de dados do NET MAUI (.NET Multi-platform App UI) vincula um par de propriedades entre dois objetos e pelo menos um deles geralmente é um objeto da interface do usuário. Esses dois objetos são chamados de destino e origem:

  • O destino é o objeto (e a propriedade) no qual a associação de dados é definida.
  • A origem é o objeto (e propriedade) referenciado pela associação de dados.

No caso mais simples, os dados fluem da origem para o destino, o que significa que o valor da propriedade de destino é definido pelo valor da propriedade da origem. No entanto, em alguns casos, os dados podem fluir do destino para a origem ou em ambas os sentidos.

Importante

O destino é sempre o objeto no qual a associação de dados está definida, mesmo se estiver fornecendo os dados em vez de recebendo.

Associações com um contexto de associação

Considere o exemplo XAML a seguir, cuja intenção é girar um Label um manipulando um Slider:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicCodeBindingPage"
             Title="Basic Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="48"
               HorizontalOptions="Center"
               VerticalOptions="Center" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

Sem associações de dados, você definiria o evento ValueChanged do Slider para um manipulador de eventos que acessa a propriedade Value do Slider e define esse valor para a propriedade Rotation do Label. A associação de dados automatiza essa tarefa; por isso, o manipulador de eventos e o código dentro dele não são mais necessários.

Você pode definir uma associação em uma instância de qualquer classe que deriva de BindableObject, que inclui os derivativos Element, VisualElement, View e View. A associação é sempre definida no objeto de destino. A associação faz referência ao objeto de origem. Para definir a associação de dados, use os seguintes dois membros da classe de destino:

  • A propriedade BindingContext especifica o objeto de origem.
  • O método SetBinding especifica a propriedade de destino e a propriedade de origem.

Neste exemplo, o Label é o destino da associação e o Slider é a origem da associação. As alterações na origem Slider afetam a rotação do destino Label. Os dados fluem da origem para o destino.

O método SetBinding definido pelo BindableObject tem um argumento do tipo BindingBase do qual a classe Binding deriva, mas há outros métodos SetBinding definidos pela classe BindableObjectExtensions. O code-behind do XAML usa um método de extensão SetBinding mais simples na classe BindableObjectExtensions:

public partial class BasicCodeBindingPage : ContentPage
{
    public BasicCodeBindingPage()
    {
        InitializeComponent();

        label.BindingContext = slider;
        label.SetBinding(Label.RotationProperty, "Value");
    }
}

O objeto Label é o destino da associação, portanto, é o objeto no qual essa propriedade é definida e no qual o método é chamado. A propriedade BindingContext indica a origem da associação, que é o Slider. O método SetBinding é chamado no destino da associação, mas especifica a propriedade de destino e a propriedade de origem. A propriedade de destino é especificada como um objeto BindableProperty: Label.RotationProperty. A propriedade de origem é especificada como uma cadeia de caracteres e indica a propriedade Value de Slider.

Importante

A propriedade de destino deve ter suporte de uma propriedade associável. Portanto, o objeto de destino deve ser uma instância de uma classe que deriva de BindableObject. Para mais informações, confira Propriedades associáveis.

A propriedade de origem é especificada como uma cadeia de caracteres. Internamente, a reflexão é usada para acessar a propriedade real. Nesse caso específico, no entanto, a propriedade Value também tem suporte de uma propriedade associável.

Ao manipular Slider, o Label gira de acordo:

Associação de código básica.

Como alternativa, a associação de dados pode ser especificada em XAML:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicXamlBindingPage"
             Title="Basic XAML Binding">
    <StackLayout Padding="10, 0">
        <Label Text="TEXT"
               FontSize="80"
               HorizontalOptions="Center"
               VerticalOptions="Center"
               BindingContext="{x:Reference Name=slider}"
               Rotation="{Binding Path=Value}" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

Assim como no código, a associação de dados é definida no objeto de destino, que é o Label. Duas extensões de marcação XAML são usadas para definir a associação de dados:

  • A extensão de marcação x:Reference é necessária para fazer referência ao objeto de origem, que é o Slider denominado slider.
  • A extensão de marcação Binding vincula a propriedade Rotation do Label à propriedade Value do Slider.

Para obter mais informações sobre extensões de marcação XAML, consulte Consumir extensões de marcação XAML.

Observação

A propriedade de origem é especificada com a propriedade Path da extensão de marcação Binding, que corresponde à propriedade Path da classe Binding.

As extensões de marcação XAML, como x:Reference e Binding, podem ter atributos de propriedade de conteúdo definidos, o que, para extensões de marcação XAML, significa que o nome da propriedade não precisa aparecer. A propriedade Name é a propriedade de conteúdo do x:Reference, e a propriedade Path é a propriedade de conteúdo do Binding, o que significa que elas podem ser eliminadas das expressões:

<Label Text="TEXT"
       FontSize="80"
       HorizontalOptions="Center"
       VerticalOptions="Center"
       BindingContext="{x:Reference slider}"
       Rotation="{Binding Value}" />

Importante

O desempenho da associação pode ser melhorado usando associações compiladas. Para obter mais informações, confira Associações compiladas.

Associações sem um contexto de associação

A propriedade BindingContext é um componente importante de associações de dados, mas nem sempre é necessária. O objeto de origem pode ser especificado na chamada SetBinding ou na extensão de marcação Binding:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeCodeBindingPage"
             Title="Alternative Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

Neste exemplo, o Slider é definido para controlar a propriedade Scale do Label. Por esse motivo, o Slider é definido para um intervalo de 2 a 2.

O arquivo code-behind define a associação com o SetBinding método, com o segundo argumento sendo um construtor da classe Binding:

public partial class AlternativeCodeBindingPage : ContentPage
{
    public AlternativeCodeBindingPage()
    {
        InitializeComponent();

        label.SetBinding(Label.ScaleProperty, new Binding("Value", source: slider));
    }
}

O construtor Binding tem seis parâmetros, portanto o parâmetro source é especificado com um argumento nomeado. O argumento é o objeto slider.

Observação

A classe VisualElement define também as propriedades ScaleX e ScaleY, que podem dimensionar o VisualElement de forma diferente nos sentidos horizontal e vertical.

Como alternativa, a associação de dados pode ser especificada em XAML:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeXamlBindingPage"
             Title="Alternative XAML Binding">
    <StackLayout Padding="10, 0">
        <Label Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="Center"
               Scale="{Binding Source={x:Reference slider},
                               Path=Value}" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

Neste exemplo, a extensão de marcação Binding tem duas propriedades definidas, Source e Path, separadas por uma vírgula. A propriedade Source está definida para uma extensão de marcação x:Reference inserida que normalmente tem a mesma sintaxe que a configuração de BindingContext.

A propriedade de conteúdo da extensão de marcação Binding é Path, mas a parte Path= da extensão de marcação só poderá ser eliminada se for a primeira propriedade na expressão. Para eliminar a parte Path=, você precisa trocar as duas propriedades:

Scale="{Binding Value, Source={x:Reference slider}}" />

Embora as extensões de marcação XAML geralmente sejam delimitadas por chaves, elas também podem ser expressas como elementos de objeto:

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="Center">
    <Label.Scale>
        <Binding Source="{x:Reference slider}"
                 Path="Value" />
    </Label.Scale>
</Label>

Neste exemplo, as propriedades Source e Path são atributos XAML normais: Os valores aparecem entre aspas e os atributos não são separados por uma vírgula. A extensão de marcação x:Reference também pode se tornar um elemento de objeto:

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="Center">
    <Label.Scale>
        <Binding Path="Value">
            <Binding.Source>
                <x:Reference Name="slider" />
            </Binding.Source>
        </Binding>
    </Label.Scale>
</Label>

Essa sintaxe não é comum, mas, às vezes, é necessária quando objetos complexos estão envolvidos.

Os exemplos mostrados até agora definem a propriedade BindingContext e a propriedade Source de Binding para uma extensão de marcação x:Reference para fazer referência a outra exibição na página. Essas duas propriedades são do tipo Object, e elas podem ser definidas para qualquer objeto que inclua as propriedades que são adequadas para as origens da associação. Você também pode definir a propriedade BindingContext ou Source como uma extensão de marcação x:Static para fazer referência ao valor de uma propriedade estática ou campo ou como uma extensão de marcação StaticResource para fazer referência a um objeto armazenado em um dicionário de recursos ou diretamente a um objeto, que é normalmente uma instância de um viewmodel.

Observação

A propriedade BindingContext também pode ser definida como um objeto Binding, de modo que as propriedades Source e Path de Binding definem o contexto de associação.

Herança de contexto de associação

Você pode especificar o objeto de origem usando a propriedade BindingContext ou Source do Binding objeto. Se ambas estiverem definidas, a propriedade Source do Binding terá precedência em relação a BindingContext.

Importante

O valor da propriedade BindingContext é herdado por meio da árvore visual.

O exemplo XAML a seguir demonstra a herança de contexto de associação:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BindingContextInheritancePage"
             Title="BindingContext Inheritance">
    <StackLayout Padding="10">
        <StackLayout VerticalOptions="Fill"
                     BindingContext="{x:Reference slider}">

            <Label Text="TEXT"
                   FontSize="80"
                   HorizontalOptions="Center"
                   VerticalOptions="End"
                   Rotation="{Binding Value}" />

            <BoxView Color="#800000FF"
                     WidthRequest="180"
                     HeightRequest="40"
                     HorizontalOptions="Center"
                     VerticalOptions="Start"
                     Rotation="{Binding Value}" />
        </StackLayout>

        <Slider x:Name="slider"
                Maximum="360" />
    </StackLayout>
</ContentPage>

Neste exemplo, a propriedade BindingContext do objeto StackLayout é definida como o objeto slider. Esse contexto de associação é herdado por Label e BoxView, que têm suas propriedades Rotation definidas para a propriedade Value de Slider:

Herança de contexto de associação.