Compartilhar via


Modo de vinculação

Browse sample. Navegue pelo exemplo

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:

Reverse binding.

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 destino
  • OneWay — os dados vão da origem ao destino
  • OneWayToSource — os dados vão do destino à fonte
  • OneTime — os dados vão da origem para o destino, mas apenas quando as BindingContext 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:

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, , , LuminositySaturationColore 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 BindingContextarquivo . 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:

Simple color selector.

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