Button

Многоплатформенный пользовательский интерфейс приложения .NET (.NET MAUI) Button отображает текст и реагирует на касание или щелчок, который направляет приложение для выполнения задачи. Обычно Button отображается короткая текстовая строка, указывающая команду, но она также может отображать растровое изображение или сочетание текста и изображения. Button При нажатии пальца или нажатия мыши он инициирует следующую команду.

Button определяет следующие свойства:

  • BorderColor, тип Color, описывает цвет границы кнопки.
  • BorderWidth, тип double, определяет ширину границы кнопки.
  • CharacterSpacingdoubleТип , определяет интервал между символами текста кнопки.
  • Command, типа ICommand, определяет команду, выполняемую при нажатии кнопки.
  • CommandParameter( тип object) — это параметр, передаваемый в Command.
  • ContentLayout( тип ButtonContentLayout) определяет объект, который управляет положением изображения кнопки и интервалами между изображением и текстом кнопки.
  • CornerRadiusintТип , описывает угловой радиус границы кнопки.
  • FontAttributes, типа FontAttributes, определяет стиль текста.
  • FontAutoScalingEnabledboolТип , определяет, будет ли текст кнопки отражать параметры масштабирования, заданные в операционной системе. Значение по умолчанию этого свойства равно true.
  • FontFamily, тип string, определяет семейство шрифтов.
  • FontSize, тип double, определяет размер шрифта.
  • ImageSource, тип ImageSource, указывает растровое изображение для отображения в виде содержимого кнопки.
  • LineBreakMode, типа LineBreakMode, определяет, как следует обрабатывать текст, если он не может помещаться в одну строку.
  • PaddingThicknessТип , определяет заполнение кнопки.
  • Text, типа string, определяет текст, отображаемый в виде содержимого кнопки.
  • TextColorColorТип , описывает цвет текста кнопки.
  • TextTransform, типа TextTransform, определяет регистр текста кнопки.

Эти свойства поддерживаются объектами BindableProperty, то есть эти свойства можно указывать в качестве целевых для привязки и стилизации данных.

Примечание.

При Button определении ImageSource свойства, позволяющего отображать изображение на Buttonизображении, это свойство предназначено для использования при отображении небольшого значка рядом с текстом Button .

Кроме того, Button определяет Clickedи PressedReleased события. Событие Clicked возникает, когда Button касание с пальцем или указателем мыши освобождается из поверхности кнопки. Событие Pressed возникает, когда пальцем нажимает Buttonклавишу, или кнопка мыши нажимается на указатель, расположенный над ним Button. Событие Released возникает при освобождении пальца или кнопки мыши. Как правило, Clicked событие также вызывается одновременно с Released событием, но если указатель мыши скользит от поверхности Button перед выпуском, Clicked это событие может не произойти.

Важно!

Для Button ответа на касания должны быть заданы true его IsEnabled свойства.

Создание кнопки

Чтобы создать кнопку, создайте объект и обработайте Button его Clicked событие.

В следующем примере XAML показано, как создать 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>

Свойство Text указывает текст, отображаемый в Button. Событие Clicked имеет имя обработчика OnButtonClickedсобытий. Этот обработчик находится в файле программной части:

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

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

В этом примере при Button нажатии OnButtonClicked метода выполняется метод. Аргумент sender является объектом, Button ответственным за это событие. Это можно использовать для доступа к объекту Button или для различения нескольких Button объектов, использующих одно и то же Clicked событие. Обработчик Clicked вызывает функцию анимации, которая поворачивает Label 360 градусов в 1000 миллисекундах:

Screenshot of a Button.

Эквивалентный код C# для создания 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);

Использование интерфейса команды

Приложение может реагировать на Button касания без обработки Clicked события. Реализует Button альтернативный механизм уведомлений, называемый командой или интерфейсом команд . Это состоит из двух свойств:

  • Command тип ICommand, интерфейс, определенный System.Windows.Input в пространстве имен.
  • CommandParameter свойство типа Object.

Этот подход особенно подходит в связи с привязкой данных и особенно при реализации шаблона Model-View-ViewModel (MVVM). В приложении MVVM модель представления определяет свойства типа ICommand , которые затем подключаются к Button объектам с привязками данных. .NET MAUI также определяет и классыCommand, реализующие ICommand интерфейс и помогающие модели представления в определении свойств типаICommand.Command<T> Дополнительные сведения о команде см. в разделе "Командирование".

