Partilhar via


Botão

A IU do aplicativo multiplataforma .NET (.NET MAUI) Button exibe texto e responde a um toque ou clique que direciona o aplicativo para executar uma tarefa. Um Button geralmente exibe uma cadeia de texto curta indicando um comando, mas também pode exibir uma imagem de bitmap ou uma combinação de texto e uma imagem. Quando o é pressionado com um dedo ou clicado Button com um mouse, ele inicia esse comando.

Button define as propriedades a seguir:

  • BorderColor, do tipo Color, descreve a cor da borda do botão.
  • BorderWidth, do tipo double, define a largura da borda do botão.
  • CharacterSpacing, do tipo double, define o espaçamento entre caracteres do texto do botão.
  • Command, do tipo ICommand, define o comando que é executado quando o botão é tocado.
  • CommandParameter, do tipo object, é o parâmetro que é passado para Command.
  • ContentLayout, do tipo ButtonContentLayout, define o objeto que controla a posição da imagem do botão e o espaçamento entre a imagem e o texto do botão.
  • CornerRadius, do tipo int, descreve o raio de canto da borda do botão.
  • FontAttributes, do tipo FontAttributes, determina o estilo do texto.
  • FontAutoScalingEnabled, do tipo bool, define se o texto do botão refletirá as preferências de dimensionamento definidas no sistema operacional. O valor padrão dessa propriedade é true.
  • FontFamily, do tipo string, define a família de fontes.
  • FontSize, do tipo double, define o tamanho da fonte.
  • ImageSource, do tipo ImageSource, especifica uma imagem de bitmap a ser exibida como o conteúdo do botão.
  • LineBreakMode, do tipo LineBreakMode, determina como o texto deve ser manipulado quando não cabe em uma linha.
  • Padding, do tipo Thickness, determina o preenchimento do botão.
  • Text, do tipo string, define o texto exibido como o conteúdo do botão.
  • TextColor, do tipo Color, descreve a cor do texto do botão.
  • TextTransform, do tipo TextTransform, define a caixa do texto do botão.

Essas propriedades são apoiadas por BindableProperty objetos, o que significa que elas podem ser alvos de associações de dados e estilizadas.

Observação

Embora Button defina uma propriedade, que permite exibir uma ImageSource imagem no Button, essa propriedade destina-se a ser usada ao exibir um pequeno ícone ao lado do Button texto.

Além disso, define Clicked, PressedButton e Released eventos. O Clicked evento é gerado quando um toque com um Button dedo ou ponteiro do mouse é liberado da superfície do botão. O Pressed evento é gerado quando um dedo pressiona um , ou um Buttonbotão do mouse é pressionado com o ponteiro posicionado sobre o Button. O Released evento é gerado quando o botão do dedo ou do mouse é liberado. Geralmente, um Clicked evento também é gerado ao mesmo tempo que o evento, mas se o ponteiro do dedo ou do mouse deslizar para longe da superfície do antes de Button ser liberado, o ReleasedClicked evento pode não ocorrer.

Importante

Um Button deve ter sua IsEnabled propriedade definida como true para que ele responda a toques.

Criar um botão

Para criar um botão, crie um Button objeto e manipule seu Clicked evento.

O exemplo XAML a seguir mostra como criar um Button:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ButtonDemos.BasicButtonClickPage"
             Title="Basic Button Click">
    <StackLayout>
        <Button Text="Click to Rotate Text!"
                VerticalOptions="Center"
                HorizontalOptions="Center"
                Clicked="OnButtonClicked" />
        <Label x:Name="label"
               Text="Click the Button above"
               FontSize="18"
               VerticalOptions="Center"
               HorizontalOptions="Center" />
    </StackLayout>
</ContentPage>

A propriedade Text especifica o texto exibido no Button. O Clicked evento é definido como um manipulador de eventos chamado OnButtonClicked. Esse manipulador está localizado no arquivo code-behind:

public partial class BasicButtonClickPage : ContentPage
{
    public BasicButtonClickPage ()
    {
        InitializeComponent ();
    }

    async void OnButtonClicked(object sender, EventArgs args)
    {
        await label.RelRotateTo(360, 1000);
    }
}

Neste exemplo, quando o é tocado, o ButtonOnButtonClicked método é executado. O sender argumento é o Button objeto responsável por esse evento. Você pode usar isso para acessar o objeto ou para distinguir entre vários Button objetos que compartilham o Button mesmo Clicked evento. O Clicked manipulador chama uma função de animação que gira os Label 360 graus em 1000 milissegundos:

Screenshot of a Button.

O código C# equivalente para criar um Button é:

Button button = new Button
{
    Text = "Click to Rotate Text!",
    VerticalOptions = LayoutOptions.Center,
    HorizontalOptions = LayoutOptions.Center
};
button.Clicked += async (sender, args) => await label.RelRotateTo(360, 1000);

Usar a interface de comando

Um aplicativo pode responder a Button toques sem manipular o Clicked evento. O Button implementa um mecanismo de notificação alternativo chamado de comando ou interface de comando. Isso consiste em duas propriedades:

Essa abordagem é particularmente adequada em conexão com a vinculação de dados e, particularmente, ao implementar o padrão MVVM (Model-View-ViewModel). Em um aplicativo MVVM, o viewmodel define propriedades do tipo ICommand que são conectadas a Button objetos com associações de dados. O .NET MAUI também define Command e classes que implementam a ICommand interface e Command<T> auxiliam o viewmodel na definição de propriedades do tipo ICommand. Para obter mais informações sobre comando, consulte Comando.

O exemplo a seguir mostra uma classe viewmodel muito simples que define uma propriedade do tipo chamada , e duas propriedades do tipo doubleICommand chamado MultiplyBy2Command e DivideBy2Command:Number

public class CommandDemoViewModel : INotifyPropertyChanged
{
    double number = 1;

    public event PropertyChangedEventHandler PropertyChanged;

    public ICommand MultiplyBy2Command { get; private set; }
    public ICommand DivideBy2Command { get; private set; }

    public CommandDemoViewModel()
    {
        MultiplyBy2Command = new Command(() => Number *= 2);
        DivideBy2Command = new Command(() => Number /= 2);
    }

    public double Number
    {
        get
        {
            return number;
        }
        set
        {
            if (number != value)
            {
                number = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Number"));
            }
        }
    }
}

Neste exemplo, as duas ICommand propriedades são inicializadas no construtor da classe com dois objetos do tipo Command. Os Command construtores incluem uma pequena função (chamada de argumento do execute construtor) que dobra ou reduz pela metade o Number valor da propriedade.

O exemplo XAML a seguir consome a CommandDemoViewModel classe:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ButtonDemos"
             x:Class="ButtonDemos.BasicButtonCommandPage"
             Title="Basic Button Command">
    <ContentPage.BindingContext>
        <local:CommandDemoViewModel />
    </ContentPage.BindingContext>

    <StackLayout>
        <Label Text="{Binding Number, StringFormat='Value is now {0}'}"
               FontSize="18"
               VerticalOptions="Center"
               HorizontalOptions="Center" />
        <Button Text="Multiply by 2"
                VerticalOptions="Center"
                HorizontalOptions="Center"
                Command="{Binding MultiplyBy2Command}" />
        <Button Text="Divide by 2"
                VerticalOptions="Center"
                HorizontalOptions="Center"
                Command="{Binding DivideBy2Command}" />
    </StackLayout>
</ContentPage>

Neste exemplo, o Label elemento e dois Button objetos contêm ligações para as três propriedades na CommandDemoViewModel classe. À medida que os dois Button objetos são tocados, os comandos são executados e o número muda de valor. A vantagem dessa abordagem sobre Clicked os manipuladores é que toda a lógica que envolve a funcionalidade desta página está localizada no viewmodel em vez do arquivo code-behind, obtendo uma melhor separação da interface do usuário da lógica de negócios.

Também é possível que os Command objetos controlem a habilitação e a desativação dos Button objetos. Por exemplo, suponha que você queira limitar o intervalo de valores numéricos entre 2, 10 e 2–10. Você pode adicionar outra função ao construtor (chamado de canExecute argumento) que retorna true se o Button deve ser habilitado:

public class CommandDemoViewModel : INotifyPropertyChanged
{
    ···
    public CommandDemoViewModel()
    {
        MultiplyBy2Command = new Command(
            execute: () =>
            {
                Number *= 2;
                ((Command)MultiplyBy2Command).ChangeCanExecute();
                ((Command)DivideBy2Command).ChangeCanExecute();
            },
            canExecute: () => Number < Math.Pow(2, 10));

        DivideBy2Command = new Command(
            execute: () =>
            {
                Number /= 2;
                ((Command)MultiplyBy2Command).ChangeCanExecute();
                ((Command)DivideBy2Command).ChangeCanExecute();
            },
            canExecute: () => Number > Math.Pow(2, -10));
    }
    ···
}

Neste exemplo, as chamadas para o método de são necessárias para que o método possa chamar o método e determinar se o ChangeCanExecuteCommandcanExecute deve ser desabilitado CommandButton ou não. Com essa alteração de código, à medida que o número atinge o limite, o Button é desabilitado.

Também é possível que dois ou mais Button elementos sejam vinculados à mesma ICommand propriedade. Os Button elementos podem ser distinguidos usando a CommandParameter propriedade de Button. Nesse caso, convém usar a classe genérica Command<T> . O CommandParameter objeto é então passado como um argumento para os execute métodos e canExecute . Para obter mais informações, consulte Comando.

Pressione e solte o botão

