Modo de vinculação
Cada propriedade vinculável da IU do aplicativo multiplataforma do .NET (.NET MAUI) tem um modo de associação padrão que é definido quando a propriedade vinculável é criada e que está disponível na DefaultBindingMode
propriedade do BindableProperty objeto. Esse modo de associação padrão indica o modo em vigor quando essa propriedade é um destino da associação de dados. O modo de associação padrão para a maioria das propriedades, como Rotation
, Scale
e Opacity
, é OneWay
. Quando essas propriedades são destinos de associação de dados, a propriedade de destino é definida na origem.
O exemplo a seguir mostra uma associação de dados definida em um Slider:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingDemos.ReverseBindingPage"
Title="Reverse Binding">
<StackLayout Padding="10, 0">
<Label x:Name="label"
Text="TEXT"
FontSize="80"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Slider x:Name="slider"
VerticalOptions="Center"
Value="{Binding Source={x:Reference label},
Path=Opacity}" />
</StackLayout>
</ContentPage>
Neste exemplo, o é a fonte de vinculação de dados e o é o Label Slider destino. A associação referencia a propriedade Opacity
do Label, que tem um valor padrão igual a 1. Portanto, o é inicializado para o Slider valor 1 do valor inicial Opacity
de Label. Isso é mostrado na captura de tela a seguir:
Além disso, o continua Slider funcionando. Isso ocorre porque o modo de vinculação padrão para a Value
propriedade de Slider é TwoWay
. Isso significa que, quando a propriedade é um destino de vinculação de dados, o destino é definido a partir da origem, mas a origem também é definida a Value
partir do destino. Isso permite que o Slider seja definido a partir do valor inicial Opacity
.
Observação
As propriedades vinculáveis não sinalizam uma alteração de propriedade, a menos que a propriedade realmente seja alterada. Isso impede um loop infinito.
Se o modo de associação padrão na propriedade de destino não for adequado para uma associação de dados específica, é possível substituí-lo definindo a Mode
propriedade de (ou a Binding
Mode
propriedade da extensão de Binding
marcação) para um dos membros da BindingMode
enumeração:
Default
TwoWay
— os dados vão nos dois sentidos entre a origem e o destinoOneWay
— os dados vão da origem ao destinoOneWayToSource
— os dados vão do destino à fonteOneTime
— os dados vão da origem para o destino, mas apenas quando asBindingContext
alterações
Ligações bidirecionais
A maioria das propriedades vinculáveis tem um modo de vinculação padrão de mas algumas propriedades têm um modo de associação padrão de OneWay
TwoWay
, incluindo o seguinte:
- Propriedade
Date
de DatePicker - Propriedade
Text
de Editor, Entry, SearchBar e EntryCell - Propriedade
IsRefreshing
de ListView - Propriedade
SelectedItem
deMultiPage
- Propriedades
SelectedIndex
eSelectedItem
de Picker - Propriedade
Value
de Slider e Stepper - Propriedade
IsToggled
de Switch - Propriedade
On
de SwitchCell - Propriedade
Time
de TimePicker
Essas propriedades são definidas como TwoWay
porque quando as associações de dados são usadas com o padrão MVVM (Model-View-ViewModel), a classe viewmodel é a fonte de vinculação de dados e a exibição, que consiste em exibições como Slider, são destinos de vinculação de dados. As ligações MVVM se assemelham ao exemplo acima, porque é provável que você queira que cada modo de exibição na página seja inicializado com o valor da propriedade correspondente no viewmodel, mas as alterações no modo de exibição também devem afetar a propriedade viewModel.
Ligações unidirecionais à origem
As propriedades vinculáveis somente leitura têm um modo de associação padrão igual a OneWayToSource
. Por exemplo, a SelectedItem
propriedade de tem um modo de vinculação padrão de ListView OneWayToSource
. Isso ocorre porque uma associação na propriedade deve resultar na SelectedItem
configuração da origem da vinculação.
Ligações únicas
Propriedades de destino com um modo de associação igual a OneTime
são atualizadas somente quando o contexto de associação é alterado. Para as associações nessas propriedades de destino, isso simplifica a infraestrutura de associação porque não é necessário monitorar as alterações nas propriedades de origem.
Várias propriedades têm um modo de associação padrão do OneTime
, incluindo a propriedade IsTextPredictionEnabled
de Entry.
Viewmodels e notificações de alteração de propriedade
Ao usar um viewmodel em uma associação de dados, o viewmodel é a fonte de vinculação de dados. O viewmodel não define propriedades vinculáveis, mas implementa um mecanismo de notificação que permite que a infraestrutura de vinculação seja notificada quando o valor de uma propriedade for alterado. Esse mecanismo de notificação é a interface INotifyPropertyChanged
, que define um único evento chamado PropertyChanged
. Uma classe que implementa essa interface normalmente dispara o evento quando uma de suas propriedades públicas altera o valor. O evento não precisa ser gerado se a propriedade nunca for alterada. A INotifyPropertyChanged
interface também é implementada por e um PropertyChanged
evento é gerado sempre BindableObject que uma propriedade vinculável altera o valor.
No exemplo a seguir, as associações de dados permitem selecionar uma cor usando três Slider elementos para matiz, saturação e luminosidade:
public class HslColorViewModel : INotifyPropertyChanged
{
Color color;
string name;
float hue;
float saturation;
float luminosity;
public event PropertyChangedEventHandler PropertyChanged;
public float Hue
{
get
{
return hue;
}
set
{
if (hue != value)
{
Color = Color.FromHsla(value, saturation, luminosity);
}
}
}
public float Saturation
{
get
{
return saturation;
}
set
{
if (saturation != value)
{
Color = Color.FromHsla(hue, value, luminosity);
}
}
}
public float Luminosity
{
get
{
return luminosity;
}
set
{
if (luminosity != value)
{
Color = Color.FromHsla(hue, saturation, value);
}
}
}
public Color Color
{
get
{
return color;
}
set
{
if (color != value)
{
color = value;
hue = color.GetHue();
saturation = color.GetSaturation();
luminosity = color.GetLuminosity();
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Hue"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Saturation"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Luminosity"));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Color"));
Name = NamedColor.GetNearestColorName(color);
}
}
}
public string Name
{
get
{
return name;
}
private set
{
if (name != value)
{
name = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
}
}
}
}
Neste exemplo, a HslColorViewModel
classe define Hue
, , , Luminosity
Saturation
Color
e Name
propriedades. Quando qualquer um dos três componentes de cor altera o valor, a Color
propriedade é recalculada e PropertyChanged
os eventos são gerados para todas as quatro propriedades. Quando a propriedade é alterada, o NamedColor
método estático GetNearestColorName
na classe obtém a cor nomeada mais próxima e define a Name
Color
propriedade.
Quando um viewmodel é definido como uma fonte de vinculação, a infraestrutura de vinculação anexa um manipulador ao PropertyChanged
evento. Dessa forma, a associação pode ser notificada sobre alterações nas propriedades e, em seguida, pode definir as propriedades de destino a partir dos valores alterados. No entanto, quando uma propriedade de destino (ou a definição Binding
de uma propriedade de destino) tem um BindingMode
igual a OneTime
, não é necessário que a infraestrutura de associação anexe um manipulador no evento PropertyChanged
. A propriedade de destino é atualizada somente quando o BindingContext
é alterado e não quando a propriedade de origem em si é alterada.
O XAML a seguir consome o HslColorViewModel
:
<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.SimpleColorSelectorPage">
<ContentPage.BindingContext>
<local:HslColorViewModel Color="MediumTurquoise" />
</ContentPage.BindingContext>
<ContentPage.Resources>
<Style TargetType="Slider">
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
</Style>
</ContentPage.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<BoxView Color="{Binding Color}"
Grid.Row="0" />
<StackLayout Grid.Row="1"
Margin="10, 0">
<Label Text="{Binding Name}"
HorizontalTextAlignment="Center" />
<Slider Value="{Binding Hue}" />
<Slider Value="{Binding Saturation}" />
<Slider Value="{Binding Luminosity}" />
</StackLayout>
</Grid>
</ContentPage>
Neste exemplo, o HslColorViewModel
é instanciado e conjunto de propriedades e Color
definido como o BindingContext
arquivo . A BoxView, o Label e três 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 Color
BoxViewpropriedade do , e a propriedade do , as associações de dados são - as propriedades no modo de Labelexibição são OneWay
definidas a Text
partir das propriedades no viewmodel. A Value
propriedade do , no entanto, usa um TwoWay
modo de Slidervinculação. Isso permite que cada um seja definido a partir do viewmodel, e também para que o viewmodel seja definido a partir de cada Slider Slider.
Quando o exemplo é executado pela primeira vez, o , Labele três Slider elementos são todos definidos a partir do viewmodel com base no conjunto de propriedades inicial Color
quando o BoxViewviewmodel foi instanciado:
À medida que você manipula os controles deslizantes, o e Label é atualizado de BoxView acordo.
Substituindo o modo de vinculação
O modo de associação para uma propriedade de destino pode ser substituído definindo a Mode
propriedade de (ou a Binding
Mode
propriedade da extensão de Binding
marcação) para um dos membros da BindingMode
enumeração.
No entanto, a definição da Mode
propriedade nem sempre produz o resultado esperado. Por exemplo, no exemplo a seguir, definir a Mode
propriedade como TwoWay
não funciona como você poderia esperar:
<Label Text="TEXT"
FontSize="40"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Scale="{Binding Source={x:Reference slider},
Path=Value,
Mode=TwoWay}" />
Neste exemplo, era de se esperar que o Slider fosse inicializado para o Scale
valor inicial da propriedade, que é 1, mas isso não acontece. Quando uma associação TwoWay
é inicializada, o destino é definido na origem primeiro, o que significa que a propriedade Scale
é definida com o valor padrão de Slider igual a 0. Quando a associação TwoWay
é definida no Slider, o Slider inicialmente é definido da origem.
Como alternativa, você pode definir o modo de vinculação como OneWayToSource
:
<Label Text="TEXT"
FontSize="40"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Scale="{Binding Source={x:Reference slider},
Path=Value,
Mode=OneWayToSource}" />
Agora o é inicializado para 1 (o Slider valor padrão de Scale
), mas a manipulação do não afeta a Slider Scale
propriedade.
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.
Um aplicativo muito útil de substituir o modo de vinculação padrão por um TwoWay
modo de vinculação envolve a SelectedItem
propriedade de ListView. O modo de associação padrão é OneWayToSource
. Quando uma associação de dados é definida na SelectedItem
propriedade para fazer referência a uma propriedade source em um viewmodel, essa propriedade source é definida a ListView partir da seleção. No entanto, em algumas circunstâncias, você também pode desejar que o ListView seja inicializado a partir do viewmodel.
Importante
O modo de associação padrão pode variar de controle para controle e é definido quando a propriedade bindable é criada. Ele está disponível na DefaultBindingMode
propriedade do BindableProperty objeto.