Xamarin.Forms Пуговица
Кнопка реагирует на касание или нажатие, которое направляет приложение для выполнения конкретной задачи.
Самый Button
фундаментальный интерактивный элемент управления во всем Xamarin.Forms. Обычно Button
отображается короткая текстовая строка, указывающая команду, но она также может отображать растровое изображение или сочетание текста и изображения. Пользователь нажимает Button
пальцем или щелкает его мышью, чтобы инициировать следующую команду.
Обработка нажатий кнопки
Button
определяет событие, которое запускается, когда пользователь нажимает Clicked
Button
указатель мыши или пальцем. Событие запускается при освобождении пальца или кнопки мыши из поверхности.Button
Для Button
ответа на касания должны быть заданы true
его IsEnabled
свойства.
На странице "Базовый нажатие кнопки " в примере показано, как создать экземпляр Button
xaml и обработать его Clicked
событие. Файл BasicButtonClickPage.xaml содержит как aStackLayout
, так Label
и :Button
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ButtonDemos.BasicButtonClickPage"
Title="Basic Button Click">
<StackLayout>
<Label x:Name="label"
Text="Click the Button below"
FontSize="Large"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center" />
<Button Text="Click to Rotate Text!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"
Clicked="OnButtonClicked" />
</StackLayout>
</ContentPage>
Как Button
правило, занимает все пространство, которое разрешено для него. Например, если свойство не задано HorizontalOptions
Button
как другое Fill
, Button
будет занимать полную ширину родительского элемента.
По умолчанию Button
прямоугольный прямоугольник, но его можно указать скругленными углами с помощью CornerRadius
свойства, как описано ниже в разделе "Внешний вид кнопки".
Свойство Text
указывает текст, отображаемый в Button
. Событие Clicked
имеет имя обработчика OnButtonClicked
событий. Этот обработчик находится в файле программной части BasicButtonClickPage.xaml.cs:
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 миллисекундах. Вот программа, запущенная на устройствах iOS и Android, а также в качестве приложения универсальная платформа Windows (UWP) на рабочем столе Windows 10:
Обратите внимание, что метод OnButtonClicked
включает async
модификатор, так как await
используется в обработчике событий. Обработчик Clicked
событий требует async
модификатора только в том случае, если текст обработчика используется await
.
Каждая платформа выполняет отрисовку Button
собственного конкретного способа. В разделе "Внешний вид кнопки" вы увидите, как задать цвета и сделать границу видимой Button
для более настраиваемых внешних видов. Button
IFontElement
реализует интерфейс, поэтому он включает FontFamily
FontSize
и FontAttributes
свойства.
Создание кнопки в коде
Обычно создается экземпляр Button
xaml, но вы также можете создать его в коде Button
. Это может быть удобно, если приложению нужно создать несколько кнопок на основе данных, которые можно перечислить циклом foreach
.
На странице нажатия кнопки кода показано, как создать страницу, которая функционально эквивалентна странице "Базовый нажатие кнопки", но полностью в C#:
public class CodeButtonClickPage : ContentPage
{
public CodeButtonClickPage ()
{
Title = "Code Button Click";
Label label = new Label
{
Text = "Click the Button below",
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.Center
};
Button button = new Button
{
Text = "Click to Rotate Text!",
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.Center
};
button.Clicked += async (sender, args) => await label.RelRotateTo(360, 1000);
Content = new StackLayout
{
Children =
{
label,
button
}
};
}
}
Все выполняется в конструкторе класса. Clicked
Так как обработчик имеет длину только одного оператора, его можно подключить к событию очень просто:
button.Clicked += async (sender, args) => await label.RelRotateTo(360, 1000);
Конечно, можно также определить обработчик событий как отдельный метод (как OnButtonClick
и метод в базовом нажатии кнопки) и присоединить этот метод к событию:
button.Clicked += OnButtonClicked;
Отключение кнопки
Иногда приложение находится в определенном состоянии, в котором конкретный Button
щелчок не является допустимой операцией. В таких случаях следует отключить, Button
задав для свойства значение false
IsEnabled
. Классический Entry
пример — это элемент управления для имени файла, сопровождаемого файлом открытия Button
файла: Button
его следует включить только в том случае, если некоторый текст был введен в файл Entry
.
Эту задачу можно использовать DataTrigger
, как показано в статье "Триггеры данных".
Использование интерфейса команды
Приложение может реагировать на Button
касания без обработки Clicked
события. Реализует Button
альтернативный механизм уведомлений, называемый командой или интерфейсом команд . Это состоит из двух свойств:
Command
типICommand
, интерфейс, определенныйSystem.Windows.Input
в пространстве имен.CommandParameter
свойство типаObject
.
Этот подход особенно подходит в связи с привязкой данных, и особенно при реализации архитектуры Model-View-ViewModel (MVVM). Эти разделы рассматриваются в статьях "Привязка данных", "От привязок данных к MVVM" и MVVM.
В приложении MVVM модель представления определяет свойства типа ICommand
, которые затем подключаются к элементам XAML Button
с привязками данных. Xamarin.Formsтакже определяет и классыCommand
, реализующие ICommand
интерфейс и помогающие модели представления в определении свойств типаICommand
.Command<T>
Команды подробно описаны в статье "Интерфейс команд", но на странице "Базовая кнопка" в примере показан базовый подход.
Класс CommandDemoViewModel
представляет собой очень простую модель представления, которая определяет свойство типа double
с именем, а также два свойства типа ICommand
с именем Number
MultiplyBy2Command
иDivideBy2Command
:
class CommandDemoViewModel : INotifyPropertyChanged
{
double number = 1;
public event PropertyChangedEventHandler PropertyChanged;
public CommandDemoViewModel()
{
MultiplyBy2Command = new Command(() => Number *= 2);
DivideBy2Command = new Command(() => Number /= 2);
}
public double Number
{
set
{
if (number != value)
{
number = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Number"));
}
}
get
{
return number;
}
}
public ICommand MultiplyBy2Command { private set; get; }
public ICommand DivideBy2Command { private set; get; }
}
Два ICommand
свойства инициализированы в конструкторе класса с двумя объектами типа Command
. Конструкторы Command
включают небольшую функцию (называется execute
аргументом конструктора), которая либо двойнит, либо половины Number
свойства.
Файл BasicButtonCommand.xaml задает его BindingContext
экземпляру CommandDemoViewModel
. Элемент Label
и два Button
элемента содержат привязки к трем свойствам:CommandDemoViewModel
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
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="Large"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center" />
<Button Text="Multiply by 2"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"
Command="{Binding MultiplyBy2Command}" />
<Button Text="Divide by 2"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"
Command="{Binding DivideBy2Command}" />
</StackLayout>
</ContentPage>
По мере касания двух Button
элементов выполняются команды и значение числа изменений:
Преимущество этого подхода по сравнению Clicked
с обработчиками заключается в том, что все логики, связанные с функциональностью этой страницы, находятся в режиме просмотра, а не в файле программной части, что обеспечивает лучшее разделение пользовательского интерфейса от бизнес-логики.
Кроме того, объекты могут Command
управлять включением и отключением Button
элементов. Например, предположим, что необходимо ограничить диапазон значений числа от 2до 10 –10. Вы можете добавить другую функцию в конструктор (называемый аргументом canExecute
), которая возвращает true
, если она должна быть включена Button
. Ниже приведено изменение конструктора CommandDemoViewModel
:
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
методы. Этот метод подробно показан в разделе "Базовый команд" статьи "Интерфейс командной строки".
В примере также используется этот метод в своем MainPage
классе. Файл MainPage.xaml содержит Button
для каждой страницы примера:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ButtonDemos"
x:Class="ButtonDemos.MainPage"
Title="Button Demos">
<ScrollView>
<FlexLayout Direction="Column"
JustifyContent="SpaceEvenly"
AlignItems="Center">
<Button Text="Basic Button Click"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:BasicButtonClickPage}" />
<Button Text="Code Button Click"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:CodeButtonClickPage}" />
<Button Text="Basic Button Command"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:BasicButtonCommandPage}" />
<Button Text="Press and Release Button"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:PressAndReleaseButtonPage}" />
<Button Text="Button Appearance"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:ButtonAppearancePage}" />
<Button Text="Toggle Button Demo"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:ToggleButtonDemoPage}" />
<Button Text="Image Button Demo"
Command="{Binding NavigateCommand}"
CommandParameter="{x:Type local:ImageButtonDemoPage}" />
</FlexLayout>
</ScrollView>
</ContentPage>
Каждое Button
свойство привязано Command
к свойству с именем NavigateCommand
, и CommandParameter
для него задан Type
объект, соответствующий одному из классов страниц в проекте.
Это NavigateCommand
свойство имеет тип ICommand
и определяется в файле кода программной части:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
NavigateCommand = new Command<Type>(async (Type pageType) =>
{
Page page = (Page)Activator.CreateInstance(pageType);
await Navigation.PushAsync(page);
});
BindingContext = this;
}
public ICommand NavigateCommand { private set; get; }
}
Конструктор инициализирует NavigateCommand
свойство Command<Type>
объекту, так как Type
является типом CommandParameter
объекта, заданного в XAML-файле. Это означает, что execute
метод имеет аргумент типа Type
, соответствующий этому CommandParameter
объекту. Функция создает экземпляр страницы, а затем переходит к ней.
Обратите внимание, что конструктор завершается установкой для BindingContext
себя. Это необходимо для свойств в XAML-файле для привязки к свойству NavigateCommand
.
Нажатие и освобождение кнопки
Помимо события Clicked
Button
также определяет события Pressed
и Released
. Это Pressed
событие возникает, когда пальцем нажимает клавишу Button
, или кнопка мыши нажимается указателем, расположенным над ним Button
. Событие Released
возникает при освобождении пальца или кнопки мыши. Как правило, Clicked
событие также запускается Released
одновременно с событием, но если указатель мыши или пальцем скользит от поверхности Button
перед освобождением, Clicked
событие может не произойти.
Часто Pressed
используются и Released
события, но их можно использовать для специальных целей, как показано на странице "Кнопка нажатия и выпуска". XAML-файл содержит Label
обработчики, подключенные к Pressed
событиям и Button
Released
событиям:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ButtonDemos.PressAndReleaseButtonPage"
Title="Press and Release Button">
<StackLayout>
<Label x:Name="label"
Text="Press and hold the Button below"
FontSize="Large"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center" />
<Button Text="Press to Rotate Text!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"
Pressed="OnButtonPressed"
Released="OnButtonReleased" />
</StackLayout>
</ContentPage>
Файл программной части анимирует Label
Pressed
событие при возникновении события, но приостанавливает поворот при Released
возникновении события:
public partial class PressAndReleaseButtonPage : ContentPage
{
bool animationInProgress = false;
Stopwatch stopwatch = new Stopwatch();
public PressAndReleaseButtonPage ()
{
InitializeComponent ();
}
void OnButtonPressed(object sender, EventArgs args)
{
stopwatch.Start();
animationInProgress = true;
Device.StartTimer(TimeSpan.FromMilliseconds(16), () =>
{
label.Rotation = 360 * (stopwatch.Elapsed.TotalSeconds % 1);
return animationInProgress;
});
}
void OnButtonReleased(object sender, EventArgs args)
{
animationInProgress = false;
stopwatch.Stop();
}
}
Результатом является то, что Label
только поворачивается, пока пальцем контактирует с Button
, и останавливается при освобождении пальца:
Такое поведение имеет приложения для игр: палец, удерживаемый на Button
экране, может сделать перемещение объекта на экране в определенном направлении.
Внешний вид кнопки
Наследуется Button
или определяет несколько свойств, влияющих на его внешний вид:
TextColor
— это цветButton
текстаBackgroundColor
— цвет фона для этого текстаBorderColor
цвет области вокругButton
FontFamily
— семейство шрифтов, используемое для текстаFontSize
— это размер текстаFontAttributes
указывает, является ли текст курсивным или полужирнымBorderWidth
— ширина границыCornerRadius
— это угол радиусаButton
CharacterSpacing
— интервал между символамиButton
текста.TextTransform
определяет регистрButton
текста.
Примечание.
Класс Button
также имеет Margin
и Padding
свойства, которые управляют поведением макета Button
объекта. Дополнительные сведения см. в статье Поля и заполнение.
Эффекты шести из этих свойств (за исключением FontFamily
и FontAttributes
) показаны на странице "Внешний вид кнопки". Другое свойство, Image
описано в разделе "Использование растровых карт с кнопкой".
Все представления и привязки данных на странице "Внешний вид кнопки" определяются в XAML-файле:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ButtonDemos"
x:Class="ButtonDemos.ButtonAppearancePage"
Title="Button Appearance">
<StackLayout>
<Button x:Name="button"
Text="Button"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"
TextColor="{Binding Source={x:Reference textColorPicker},
Path=SelectedItem.Color}"
BackgroundColor="{Binding Source={x:Reference backgroundColorPicker},
Path=SelectedItem.Color}"
BorderColor="{Binding Source={x:Reference borderColorPicker},
Path=SelectedItem.Color}" />
<StackLayout BindingContext="{x:Reference button}"
Padding="10">
<Slider x:Name="fontSizeSlider"
Maximum="48"
Minimum="1"
Value="{Binding FontSize}" />
<Label Text="{Binding Source={x:Reference fontSizeSlider},
Path=Value,
StringFormat='FontSize = {0:F0}'}"
HorizontalTextAlignment="Center" />
<Slider x:Name="borderWidthSlider"
Minimum="-1"
Maximum="12"
Value="{Binding BorderWidth}" />
<Label Text="{Binding Source={x:Reference borderWidthSlider},
Path=Value,
StringFormat='BorderWidth = {0:F0}'}"
HorizontalTextAlignment="Center" />
<Slider x:Name="cornerRadiusSlider"
Minimum="-1"
Maximum="24"
Value="{Binding CornerRadius}" />
<Label Text="{Binding Source={x:Reference cornerRadiusSlider},
Path=Value,
StringFormat='CornerRadius = {0:F0}'}"
HorizontalTextAlignment="Center" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="Label">
<Setter Property="VerticalOptions" Value="Center" />
</Style>
</Grid.Resources>
<Label Text="Text Color:"
Grid.Row="0" Grid.Column="0" />
<Picker x:Name="textColorPicker"
ItemsSource="{Binding Source={x:Static local:NamedColor.All}}"
ItemDisplayBinding="{Binding FriendlyName}"
SelectedIndex="0"
Grid.Row="0" Grid.Column="1" />
<Label Text="Background Color:"
Grid.Row="1" Grid.Column="0" />
<Picker x:Name="backgroundColorPicker"
ItemsSource="{Binding Source={x:Static local:NamedColor.All}}"
ItemDisplayBinding="{Binding FriendlyName}"
SelectedIndex="0"
Grid.Row="1" Grid.Column="1" />
<Label Text="Border Color:"
Grid.Row="2" Grid.Column="0" />
<Picker x:Name="borderColorPicker"
ItemsSource="{Binding Source={x:Static local:NamedColor.All}}"
ItemDisplayBinding="{Binding FriendlyName}"
SelectedIndex="0"
Grid.Row="2" Grid.Column="1" />
</Grid>
</StackLayout>
</StackLayout>
</ContentPage>
В Button
верхней части страницы есть три Color
свойства, привязанные к Picker
элементам в нижней части страницы. Элементы в Picker
элементах — это цвета из NamedColor
класса, включенного в проект. Три Slider
элемента содержат двусторонняя привязка к FontSize
и BorderWidth
CornerRadius
свойствам объектаButton
.
Эта программа позволяет экспериментировать с сочетаниями всех этих свойств:
Чтобы увидеть границу Button
, необходимо задать BorderColor
значение, отличное Default
от значения, а BorderWidth
также положительное значение.
В iOS вы заметите, что большая ширина границы встраивается в интерьер и Button
вмешивается в отображение текста. Если вы решили использовать границу с iOS Button
, вам, вероятно, нужно начать и завершить Text
свойство пробелами, чтобы сохранить ее видимость.
В UWP выберите значение CornerRadius
, превышающее половину высоты Button
возникающего исключения.
Визуальные состояния кнопки
Button
имеет значение Pressed
VisualState
, которое можно использовать для запуска визуального изменения 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>
Указывает Pressed
VisualState
, что при Button
нажатии нажатия его Scale
свойство будет изменено со значения по умолчанию от 1 до 0,8. Указывает Normal
VisualState
, что при Button
обычном состоянии его Scale
свойство будет иметь значение 1. Таким образом, общий эффект заключается в том, что при Button
нажатии она будет немного меньше, а при Button
выпуске она будет масштабирована до размера по умолчанию.
Дополнительные сведения о визуальных состояниях см. в разделе "Диспетчер визуальных состоянийXamarin.Forms".
Создание кнопки переключения
Можно подкласс Button
, чтобы он работал как выключенный переключатель: коснитесь кнопки один раз, чтобы переключить кнопку и снова коснитесь ее, чтобы отключить его.
ToggleButton
Следующий класс является производным от Button
и определяет новое событие с именем Toggled
и логическим свойством.IsToggled
Это те же два свойства, определенные в следующих Xamarin.FormsSwitch
свойствах:
class ToggleButton : Button
{
public event EventHandler<ToggledEventArgs> Toggled;
public static BindableProperty IsToggledProperty =
BindableProperty.Create("IsToggled", typeof(bool), typeof(ToggleButton), false,
propertyChanged: OnIsToggledChanged);
public ToggleButton()
{
Clicked += (sender, args) => IsToggled ^= true;
}
public bool IsToggled
{
set { SetValue(IsToggledProperty, value); }
get { return (bool)GetValue(IsToggledProperty); }
}
protected override void OnParentSet()
{
base.OnParentSet();
VisualStateManager.GoToState(this, "ToggledOff");
}
static void OnIsToggledChanged(BindableObject bindable, object oldValue, object newValue)
{
ToggleButton toggleButton = (ToggleButton)bindable;
bool isToggled = (bool)newValue;
// Fire event
toggleButton.Toggled?.Invoke(toggleButton, new ToggledEventArgs(isToggled));
// Set the visual state
VisualStateManager.GoToState(toggleButton, isToggled ? "ToggledOn" : "ToggledOff");
}
}
Конструктор ToggleButton
присоединяет обработчик к Clicked
событию, чтобы он смог изменить значение IsToggled
свойства. Метод OnIsToggledChanged
запускает Toggled
событие.
Последняя строка OnIsToggledChanged
метода вызывает статический VisualStateManager.GoToState
метод с двумя текстовыми строками ToggledOn и ToggledOff. Вы можете ознакомиться с этим методом и о том, как приложение может реагировать на визуальные состояния в статье Диспетчер визуальных состояний.Xamarin.Forms
Так как ToggleButton
вызывается VisualStateManager.GoToState
, самому классу не нужно включать дополнительные средства для изменения внешнего вида кнопки на основе его IsToggled
состояния. Это ответственность за XAML, на котором размещается ToggleButton
объект .
На странице демонстрации кнопки переключателя содержатся два экземпляра разметки, включая разметку диспетчера визуальных ToggleButton
состояний, задающую Text
BackgroundColor
TextColor
и кнопку на основе визуального состояния:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:ButtonDemos"
x:Class="ButtonDemos.ToggleButtonDemoPage"
Title="Toggle Button Demo">
<ContentPage.Resources>
<Style TargetType="local:ToggleButton">
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
<Setter Property="HorizontalOptions" Value="Center" />
</Style>
</ContentPage.Resources>
<StackLayout Padding="10, 0">
<local:ToggleButton Toggled="OnItalicButtonToggled">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="ToggleStates">
<VisualState Name="ToggledOff">
<VisualState.Setters>
<Setter Property="Text" Value="Italic Off" />
<Setter Property="BackgroundColor" Value="#C0C0C0" />
<Setter Property="TextColor" Value="Black" />
</VisualState.Setters>
</VisualState>
<VisualState Name="ToggledOn">
<VisualState.Setters>
<Setter Property="Text" Value=" Italic On " />
<Setter Property="BackgroundColor" Value="#404040" />
<Setter Property="TextColor" Value="White" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</local:ToggleButton>
<local:ToggleButton Toggled="OnBoldButtonToggled">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="ToggleStates">
<VisualState Name="ToggledOff">
<VisualState.Setters>
<Setter Property="Text" Value="Bold Off" />
<Setter Property="BackgroundColor" Value="#C0C0C0" />
<Setter Property="TextColor" Value="Black" />
</VisualState.Setters>
</VisualState>
<VisualState Name="ToggledOn">
<VisualState.Setters>
<Setter Property="Text" Value=" Bold On " />
<Setter Property="BackgroundColor" Value="#404040" />
<Setter Property="TextColor" Value="White" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</local:ToggleButton>
<Label x:Name="label"
Text="Just a little passage of some sample text that can be formatted in italic or boldface by toggling the two buttons."
FontSize="Large"
HorizontalTextAlignment="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>
Обработчики Toggled
событий находятся в файле кода программной части. Они отвечают за задание FontAttributes
свойства Label
на основе состояния кнопок:
public partial class ToggleButtonDemoPage : ContentPage
{
public ToggleButtonDemoPage ()
{
InitializeComponent ();
}
void OnItalicButtonToggled(object sender, ToggledEventArgs args)
{
if (args.Value)
{
label.FontAttributes |= FontAttributes.Italic;
}
else
{
label.FontAttributes &= ~FontAttributes.Italic;
}
}
void OnBoldButtonToggled(object sender, ToggledEventArgs args)
{
if (args.Value)
{
label.FontAttributes |= FontAttributes.Bold;
}
else
{
label.FontAttributes &= ~FontAttributes.Bold;
}
}
}
Ниже приведена программа, запущенная в iOS, Android и UWP:
Использование растровых изображений в кнопках
Класс Button
определяет ImageSource
свойство, которое позволяет отображать растровое изображение в Button
одном или в сочетании с текстом. Вы также можете указать порядок упорядочения текста и изображения.
Свойство ImageSource
имеет тип ImageSource
, что означает, что растровые изображения можно загружать из файла, внедренного ресурса, URI или потока.
Примечание.
Button
Хотя можно загрузить анимированный GIF-файл, он будет отображать только первый кадр GIF.
Каждая платформа, поддерживаемая с помощью Xamarin.Forms изображений, может храниться в нескольких размерах для разных разрешений пикселей различных устройств, на которых может работать приложение. Эти несколько растровых карт именуются или хранятся таким образом, чтобы операционная система может выбрать оптимальное соответствие для разрешения дисплея видео устройства.
Для растрового Button
изображения лучшего размера обычно составляет от 32 до 64 единиц, независимых от устройства, в зависимости от того, насколько большой размер он должен быть. Изображения, используемые в этом примере, основаны на размере 48 независимых от устройств единиц.
В проекте iOS папка Resources содержит три размера этого образа:
- 48-пиксельная квадратная растровая карта, сохраненная как /Resources/MonkeyFace.png
- 96-пиксельная квадратная растровая карта, сохраненная как /Resource/MonkeyFace@2x.png
- 144-пиксельная квадратная растровая карта, хранящуюся как /Resource/MonkeyFace@3x.png
Все три растровых изображения были предоставлены действие сборки пакетаResource.
Для проекта Android все растровые изображения имеют одно и то же имя, но они хранятся в разных вложенных папках папки Resources :
- 72-пиксельная квадратная растровая карта, сохраненная как /Resources/drawable-hdpi/MonkeyFace.png
- 96-пиксельная квадратная растровая карта, сохраненная как /Resources/drawable-xhdpi/MonkeyFace.png
- 144-пиксельная квадратная растровая карта, сохраненная как /Resources/drawable-xxhdpi/MonkeyFace.png
- 192-пиксельная квадратная растровая карта, сохраненная как /Resources/drawable-xxxhdpi/MonkeyFace.png
Они были даны действие сборки AndroidResource.
В проекте UWP растровые изображения могут храниться в любом месте проекта, но они обычно хранятся в пользовательской папке или существующей папке Assets . Проект UWP содержит следующие растровые изображения:
- 48-пиксельная квадратная растровая карта, сохраненная как /Assets/MonkeyFace.scale-100.png
- 96-пиксельная квадратная растровая карта, сохраненная как /Assets/MonkeyFace.scale-200.png
- 192-пиксельная квадратная растровая карта, сохраненная как /Assets/MonkeyFace.scale-400.png
Все они получили действие сборки содержимого.
Вы можете указать, как Text
упорядочены свойства и ImageSource
свойства с Button
помощью ContentLayout
свойства Button
. Это свойство имеет тип ButtonContentLayout
, который является внедренным классом в Button
. Конструктор имеет два аргумента:
- Элемент
ImagePosition
перечисления:Left
,Top
Right
илиBottom
указывает, как появляется растровое изображение относительно текста. double
Значение интервала между растровым изображением и текстом.
По умолчанию используются Left
10 единиц. Два свойства только для ButtonContentLayout
чтения именованных Position
и Spacing
предоставляют значения этих свойств.
В коде можно создать Button
и задать следующее ContentLayout
свойство:
Button button = new Button
{
Text = "button text",
ImageSource = new FileImageSource
{
File = "image filename"
},
ContentLayout = new Button.ButtonContentLayout(Button.ButtonContentLayout.ImagePosition.Right, 20)
};
В XAML необходимо указать только элемент перечисления, интервал или оба порядка, разделенные запятыми:
<Button Text="button text"
ImageSource="image filename"
ContentLayout="Right, 20" />
Страница демонстрации кнопки изображения используется OnPlatform
для указания различных имен файлов для файлов растровых карт iOS, Android и UWP. Если вы хотите использовать одно и то же имя файла для каждой платформы и избежать использования OnPlatform
, необходимо сохранить растровые изображения UWP в корневом каталоге проекта.
Первый на странице Button
"Демонстрация кнопки изображения" задает Image
свойство, но не Text
свойство:
<Button>
<Button.ImageSource>
<OnPlatform x:TypeArguments="ImageSource">
<On Platform="iOS, Android" Value="MonkeyFace.png" />
<On Platform="UWP" Value="Assets/MonkeyFace.png" />
</OnPlatform>
</Button.ImageSource>
</Button>
Если растровые карты UWP хранятся в корневом каталоге проекта, эта разметка может быть значительно упрощена:
<Button ImageSource="MonkeyFace.png" />
Чтобы избежать много повторной разметки в файле ImageButtonDemo.xaml , неявное Style
также определяется для задания ImageSource
свойства. Это Style
автоматически применяется к пяти другим Button
элементам. Ниже приведен полный XAML-файл:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ButtonDemos.ImageButtonDemoPage">
<FlexLayout Direction="Column"
JustifyContent="SpaceEvenly"
AlignItems="Center">
<FlexLayout.Resources>
<Style TargetType="Button">
<Setter Property="ImageSource">
<OnPlatform x:TypeArguments="ImageSource">
<On Platform="iOS, Android" Value="MonkeyFace.png" />
<On Platform="UWP" Value="Assets/MonkeyFace.png" />
</OnPlatform>
</Setter>
</Style>
</FlexLayout.Resources>
<Button>
<Button.ImageSource>
<OnPlatform x:TypeArguments="ImageSource">
<On Platform="iOS, Android" Value="MonkeyFace.png" />
<On Platform="UWP" Value="Assets/MonkeyFace.png" />
</OnPlatform>
</Button.ImageSource>
</Button>
<Button Text="Default" />
<Button Text="Left - 10"
ContentLayout="Left, 10" />
<Button Text="Top - 10"
ContentLayout="Top, 10" />
<Button Text="Right - 20"
ContentLayout="Right, 20" />
<Button Text="Bottom - 20"
ContentLayout="Bottom, 20" />
</FlexLayout>
</ContentPage>
Последние четыре Button
элемента используют ContentLayout
свойство для указания положения и интервала текста и растрового изображения:
Теперь вы видели различные способы обработки Button
событий и изменения Button
внешнего вида.