Compartilhar via


Recursos do Kit de Ferramentas MVVM

Dica

Esse conteúdo é um trecho do livro eletrônico, Padrões de Aplicativo Empresarial Usando .NETMAUI, disponível em .NET Docs ou em PDF para download gratuito que pode ser lido off-line.

Padrões de Aplicativo Empresarial Usando .NET MAUI.

Kit de ferramentas MVVM

O padrão MVVM (Model-View-ViewModel) é uma ótima base estrutural para criar nossos aplicativos. Nesse padrão, o ViewModel se torna o backbone do nosso aplicativo, pois fornece comunicação com nossa interface do usuário front-end e componentes de suporte. Para fornecer integração com a interface do usuário, contaremos com as propriedades e os comandos do ViewModel. Conforme detalhado em Atualizando exibições em resposta a alterações no modelo ou modelo de exibição subjacente, a interface INotifyPropertyChanged em nosso ViewModel permite que as alterações em nossas propriedades notifiquem quando o valor é alterado. Implementar todos esses recursos significa que nosso ViewModel pode acabar ficando muito detalhado. Por exemplo, o seguinte código mostra um ViewModel simples com propriedades que geram alterações:

public class SampleViewModel : INotifyPropertyChanged
{
    private string _name;
    private int _value;

    public event PropertyChangedEventHandler PropertyChanged;

    public string Name
    {
        get => _name;
        set => SetPropertyValue(ref _name, value);
    }

    public int Value
    {
        get => _value;
        set => SetPropertyValue(ref _value, value);
    }

    protected void SetPropertyValue<T>(ref T storageField, T newValue, [CallerMemberName] string propertyName = "")
    {
        if (Equals(storageField, newValue))
            return;

        storageField = newValue;
        RaisePropertyChanged(propertyName);
    }

    protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Embora algumas otimizações possam ser feitas ao longo do tempo, ainda acabaremos com um conjunto bastante detalhado de código para definir nosso ViewModel. Esse código pode ser difícil de manter e se torna propenso a erros.

O Pacote NuGet CommunityToolkit.Mvvm (também conhecido como Kit de Ferramentas MVVM) pode ser usado para ajudar a resolver e simplificar esses padrões MVVM comuns. O Kit de Ferramentas MVVM, juntamente com recursos mais recentes para a linguagem .NET, permite lógica simplificada, fácil adoção em um projeto e independência de runtime. O seguinte exemplo mostra o mesmo ViewModel usando componentes que vêm com o Kit de Ferramentas MVVM:

public partial class SampleViewModel : ObservableObject
{
    [ObservableProperty]
    private string _name;

    [ObservableProperty]
    private int _value;
}

Observação

O Kit de Ferramentas MVVM é fornecido com o pacote CommunityToolkit.Mvvm. Para obter informações sobre como adicionar o pacote ao seu projeto, confira Introdução ao MVVM Toolkit na Central de Desenvolvedores da Microsoft.

Em comparação com o exemplo original, conseguimos reduzir drasticamente a complexidade geral e simplificar a manutenção de nosso ViewModel. O Kit de Ferramentas MVVM vem com muitos componentes e recursos comuns pré-criados, como o ObservableObject mostrado acima, que simplifica e padroniza o código que temos em todo o aplicativo.

ObservableObject

O Kit de Ferramentas MVVM fornece ObservableObject o que se destina a ser usado como a base de nossos ViewModel objetos ou qualquer objeto que precise gerar notificações de alteração. Ele implementa INotifyPropertyChanged e INotifyPropertyChanging juntamente com métodos auxiliares para definir propriedades e gerar alterações. Veja abaixo um exemplo de um ViewModel padrão usando ObservableObject:

public class SampleViewModel : ObservableObject
{
    private string _name;
    private int _value;

    public string Name
    {
        get => _name;
        set => SetProperty(ref _name, value);
    }