В следующем примере показан очень простой класс viewmodel, определяющий свойство типа с именемNumber, а также два свойства именованного MultiplyBy2Command типа doubleICommand иDivideBy2Command:

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"));
            }
        }
    }
}

В этом примере два ICommand свойства инициализированы в конструкторе класса с двумя объектами типа Command. Конструкторы Command включают небольшую функцию (называется execute аргументом конструктора), которая либо удвояет, либо сокращает значение Number свойства.

В следующем примере XAML используется CommandDemoViewModel класс:

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

В этом примере Label элемент и два Button объекта содержат привязки к трем свойствам CommandDemoViewModel класса. По мере касания двух Button объектов выполняются команды и значение числа изменений. Преимущество этого подхода по сравнению Clicked с обработчиками заключается в том, что все логики, связанные с функциональностью этой страницы, находятся в режиме просмотра, а не в файле программной части, что обеспечивает лучшее разделение пользовательского интерфейса от бизнес-логики.

Кроме того, объекты могут Command управлять включением и отключением Button объектов. Например, предположим, что необходимо ограничить диапазон значений числа от 2до 1010. Вы можете добавить другую функцию в конструктор (называемый аргументом canExecute ), возвращающую true , если необходимо включить следующее Button :

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));
    }
    ···
}

В этом примере вызовы ChangeCanExecute метода Command необходимы, чтобы Command метод можно было вызвать canExecute метод и определить, следует ли Button отключить или нет. При изменении этого кода число достигает предела, оно Button отключено.

Можно также привязать два или более Button элемента к одному свойству ICommand . Элементы Button можно различать с помощью CommandParameter свойства Button. В этом случае необходимо использовать универсальный Command<T> класс. Затем CommandParameter объект передается в качестве аргумента execute в методы и canExecute методы. Дополнительные сведения см. в разделе "Командирование".

Нажмите и отпустите кнопку

Событие Pressed возникает, когда пальцем нажимает Buttonклавишу, или кнопка мыши нажимается на указатель, расположенный над ним Button. Событие Released возникает при освобождении пальца или кнопки мыши. Как правило, Clicked событие также вызывается одновременно с Released событием, но если указатель мыши скользит от поверхности Button перед выпуском, Clicked это событие может не произойти.

В следующем примере XAML показаны Label обработчики, подключенные к Pressed событиям и ButtonReleased событиям:

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

Файл программной части анимирует LabelPressed событие при возникновении события, но приостанавливает поворот при Released возникновении события:

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();
    }
}

Результатом является то, что Label только вращается, пока пальцем контактирует с Button, и останавливается при освобождении пальца.

Визуальные состояния кнопки

Button имеет значение PressedVisualState , которое можно использовать для запуска визуального изменения Button при нажатии, если оно включено.

В следующем примере XAML показано, как определить визуальное состояние для Pressed состояния:

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

В этом примере указывает, PressedVisualState что при Button нажатии его Scale свойство будет изменено со значения по умолчанию от 1 до 0,8. Указывает NormalVisualState , что при Button обычном состоянии его Scale свойство будет иметь значение 1. Таким образом, общий эффект заключается в том, что при Button нажатии она будет немного меньше, а при Button выпуске она будет масштабирована до размера по умолчанию.

Дополнительные сведения о визуальных состояниях см. в разделе "Визуальные состояния".

Использование растровых изображений с кнопками

Класс Button определяет ImageSource свойство, позволяющее отображать небольшое растровое изображение на Buttonодном или в сочетании с текстом. Вы также можете указать порядок упорядочения текста и изображения. Свойство ImageSource имеет тип ImageSource, что означает, что растровые изображения можно загружать из файла, внедренного ресурса, URI или потока.

Растровые изображения не масштабируются для соответствия Button. Оптимальный размер обычно составляет от 32 до 64 устройств независимо от единиц, в зависимости от размера растрового изображения.

Вы можете указать, как Text упорядочены свойства и ImageSource свойства с Button помощью ContentLayout свойства Button. Это свойство имеет тип ButtonContentLayout, и его конструктор имеет два аргумента:

  • Элемент ImagePosition перечисления: Left, TopRightили Bottom указывает, как появляется растровое изображение относительно текста.
  • double Значение интервала между растровым изображением и текстом.

В XAML можно создать Button и задать ContentLayout свойство, указав только элемент перечисления, интервал или оба порядка, разделенные запятыми:

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

Эквивалентный код на C# выглядит так:

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

Отключение кнопки

Иногда приложение вводит состояние, в котором Button щелчк не является допустимой операцией. В таких случаях Button можно отключить, задав свойству IsEnabled значение false.