Associações básicas
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:
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 denominadoslider
. - A extensão de marcação
Binding
vincula a propriedadeRotation
do Label à propriedadeValue
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: