Comparar uma interface do usuário orientada a eventos com uma interface do usuário vinculada a dados

Concluído

Uma interface do usuário orientada a eventos é projetada em torno dos eventos que um controle expõe. Esses eventos podem ser associados ao código do manipulador de eventos que é invocado quando o evento é acionado. Por exemplo, digamos que você tenha um botão que, quando clicado, executa uma operação de longa duração. O manipulador de eventos atribuído ao Clicked evento pode iniciar a operação e, em seguida, definir a propriedade do IsEnabled botão como false, impedindo que o botão seja clicado novamente enquanto a operação está em execução.

Uma interface do usuário vinculada a dados usa a vinculação de dados para apresentar e interagir com dados. As propriedades dos controles são vinculadas às propriedades do objeto de dados, e essas associações podem detetar alterações nas propriedades. Usando o exemplo anterior, considere o botão que executa uma operação de longa duração. Em vez de desativar o botão no code-behind, a IsEnabled propriedade é vinculada à propriedade do objeto de IsBusy dados. Sempre que o objeto de dados se torna "ocupado", o estado ativado do botão é automaticamente alterado para corresponder.

Prós e contras do uso de eventos e code-behind

Usar o manipulador de eventos do controle com code-behind é uma maneira rápida e conveniente de projetar a lógica do aplicativo para sua interface do usuário. Você usa o código para chamar serviços para obter dados, executar operações nesses dados e interagir com os controles na página. O código é usado para manter a interface do usuário e os dados sincronizados.

Considere o exemplo de um aplicativo de serviço meteorológico. O fragmento XAML a seguir contém um botão de interface do usuário simples que o usuário seleciona para obter os dados mais recentes e atualizar a interface do usuário com a umidade.

<VerticalStackLayout Margin="10">
    <HorizontalStackLayout Spacing="20">
        <Label Text="Postal Code:" VerticalOptions="Center" />
        <Entry x:Name="PostalCode" WidthRequest="100" />
        <Button x:Name="RefreshWeatherButton" Text="Refresh" WidthRequest="200" Clicked="RefreshWeatherButton_Clicked" />
    </HorizontalStackLayout>
    <Label x:Name="Humidity" Text="Humidity: ?" />
</VerticalStackLayout>

Captura de tela de um aplicativo .NET MAUI que tem um controle de entrada para um código postal, um botão com a atualização de texto. Sob esses dois controles há um rótulo que representa a umidade.

Há três controles nomeados neste exemplo:

  • Entry controle chamado PostalCode.
  • Buttonchamado RefreshWeatherButton.
  • Labelchamado Humidade.

O RefreshWeatherButton tem um manipulador de eventos declarado para o Clicked evento. Quando o botão é clicado, o manipulador de eventos consulta um serviço meteorológico para obter a previsão do tempo mais recente, usando os dados inseridos PostalCode no controle de entrada, e define o texto do Humidity rótulo para a umidade atual.

private void RefreshWeatherButton_Clicked(object sender, EventArgs e)
{
    WeatherService.Location = PostalCode.Text;
    WeatherService.Refresh();
    Humidity.Text = $"Humidity: {WeatherService.Humidity}";
}

Neste manipulador de eventos, três controles são firmemente acoplados entre si e os dados por meio do code-behind.

Esse design funciona muito bem para pequenas interfaces do usuário, mas assim que a interface do usuário se torna complexa, manter um code-behind firmemente acoplado pode se tornar problemático. Se você excluir ou alterar um controle, deverá limpar qualquer código usando esses controles de interface do usuário, que podem incluir o manipulador de eventos. Se você decidir redesenhar a interface do usuário, também terá muito código para refatorar. E quando a estrutura de dados de backup muda, você precisa mergulhar no código de cada interface do usuário para ficar sincronizado.

A vinculação de dados ajuda

As associações de dados podem ser implementadas em XAML ou código, mas são muito mais comuns em XAML, onde ajudam a reduzir o tamanho do arquivo code-behind. Ao substituir o código de procedimento em manipuladores de eventos por código declarativo ou marcação, o aplicativo é simplificado e esclarecido. Como as associações não exigem code-behind, você pode criar, alterar ou redesenhar facilmente a interface do usuário para se ajustar à forma como deseja apresentar os dados.

Vamos pegar o mesmo exemplo da seção anterior, mas atualizá-lo para usar a vinculação de dados:

<VerticalStackLayout Margin="10">
    <HorizontalStackLayout Spacing="20">
        <Label Text="Postal Code:" VerticalOptions="Center" />
        <Entry Text="{Binding Location, Mode=OneWayToSource}" WidthRequest="100" />
        <Button Text="Refresh" Command="{Binding RefreshWeather}" WidthRequest="200" />
    </HorizontalStackLayout>
    <Label Text="{Binding Humidity}" />
</VerticalStackLayout>

Você pode identificar as propriedades que estão vinculadas a dados, elas usam a sintaxe {Binding ...} da extensão XAML para o valor da propriedade. Não se preocupe com os detalhes ainda, que é abordado mais adiante neste módulo.

Os mesmos três controles são declarados no XAML, mas nenhum deles é nomeado, pois um nome não é necessário:

  • Entry Controlo:

    A propriedade deste Text controle está vinculada a uma propriedade chamada Location.

  • Button Controlo:

    A propriedade do Command botão está vinculada a uma propriedade chamada RefreshWeather. Command é uma propriedade no botão que invoca o código quando o botão é pressionado. É uma alternativa ao Clicked evento usado na vinculação de dados.

  • Label Controlo:

    Esta Text propriedade está vinculada a uma propriedade chamada Humidity.

Nesta interface do usuário simples, todo o code-behind é eliminado. Remover todo o code-behind não é o ponto da vinculação de dados, embora geralmente seja possível. Code-behind ainda tem o seu lugar. A quantidade de vinculação de dados que você implementa depende de você.

Agora, a interface do usuário está fracamente acoplada a um objeto de dados. Porque é que está frouxamente acoplado em vez de firmemente acoplado? Devido à forma como as ligações são avaliadas. Cada controle tem uma BindingContext propriedade. Se o contexto não estiver definido, o contexto do controle pai será usado, e assim por diante, até que a raiz do XAML seja avaliada. Quando as associações são avaliadas, a instância do objeto do contexto é verificada quanto às propriedades necessárias, como a associação do Text controle label à propriedade do Humidity contexto. Se Humidity não existir no contexto, nada acontece.

Como a interface do usuário é fracamente acoplada, você pode reprojetar a interface do usuário sem a preocupação de quebrar o código. No entanto, você pode interromper a funcionalidade. Por exemplo, você pode excluir o botão e o aplicativo ainda compila e é executado, mas você não tem uma maneira de atualizar o tempo. Por outro lado, você pode substituir os Entry controles e Button pelo controle único SearchBar . Esse controle permite inserir texto e invocar um comando.

<SearchBar Text="{Binding Location, Mode=OneWayToSource}" SearchCommand="{Binding RefreshWeather}" />

Como você pode ver, o uso da vinculação de dados no design da interface do usuário pode ajudá-lo a evoluir e alterar sua interface do usuário sem muito trabalho. Ele mantém a interface do usuário sincronizada com os dados automaticamente e a lógica do aplicativo é separada da interface do usuário.

Verifique o seu conhecimento

1.

Qual das instruções a seguir descreve como a vinculação de dados melhora a interface do usuário?

2.

Em um aplicativo que recupera o clima mais recente, um controle de rótulo que representa a temperatura é vinculado ao objeto de dados. Quando o usuário pressiona o botão "Get Weather", acionando o Clicked evento, o que o código do manipulador de eventos faria para atualizar a interface do usuário?