Xamarin.Forms Kancing
Tombol merespons ketukan atau klik yang mengarahkan aplikasi untuk melakukan tugas tertentu.
Button
adalah kontrol interaktif paling mendasar di semua Xamarin.Forms. Button
biasanya menampilkan string teks pendek yang menunjukkan perintah, tetapi juga dapat menampilkan gambar bitmap, atau kombinasi teks dan gambar. Pengguna menekan Button
dengan jari atau mengkliknya dengan mouse untuk memulai perintah tersebut.
Menangani klik tombol
Button
Clicked
menentukan peristiwa yang diaktifkan saat pengguna mengetuk Button
dengan jari atau penunjuk mouse. Peristiwa dipicu ketika jari atau tombol mouse dilepaskan dari permukaan Button
. Button
properti harus IsEnabled
diatur ke true
agar properti merespons ketukan.
Halaman Klik Tombol Dasar dalam sampel menunjukkan cara membuat instans Button
di XAML dan menangani peristiwanya Clicked
. File BasicButtonClickPage.xaml berisi StackLayout
dengan dan 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>
Cenderung Button
menempati semua ruang yang diizinkan untuk itu. Misalnya, jika Anda tidak mengatur HorizontalOptions
properti ke Button
sesuatu selain Fill
, Button
akan menempati lebar penuh induknya.
Secara default, Button
persegi panjang, tetapi Anda dapat memberikan sudut bulat dengan menggunakan CornerRadius
properti , seperti yang dijelaskan di bawah ini di bagian Tampilan tombol.
Properti Text
menentukan teks yang muncul di Button
. Kejadian Clicked
diatur ke penanganan aktivitas bernama OnButtonClicked
. Handler ini terletak di file code-behind, BasicButtonClickPage.xaml.cs:
public partial class BasicButtonClickPage : ContentPage
{
public BasicButtonClickPage ()
{
InitializeComponent ();
}
async void OnButtonClicked(object sender, EventArgs args)
{
await label.RelRotateTo(360, 1000);
}
}
Ketika diketuk Button
, metode akan OnButtonClicked
dijalankan. Argumen sender
adalah objek yang Button
bertanggung jawab atas peristiwa ini. Anda dapat menggunakan ini untuk mengakses Button
objek, atau untuk membedakan antara beberapa Button
objek yang berbagi peristiwa yang sama Clicked
.
Handler khusus Clicked
ini memanggil fungsi animasi yang memutar Label
360 derajat dalam 1000 milidetik. Berikut adalah program yang berjalan di perangkat iOS dan Android, dan sebagai aplikasi Platform Windows Universal (UWP) di desktop Windows 10:
Perhatikan bahwa OnButtonClicked
metode menyertakan pengubah async
karena await
digunakan dalam penanganan aktivitas. Penanganan Clicked
aktivitas memerlukan pengubah async
hanya jika isi handler menggunakan await
.
Setiap platform merender dengan Button
cara spesifiknya sendiri. Di bagian Tampilan tombol, Anda akan melihat cara mengatur warna dan membuat Button
batas terlihat untuk tampilan yang lebih disesuaikan. Button
IFontElement
mengimplementasikan antarmuka, sehingga mencakup FontFamily
properti , FontSize
, dan FontAttributes
.
Membuat tombol dalam kode
Adalah umum untuk membuat instans Button
di XAML, tetapi Anda juga dapat membuat Button
dalam kode. Ini mungkin nyaman ketika aplikasi Anda perlu membuat beberapa tombol berdasarkan data yang dapat dihitung dengan perulangan foreach
.
Halaman Klik Tombol Kode menunjukkan cara membuat halaman yang secara fungsional setara dengan halaman Klik Tombol Dasar tetapi sepenuhnya di 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
}
};
}
}
Semuanya dilakukan di konstruktor kelas. Karena handler Clicked
hanya satu pernyataan panjang, itu dapat dilampirkan ke peristiwa dengan sangat sederhana:
button.Clicked += async (sender, args) => await label.RelRotateTo(360, 1000);
Tentu saja, Anda juga dapat menentukan penanganan aktivitas sebagai metode terpisah (sama seperti OnButtonClick
metode di Klik Tombol Dasar) dan melampirkan metode tersebut ke peristiwa:
button.Clicked += OnButtonClicked;
Menonaktifkan tombol
Terkadang aplikasi berada dalam status tertentu di mana klik tertentu Button
bukan operasi yang valid. Dalam kasus tersebut Button
, harus dinonaktifkan dengan mengatur propertinya IsEnabled
ke false
. Contoh klasik adalah Entry
kontrol untuk nama file yang disertai dengan file-open Button
: harus Button
diaktifkan hanya jika beberapa teks telah diketik ke Entry
dalam .
Anda bisa menggunakan untuk tugas ini, seperti yang DataTrigger
diperlihatkan dalam artikel Pemicu Data.
Menggunakan antarmuka perintah
Dimungkinkan bagi aplikasi untuk menanggapi ketukan Button
tanpa menangani Clicked
peristiwa. menerapkan Button
mekanisme pemberitahuan alternatif yang disebut perintah atau antarmuka perintah . Ini terdiri dari dua properti:
Command
jenisICommand
, antarmuka yang ditentukan dalamSystem.Windows.Input
namespace layanan.CommandParameter
properti jenisObject
.
Pendekatan ini sangat cocok sehubungan dengan pengikatan data, dan terutama saat menerapkan arsitektur Model-View-ViewModel (MVVM). Topik-topik ini dibahas dalam artikel Pengikatan Data, Dari Pengikatan Data ke MVVM, dan MVVM.
Dalam aplikasi MVVM, viewmodel menentukan properti jenis ICommand
yang kemudian terhubung ke elemen XAML Button
dengan pengikatan data. Xamarin.Forms juga mendefinisikan Command
kelas dan Command<T>
yang mengimplementasikan ICommand
antarmuka dan membantu viewmodel dalam menentukan properti jenis ICommand
.
Perintah dijelaskan secara lebih rinci dalam artikel Antarmuka Perintah tetapi halaman Perintah Tombol Dasar dalam sampel menunjukkan pendekatan dasar.
Kelas CommandDemoViewModel
ini adalah viewmodel yang sangat sederhana yang mendefinisikan properti jenis double
bernama Number
, dan dua properti jenis ICommand
bernama MultiplyBy2Command
dan 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; }
}
Dua ICommand
properti diinisialisasi dalam konstruktor kelas dengan dua objek jenis Command
. Konstruktor Command
menyertakan sedikit fungsi (disebut execute
argumen konstruktor) yang menggandakan atau memisahkan Number
properti.
File BasicButtonCommand.xaml mengaturnya BindingContext
ke instans CommandDemoViewModel
. Elemen Label
dan dua Button
elemen berisi pengikatan ke tiga properti di 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>
Saat dua Button
elemen diketuk, perintah dijalankan, dan nilai perubahan angka:
Keuntungan dari pendekatan ini daripada Clicked
handler adalah bahwa semua logika yang melibatkan fungsionalitas halaman ini terletak di viewmodel daripada file code-behind, mencapai pemisahan antarmuka pengguna yang lebih baik dari logika bisnis.
Dimungkinkan Command
juga bagi objek untuk mengontrol pengaktifan dan penonaktifan Button
elemen. Misalnya, Anda ingin membatasi rentang nilai angka antara 210 dan 2–10. Anda dapat menambahkan fungsi lain ke konstruktor (disebut canExecute
argumen) yang mengembalikan true
jika Button
harus diaktifkan. Berikut adalah modifikasi pada CommandDemoViewModel
konstruktor:
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));
}
···
}
Panggilan ke ChangeCanExecute
metode diperlukan sehingga Command
metode dapat memanggil canExecute
metode dan menentukan apakah Button
harus dinonaktifkan Command
atau tidak. Dengan perubahan kode ini, karena angka mencapai batas, dinonaktifkan Button
:
Dimungkinkan bagi dua elemen atau lebih Button
untuk terikat ke properti yang sama ICommand
. Elemen Button
dapat dibedakan menggunakan CommandParameter
properti .Button
Dalam hal ini, Anda harus menggunakan kelas generik Command<T>
. Objek CommandParameter
kemudian diteruskan sebagai argumen ke execute
metode dan canExecute
. Teknik ini ditampilkan secara rinci di bagian Perintah Dasar dari artikel Antarmuka Perintah.
Sampel juga menggunakan teknik ini di kelasnya MainPage
. File MainPage.xaml berisi Button
untuk setiap halaman sampel:
<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>
Masing-masing Button
memiliki properti yang Command
terikat ke properti bernama NavigateCommand
, dan CommandParameter
diatur ke objek yang Type
sesuai dengan salah satu kelas halaman dalam proyek.
Properti NavigateCommand
tersebut berjenis ICommand
dan didefinisikan dalam file code-behind:
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; }
}
Konstruktor menginisialisasi NavigateCommand
properti ke Command<Type>
objek karena Type
merupakan jenis objek yang CommandParameter
diatur dalam file XAML. Ini berarti bahwa execute
metode memiliki argumen jenis Type
yang sesuai dengan objek ini CommandParameter
. Fungsi membuat instans halaman lalu menavigasi ke halaman tersebut.
Perhatikan bahwa konstruktor menyimpulkan dengan mengaturnya BindingContext
ke dirinya sendiri. Ini diperlukan untuk properti dalam file XAML untuk mengikat ke NavigateCommand
properti .
Menekan dan melepaskan tombol
Clicked
Selain peristiwa, Button
juga menentukan Pressed
dan Released
peristiwa. Peristiwa Pressed
terjadi ketika jari menekan pada , atau tombol mouse ditekan Button
dengan penunjuk yang diposisikan di Button
atas . Peristiwa Released
terjadi ketika tombol jari atau mouse dilepaskan. Umumnya, Clicked
peristiwa juga diaktifkan pada saat yang sama dengan Released
peristiwa, tetapi jika jari atau penunjuk mouse menjauh dari permukaan Button
sebelum dilepaskan, Clicked
peristiwa mungkin tidak terjadi.
Peristiwa Pressed
dan Released
tidak sering digunakan, tetapi dapat digunakan untuk tujuan khusus, seperti yang ditunjukkan di halaman Tombol Tekan dan Rilis. File XAML berisi Label
dan Button
dengan handler yang dilampirkan untuk Pressed
peristiwa dan 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>
File code-behind menganimasikan Label
kapan peristiwa Pressed
terjadi, tetapi menangguhkan rotasi saat peristiwa Released
terjadi:
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();
}
}
Hasilnya adalah bahwa satu-satunya Label
berputar saat jari bersentuhan dengan Button
, dan berhenti ketika jari dilepaskan:
Perilaku semacam ini memiliki aplikasi untuk game: Jari yang Button
dipegang mungkin membuat objek di layar bergerak ke arah tertentu.
Tampilan tombol
Mewarisi Button
atau mendefinisikan beberapa properti yang memengaruhi penampilannya:
TextColor
adalah warnaButton
teksBackgroundColor
adalah warna latar belakang ke teks tersebutBorderColor
adalah warna area di sekitarButton
FontFamily
adalah keluarga fonta yang digunakan untuk teksFontSize
adalah ukuran teksFontAttributes
menunjukkan apakah teks miring atau tebalBorderWidth
adalah lebar batasCornerRadius
adalah radius sudutButton
CharacterSpacing
adalah penspasianButton
antara karakter teks.TextTransform
menentukan casingButton
teks.
Catatan
Kelas ini Button
juga memiliki Margin
properti dan Padding
yang mengontrol perilaku Button
tata letak . Untuk informasi selengkapnya, lihat Margin dan Padding.
Efek dari enam properti ini (tidak termasuk FontFamily
dan FontAttributes
) ditunjukkan di halaman Tampilan Tombol. Properti lain, Image
, dibahas di bagian Menggunakan bitmap dengan tombol .
Semua tampilan dan pengikatan data di halaman Tampilan Tombol ditentukan dalam file 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>
Di Button
bagian atas halaman memiliki tiga Color
properti yang terikat ke Picker
elemen di bagian bawah halaman. Item dalam Picker
elemen adalah warna dari kelas yang NamedColor
disertakan dalam proyek. Tiga Slider
elemen berisi pengikatan dua arah ke FontSize
properti , BorderWidth
, dan CornerRadius
dari Button
.
Program ini memungkinkan Anda untuk bereksperimen dengan kombinasi semua properti ini:
Untuk melihat Button
batas, Anda harus mengatur BorderColor
ke sesuatu selain Default
, dan ke BorderWidth
nilai positif.
Di iOS, Anda akan melihat bahwa lebar batas besar mengganggu interior Button
dan mengganggu tampilan teks. Jika Anda memilih untuk menggunakan batas dengan iOS Button
, Anda mungkin ingin memulai dan mengakhiri Text
properti dengan spasi untuk mempertahankan visibilitasnya.
Pada UWP, memilih CornerRadius
yang melebihi setengah tinggi dari Button
menimbulkan pengecualian.
Status visual tombol
Button
memiliki Pressed
VisualState
yang dapat digunakan untuk memulai perubahan visual ke Button
saat ditekan oleh pengguna, asalkan diaktifkan.
Contoh XAML berikut menunjukkan cara menentukan status visual untuk Pressed
status:
<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
Menentukan bahwa ketika Button
ditekan, propertinya Scale
akan diubah dari nilai defaultnya 1 menjadi 0,8. Normal
VisualState
Menentukan bahwa ketika Button
berada dalam keadaan normal, propertinya Scale
akan diatur ke 1. Oleh karena itu, efek keseluruhannya adalah ketika Button
ditekan, skalanya akan sedikit lebih kecil, dan ketika Button
dirilis, skalanya akan diskalakan ulang ke ukuran defaultnya.
Untuk informasi selengkapnya tentang status visual, lihat Xamarin.Forms Visual State Manager.
Membuat tombol alih
Dimungkinkan untuk subkelas Button
sehingga berfungsi seperti tombol on-off: Ketuk tombol sekali untuk mengaktifkan tombol dan mengetuknya lagi untuk mematikannya.
Kelas berikut ToggleButton
berasal dari Button
dan mendefinisikan peristiwa baru bernama Toggled
dan properti Boolean bernama IsToggled
. Ini adalah dua properti yang sama yang ditentukan oleh 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
Konstruktor melampirkan handler ke Clicked
peristiwa sehingga dapat mengubah nilai IsToggled
properti. Metode ini OnIsToggledChanged
menembakkan Toggled
peristiwa.
Baris OnIsToggledChanged
terakhir metode memanggil metode statis VisualStateManager.GoToState
dengan dua string teks "ToggledOn" dan "ToggledOff". Anda dapat membaca tentang metode ini dan bagaimana aplikasi Anda dapat merespons status visual dalam artikel Manajer Xamarin.Forms Status Visual.
Karena ToggleButton
melakukan panggilan ke VisualStateManager.GoToState
, kelas itu sendiri tidak perlu menyertakan fasilitas tambahan untuk mengubah tampilan tombol berdasarkan keadaannya IsToggled
. Itulah tanggung jawab XAML yang menghosting ToggleButton
.
Halaman Demo Tombol Alih berisi dua instans ToggleButton
, termasuk markup Visual State Manager yang mengatur Text
, BackgroundColor
, dan TextColor
tombol berdasarkan status visual:
<?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>
Penanganan Toggled
aktivitas berada dalam file code-behind. Mereka bertanggung jawab untuk mengatur FontAttributes
properti Label
berdasarkan status tombol:
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;
}
}
}
Berikut adalah program yang berjalan di iOS, Android, dan UWP:
Menggunakan bitmap dengan tombol
Kelas Button
menentukan ImageSource
properti yang memungkinkan Anda menampilkan gambar bitmap pada Button
, baik sendiri atau dalam kombinasi dengan teks. Anda juga dapat menentukan bagaimana teks dan gambar disusun.
Properti ImageSource
berjenis ImageSource
, yang berarti bahwa bitmap dapat dimuat dari file, sumber daya tersemat, URI, atau aliran.
Catatan
Button
Meskipun dapat memuat GIF animasi, itu hanya akan menampilkan bingkai pertama GIF.
Setiap platform yang didukung oleh Xamarin.Forms memungkinkan gambar disimpan dalam beberapa ukuran untuk resolusi piksel yang berbeda dari berbagai perangkat yang mungkin dijalankan aplikasi. Beberapa bitmap ini diberi nama atau disimpan sedih sehingga sistem operasi dapat memilih kecocokan terbaik untuk resolusi tampilan video perangkat.
Untuk bitmap pada Button
, ukuran terbaik biasanya antara 32 dan 64 unit independen perangkat, tergantung pada seberapa besar Anda menginginkannya. Gambar yang digunakan dalam contoh ini didasarkan pada ukuran 48 unit independen perangkat.
Dalam proyek iOS, folder Sumber Daya berisi tiga ukuran gambar ini:
- Bitmap persegi 48 piksel disimpan sebagai /Resources/MonkeyFace.png
- Bitmap persegi 96 piksel disimpan sebagai /Resource/MonkeyFace@2x.png
- Bitmap persegi 144 piksel disimpan sebagai /Resource/MonkeyFace@3x.png
Ketiga bitmap diberikan Build Action of BundleResource.
Untuk proyek Android, bitmap semuanya memiliki nama yang sama, tetapi disimpan di subfolder folder Sumber Daya yang berbeda:
- Bitmap persegi 72 piksel disimpan sebagai /Resources/drawable-hdpi/MonkeyFace.png
- Bitmap persegi 96 piksel disimpan sebagai /Resources/drawable-xhdpi/MonkeyFace.png
- Bitmap persegi 144 piksel disimpan sebagai /Resources/drawable-xxhdpi/MonkeyFace.png
- Bitmap persegi 192 piksel disimpan sebagai /Resources/drawable-xxxhdpi/MonkeyFace.png
Ini diberikan Tindakan Build AndroidResource.
Dalam proyek UWP, bitmap dapat disimpan di mana saja dalam proyek, tetapi umumnya disimpan dalam folder kustom atau folder Aset yang ada. Proyek UWP berisi bitmap ini:
- Bitmap persegi 48 piksel disimpan sebagai /Aset/MonkeyFace.scale-100.png
- Bitmap persegi 96 piksel disimpan sebagai /Aset/MonkeyFace.scale-200.png
- Bitmap persegi 192 piksel disimpan sebagai /Aset/MonkeyFace.scale-400.png
Mereka semua diberi Tindakan Build Konten.
Anda dapat menentukan bagaimana Text
properti dan ImageSource
diatur pada Button
menggunakan ContentLayout
properti .Button
Properti ini berjenis ButtonContentLayout
, yang merupakan kelas tersemat di Button
. Konstruktor memiliki dua argumen:
- Anggota
ImagePosition
enumerasi:Left
, ,Right
Top
, atauBottom
menunjukkan bagaimana bitmap muncul relatif terhadap teks. - Nilai
double
untuk penspasian antara bitmap dan teks.
Defaultnya adalah Left
dan 10 unit. Dua properti baca-saja bernama ButtonContentLayout
Position
dan Spacing
menyediakan nilai properti tersebut.
Dalam kode, Anda dapat membuat Button
dan mengatur ContentLayout
properti seperti ini:
Button button = new Button
{
Text = "button text",
ImageSource = new FileImageSource
{
File = "image filename"
},
ContentLayout = new Button.ButtonContentLayout(Button.ButtonContentLayout.ImagePosition.Right, 20)
};
Di XAML, Anda hanya perlu menentukan anggota enumerasi, atau penspasian, atau keduanya dalam urutan apa pun yang dipisahkan oleh koma:
<Button Text="button text"
ImageSource="image filename"
ContentLayout="Right, 20" />
Halaman Demo Tombol Gambar menggunakan OnPlatform
untuk menentukan nama file yang berbeda untuk file bitmap iOS, Android, dan UWP. Jika Anda ingin menggunakan nama file yang sama untuk setiap platform dan menghindari penggunaan OnPlatform
, Anda harus menyimpan bitmap UWP di direktori akar proyek.
Yang pertama Button
pada halaman Demo Tombol Gambar mengatur Image
properti tetapi bukan Text
properti :
<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>
Jika bitmap UWP disimpan di direktori akar proyek, markup ini dapat sangat disederhanakan:
<Button ImageSource="MonkeyFace.png" />
Untuk menghindari banyak markup berulang dalam file ImageButtonDemo.xaml , implisit Style
juga didefinisikan untuk mengatur ImageSource
properti. Ini Style
secara otomatis diterapkan ke lima elemen lainnya Button
. Berikut adalah file XAML lengkap:
<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>
Empat Button
elemen terakhir menggunakan ContentLayout
properti untuk menentukan posisi dan penspasian teks dan bitmap:
Anda sekarang telah melihat berbagai cara untuk menangani Button
peristiwa dan mengubah Button
penampilan.