O Pressed evento é gerado quando um dedo pressiona um , ou um Buttonbotão do mouse é pressionado com o ponteiro posicionado sobre o Button. O Released evento é gerado quando o botão do dedo ou do mouse é liberado. Geralmente, um Clicked evento também é gerado ao mesmo tempo que o evento, mas se o ponteiro do dedo ou do mouse deslizar para longe da superfície do antes de Button ser liberado, o ReleasedClicked evento pode não ocorrer.

O exemplo XAML a seguir mostra um e um LabelButton com manipuladores anexados para os Pressed eventos e Released :

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ButtonDemos.PressAndReleaseButtonPage"
             Title="Press and Release Button">
    <StackLayout>
        <Button Text="Press to Rotate Text!"
                VerticalOptions="Center"
                HorizontalOptions="Center"
                Pressed="OnButtonPressed"
                Released="OnButtonReleased" />
        <Label x:Name="label"
               Text="Press and hold the Button above"
               FontSize="18"
               VerticalOptions="Center"
               HorizontalOptions="Center" />
    </StackLayout>
</ContentPage>

O arquivo code-behind anima quando um evento ocorre, mas suspende a rotação quando Label um PressedReleased evento ocorre:

public partial class PressAndReleaseButtonPage : ContentPage
{
    IDispatcherTimer timer;
    Stopwatch stopwatch = new Stopwatch();

    public PressAndReleaseButtonPage()
    {
        InitializeComponent();

        timer = Dispatcher.CreateTimer();
        timer.Interval = TimeSpan.FromMilliseconds(16);
        timer.Tick += (s, e) =>
        {
            label.Rotation = 360 * (stopwatch.Elapsed.TotalSeconds % 1);
        };
    }

    void OnButtonPressed(object sender, EventArgs args)
    {
        stopwatch.Start();
        timer.Start();
    }

    void OnButtonReleased(object sender, EventArgs args)
    {
        stopwatch.Stop();
        timer.Stop();
    }
}

O resultado é que o apenas gira enquanto um dedo está em contato com o , e pára quando o LabelButtondedo é liberado.

Estados visuais do botão

Button tem um PressedVisualState que pode ser usado para iniciar uma alteração visual no Button quando pressionado, desde que esteja habilitado.

O exemplo XAML a seguir mostra como definir um estado visual para o Pressed estado:

<Button Text="Click me!"
        ...>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CommonStates">
            <VisualState x:Name="Normal">
                <VisualState.Setters>
                    <Setter Property="Scale"
                            Value="1" />
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="Pressed">
                <VisualState.Setters>
                    <Setter Property="Scale"
                            Value="0.8" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Button>

Neste exemplo, o especifica que, quando o PressedVisualStateButton é pressionado, sua Scale propriedade será alterada de seu valor padrão de 1 para 0,8. O NormalVisualState especifica que, quando o Button estiver em um estado normal, sua Scale propriedade será definida como 1. Portanto, o efeito geral é que, quando o é pressionado, ele é redimensionado para ser um pouco menor e, quando o ButtonButton é lançado, ele é redimensionado para seu tamanho padrão.

Para obter mais informações sobre estados visuais, consulte Estados visuais.

Usar bitmaps com botões

A Button classe define uma propriedade que permite exibir uma ImageSource pequena imagem de bitmap no Button, sozinho ou em combinação com texto. Você também pode especificar como o texto e a imagem são organizados. A ImageSource propriedade é do tipo ImageSource, o que significa que os bitmaps podem ser carregados de um arquivo, recurso incorporado, URI ou fluxo.

Os bitmaps não são dimensionados para se ajustarem a um Buttonarquivo . O melhor tamanho geralmente é entre 32 e 64 unidades independentes de dispositivo, dependendo do tamanho que você deseja que o bitmap seja.

Você pode especificar como as Text propriedades e ImageSource são organizadas Button usando a ContentLayout propriedade de Button. Essa propriedade é do tipo ButtonContentLayout, e seu construtor tem dois argumentos:

  • Um membro da ImagePosition enumeração: Left, , Right, Topou Bottom indicando como o bitmap aparece em relação ao texto.
  • Um double valor para o espaçamento entre o bitmap e o texto.

Em XAML, você pode criar uma Button propriedade e definir especificando ContentLayout apenas o membro de enumeração, ou o espaçamento, ou ambos em qualquer ordem separada por vírgulas:

<Button Text="Button text"
        ImageSource="button.png"
        ContentLayout="Right, 20" />

Este é o código C# equivalente:

Button button = new Button
{
    Text = "Button text",
    ImageSource = new FileImageSource
    {
        File = "button.png"
    },
    ContentLayout = new Button.ButtonContentLayout(Button.ButtonContentLayout.ImagePosition.Right, 20)
};

Desativar um botão

Às vezes, um aplicativo entra em um estado em que um Button clique não é uma operação válida. Nesses casos, o pode ser desabilitado Button definindo sua IsEnabled propriedade como false.