    public int Value
    {
        get => _value;
        set => SetProperty(ref _value, value);
    }
}

O ObservableObject manipula toda a lógica necessária para gerar notificações de alteração usando o método SetProperty em seu setter de propriedade. Se você tiver uma propriedade que retorna um Task<T>, o método SetPropertyAndNotifyOnCompletion poderá ser usado para atrasar a publicação de uma alteração de propriedade até que a tarefa seja concluída. Os métodos OnPropertyChanged e OnPropertyChanging que também podem ser usados para gerar alterações de propriedade quando necessário em seu objeto.

Para obter informações mais detalhadas sobre ObservableObject, confira ObservableObject no Centro de Desenvolvedores do Kit de Ferramentas MVVM.

RelayCommand e AsyncRelayCommand

A interação entre controles do .NET MAUI (por exemplo, tocar em um botão ou selecionar um item de uma coleção) e o ViewModel é feita com a interface ICommand. O .NET MAUI vem com uma implementação padrão de ICommand com o objeto Command. O MAUI do .NET Command é bastante básico e não tem suporte para recursos mais avançados, como suporte a trabalho assíncrono e status de execução de comando.

O Kit de Ferramentas MVVM vem com dois comandos, RelayCommand e AsyncRelayCommand. O RelayCommand destina-se a situações em que você tem código síncrono a ser executado e tem uma implementação bastante semelhante ao objeto MAUI do .NET Command.

Observação

Embora o .NET MAUICommand e RelayCommand sejam semelhantes, usar RelayCommand permite desacoplar o ViewModel de qualquer referência direta do .NET MAUI. Isso significa que o ViewModel é mais portátil, levando à reutilização mais fácil entre projetos.

O AsyncRelayCommand fornece muitos recursos adicionais ao trabalhar com fluxos de trabalho assíncronos. Isso é bastante comum em nosso ViewModel, pois normalmente estamos nos comunicando com repositórios, APIs, bancos de dados e outros sistemas que utilizam o async/await. O construtor AsyncRelayCommand recebe uma tarefa de execução definida como um Func<Task> ou um delegado que retorna Task como parte do construtor. Enquanto a tarefa de execução estiver em execução, o AsyncRelayCommand monitorará o estado da tarefa e fornecerá atualizações usando a propriedade IsRunning. A propriedade IsRunning pode ser associada à interface do usuário, o que ajuda a gerenciar estados de controle, como mostrar o carregamento com um ActivityIndicator ou desabilitar/habilitar um controle. Enquanto a tarefa de execução está sendo executada, o método Cancel pode ser chamado para tentar o cancelamento da tarefa de execução, se houver suporte.

Por padrão, o AsyncRelayCommand não permite a execução simultânea. Isso é muito útil em situações em que um usuário pode tocar acidentalmente em um controle várias vezes para executar uma operação demorada ou dispendiosa. Durante a execução da tarefa, o AsyncRelayCommand chamará automaticamente o evento CanExecuteChanged. No .NET MAUI, os controles que dão suporte às propriedades Command e CommandParameter, como Button, escutarão esse evento e o habilitarão ou desabilitarão automaticamente durante a execução. Essa funcionalidade pode ser substituída usando um parâmetro personalizado canExecute ou definindo o sinalizador AsyncRelayCommandOptions.AllowConcurrentExecutions no construtor.

Para obter informações mais detalhadas sobre como implementar comandos, confira a seção Implementando comandos no capítulo MVVM. Informações detalhadas do RelayCommand e AsyncRelayCommand estão disponíveis no Comando do Centro de Desenvolvedores do Kit de Ferramentas MVVM.

Geradores de origem

Usar os componentes do Kit de Ferramentas MVVM pronto para uso permite simplificar muito nosso ViewModel. O Kit de Ferramentas MVVM permite simplificar ainda mais os casos comuns de uso de código usando geradores de origem. Os geradores de origem do Kit de Ferramentas MVVM procuram atributos específicos em nosso código e podem gerar wrappers para propriedades e comandos.

Importante

Os Geradores de Origem do Kit de Ferramentas MVVM geram código que é aditivo aos nossos objetos existentes. Por isso, qualquer objeto que esteja aproveitando um gerador de origem precisará ser marcado como partial.

O atributo Kit de Ferramentas ObservableProperty MVVM pode ser aplicado a campos em objetos que herdam de ObservableObject e encapsulará um campo privado com uma propriedade que gera alterações. O seguinte código mostra um exemplo de como usar o atributo ObservableObject no campo _name:

public partial class SampleViewModel : ObservableObject
{
    [ObservableProperty]
    private string _name;
}

Com o atributo ObservableProperty aplicado ao campo _name, o gerador de origem será executado e gerará outra classe parcial com o seguinte código:

partial class SampleViewModel
{
    public string Name
    {
        get => _name;
        set
        {
            if (!EqualityComparer<string>.Default.Equals(_name, value))
            {
                OnNameChanging(value);
                OnPropertyChanging("Name");
                _name = value;
                OnNameChanged(value);
                OnPropertyChanged("Name");
            }
        }
    }
}

O SampleViewModel gerado usou o campo privado _name e gerou uma nova propriedade Name que implementa toda a lógica necessária para gerar notificações de alteração.

O atributo Kit de ferramentas RelayCommand MVVM pode ser aplicado a métodos dentro de um ObservableObject e criará um correspondente RelayCommand ou AsyncRelayCommand. O seguinte código mostra exemplos de como usar o atributo RelayCommand:

public partial class SampleViewModel : ObservableObject
{
    public INavigationService NavigationService { get; set; }

    [ObservableProperty]
    private string _name;

    [ObservableProperty]
    bool _isValid;

    [RelayCommand]
    private Task SettingsAsync()
    {
        return NavigationService.NavigateToAsync("Settings");
    }

    [RelayCommand]
    private void Validate()
    {
        IsValid = !string.IsNullOrEmpty(Name);
    }
}

O RelayCommand aplicado ao método Validate gerará uma RelayCommand validação ValidateCommand porque ele tem um retorno void e o método SettingsAsync gerará um AsyncRelayCommand chamado SettingsCommand. O gerador de origem gerará o seguinte código em outras classes parciais:

partial class SampleViewModel
{
    private AsyncRelayCommand? settingsCommand;

    SettingsCommand => settingsCommand ??= new AsyncRelayCommand(SettingsAsync);
}

partial class SampleViewModel
{
    private RelayCommand? validateCommand;

    public IRelayCommand ValidateCommand => validateCommand ??= new RelayCommand(Validate);
}

Toda a complexidade de encapsular os métodos do ViewModel com uma implementação ICommand foi tratada pelo gerador de origem.

Para obter informações mais detalhadas sobre geradores de origem do Kit de Ferramentas MVVM, confira Geradores de origem MVVM no Centro de Desenvolvedores do Kit de Ferramentas MVVM.

Resumo

O Kit de Ferramentas MVVM é uma ótima maneira de padronizar e simplificar nosso código ViewModel. O Kit de ferramentas MVVM oferece ótimas implementações de componentes MVVM padrão, como ObservableObject e Async/RelayCommand. Os geradores de origem ajudam a simplificar nossas propriedades e comandos ViewModel gerando todo o código clichê necessário para interações de interface do usuário. O Kit de Ferramentas MVVM oferece ainda mais recursos fora do que foi mostrado neste capítulo. Para obter mais informações sobre o Kit de Ferramentas MVVM, confira Introdução ao Kit de Ferramentas MVVM no Centro de Desenvolvedores do Kit de Ferramentas MVVM.