Xamarin.Forms Manajer Status Visual
Gunakan Visual State Manager untuk membuat perubahan pada elemen XAML berdasarkan status visual yang diatur dari kode.
Visual State Manager (VSM) menyediakan cara terstruktur untuk membuat perubahan visual pada antarmuka pengguna dari kode. Dalam kebanyakan kasus, antarmuka pengguna aplikasi didefinisikan dalam XAML, dan XAML ini mencakup markup yang menjelaskan bagaimana Visual State Manager memengaruhi visual antarmuka pengguna.
VSM memperkenalkan konsep status visual. Xamarin.Forms Tampilan seperti Button
dapat memiliki beberapa tampilan visual yang berbeda tergantung pada status mendasarnya — baik dinonaktifkan, atau ditekan, atau memiliki fokus input. Ini adalah status tombol.
Status visual dikumpulkan dalam grup status visual. Semua status visual dalam grup status visual saling eksklusif. Status visual dan grup status visual diidentifikasi oleh string teks sederhana.
Xamarin.Forms Visual State Manager menentukan satu grup status visual bernama "CommonStates" dengan status visual berikut:
- "Normal"
- "Dinonaktifkan"
- "Terfokus"
- "Dipilih"
Grup status visual ini didukung untuk semua kelas yang berasal dari VisualElement
, yang merupakan kelas dasar untuk View
dan Page
.
Anda juga dapat menentukan grup status visual dan status visual Anda sendiri, karena artikel ini akan ditunjukkan.
Catatan
Xamarin.Forms pengembang yang terbiasa dengan pemicu menyadari bahwa pemicu juga dapat membuat perubahan pada visual di antarmuka pengguna berdasarkan perubahan properti tampilan atau penembakan peristiwa. Namun, menggunakan pemicu untuk menangani berbagai kombinasi perubahan ini bisa menjadi cukup membingungkan. Secara historis, Visual State Manager diperkenalkan di lingkungan berbasis Windows XAML untuk meringankan kebingungan yang dihasilkan dari kombinasi status visual. Dengan VSM, status visual dalam grup status visual selalu saling eksklusif. Kapan saja, hanya satu status di setiap grup yang merupakan status saat ini.
Status umum
Visual State Manager memungkinkan Anda menyertakan markup dalam file XAML yang dapat mengubah tampilan visual tampilan jika tampilan normal, atau dinonaktifkan, atau memiliki fokus input. Ini dikenal sebagai keadaan umum.
Misalnya, Anda memiliki Entry
tampilan di halaman Anda, dan Anda ingin tampilan Entry
visual berubah dengan cara berikut:
Entry
harus memiliki latar belakang merah muda ketika dinonaktifkanEntry
.- Seharusnya
Entry
memiliki latar belakang kapur secara normal. Entry
harus meluas ke dua kali tinggi normalnya ketika memiliki fokus input.
Anda dapat melampirkan markup VSM ke tampilan individual, atau Anda dapat menentukannya dalam gaya jika berlaku untuk beberapa tampilan. Dua bagian berikutnya menjelaskan pendekatan ini.
Markup VSM pada tampilan
Untuk melampirkan markup VSM ke Entry
tampilan, pertama-tama Entry
pisahkan menjadi tag mulai dan akhir:
<Entry FontSize="18">
</Entry>
Ini diberi ukuran font eksplisit karena salah satu status akan menggunakan FontSize
properti untuk menggandakan ukuran teks dalam Entry
.
Selanjutnya, sisipkan VisualStateManager.VisualStateGroups
tag di antara tag tersebut:
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
</VisualStateManager.VisualStateGroups>
</Entry>
VisualStateGroups
adalah properti yang dapat diikat terlampir yang ditentukan oleh VisualStateManager
kelas . (Untuk informasi selengkapnya tentang properti yang dapat diikat terlampir, lihat artikel Properti terlampir.) Ini adalah bagaimana VisualStateGroups
properti dilampirkan ke Entry
objek.
Properti VisualStateGroups
berjenis VisualStateGroupList
, yang merupakan kumpulan VisualStateGroup
objek. VisualStateManager.VisualStateGroups
Dalam tag, sisipkan sepasang VisualStateGroup
tag untuk setiap grup status visual yang ingin Anda sertakan:
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>
Perhatikan bahwa VisualStateGroup
tag memiliki atribut yang x:Name
menunjukkan nama grup. Kelas VisualStateGroup
menentukan Name
properti yang dapat Anda gunakan sebagai gantinya:
<VisualStateGroup Name="CommonStates">
Anda dapat menggunakan salah satu x:Name
atau Name
tetapi tidak keduanya dalam elemen yang sama.
Kelas VisualStateGroup
mendefinisikan properti bernama States
, yang merupakan kumpulan VisualState
objek. States
adalah properti VisualStateGroups
konten sehingga Anda dapat menyertakan VisualState
tag langsung di VisualStateGroup
antara tag. (Properti konten dibahas dalam artikel Sintaks XAML Penting.)
Langkah selanjutnya adalah menyertakan sepasang tag untuk setiap status visual dalam grup tersebut. Ini juga dapat diidentifikasi menggunakan x:Name
atau Name
:
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
</VisualState>
<VisualState x:Name="Focused">
</VisualState>
<VisualState x:Name="Disabled">
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>
VisualState
mendefinisikan properti bernama Setters
, yang merupakan kumpulan Setter
objek. Ini adalah objek yang sama Setter
dengan yang Anda gunakan dalam Style
objek.
Setters
bukan properti konten , VisualState
sehingga perlu untuk menyertakan tag elemen properti untuk Setters
properti:
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Focused">
<VisualState.Setters>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>
Anda sekarang dapat menyisipkan satu atau beberapa Setter
objek di antara setiap pasangan Setters
tag. Ini adalah Setter
objek yang menentukan status visual yang dijelaskan sebelumnya:
<Entry FontSize="18">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Entry>
Setiap Setter
tag menunjukkan nilai properti tertentu ketika status tersebut saat ini. Properti apa pun yang Setter
direferensikan oleh objek harus didukung oleh properti yang dapat diikat.
Markup yang mirip dengan ini adalah dasar dari halaman VSM on View dalam program sampel. Halaman ini menyertakan tiga Entry
tampilan, tetapi hanya yang kedua yang memiliki markup VSM yang melekat padanya:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:VsmDemos"
x:Class="VsmDemos.MainPage"
Title="VSM Demos">
<StackLayout>
<StackLayout.Resources>
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
</Style>
<Style TargetType="Label">
<Setter Property="Margin" Value="20, 30, 20, 0" />
<Setter Property="FontSize" Value="Large" />
</Style>
</StackLayout.Resources>
<Label Text="Normal Entry:" />
<Entry />
<Label Text="Entry with VSM: " />
<Entry>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Entry.Triggers>
<DataTrigger TargetType="Entry"
Binding="{Binding Source={x:Reference entry3},
Path=Text.Length}"
Value="0">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Entry.Triggers>
</Entry>
<Label Text="Entry to enable 2nd Entry:" />
<Entry x:Name="entry3"
Text=""
Placeholder="Type something to enable 2nd Entry" />
</StackLayout>
</ContentPage>
Perhatikan bahwa yang kedua Entry
juga memiliki DataTrigger
sebagai bagian dari koleksinya Trigger
. Ini menyebabkan dinonaktifkan Entry
sampai sesuatu ditik ke ketiga Entry
. Berikut adalah halaman saat startup berjalan di iOS, Android, dan Platform Windows Universal (UWP):
Status visual saat ini adalah "Dinonaktifkan" sehingga latar belakang yang kedua Entry
berwarna merah muda di layar iOS dan Android. Implementasi Entry
UWP tidak memungkinkan pengaturan warna latar belakang ketika dinonaktifkan Entry
.
Ketika Anda memasukkan beberapa teks ke ketiga Entry
, kedua Entry
beralih ke status "Normal", dan latar belakang sekarang kapur:
Ketika Anda menyentuh yang kedua Entry
, itu mendapatkan fokus input. Ini beralih ke status "Terfokus" dan meluas ke dua kali tingginya:
Perhatikan bahwa Entry
tidak mempertahankan latar belakang kapur ketika mendapatkan fokus input. Saat Visual State Manager beralih di antara status visual, properti yang diatur oleh status sebelumnya tidak diatur. Perlu diingat bahwa status visual saling eksklusif. Status "Normal" tidak berarti hanya diaktifkan Entry
. Ini berarti bahwa Entry
diaktifkan dan tidak memiliki fokus input.
Jika Anda ingin Entry
memiliki latar belakang kapur dalam status "Terfokus", tambahkan yang lain Setter
ke status visual tersebut:
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
Agar objek ini Setter
berfungsi dengan baik, harus VisualStateGroup
berisi VisualState
objek untuk semua status dalam grup tersebut. Jika ada status visual yang tidak memiliki objek apa pun Setter
, sertakan sebagai tag kosong:
<VisualState x:Name="Normal" />
Markup Manajer Status Visual dalam gaya
Seringkali perlu untuk berbagi markup Visual State Manager yang sama di antara dua tampilan atau lebih. Dalam hal ini, Anda harus meletakkan markup dalam Style
definisi.
Berikut implisit Style
yang ada untuk Entry
elemen di halaman VSM On View :
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
</Style>
Tambahkan Setter
tag untuk VisualStateManager.VisualStateGroups
properti yang dapat dilampirkan:
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
</Setter>
</Style>
Properti konten untuk Setter
adalah Value
, sehingga nilai Value
properti dapat ditentukan langsung dalam tag tersebut. Properti tersebut berjenis VisualStateGroupList
:
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
</VisualStateGroupList>
</Setter>
</Style>
Dalam tag tersebut, Anda dapat menyertakan salah satu objek lainnya VisualStateGroup
:
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
Sisa markup VSM sama seperti sebelumnya.
Berikut adalah halaman VSM dalam Gaya yang memperlihatkan markup VSM lengkap:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="VsmDemos.VsmInStylePage"
Title="VSM in Style">
<StackLayout>
<StackLayout.Resources>
<Style TargetType="Entry">
<Setter Property="Margin" Value="20, 0" />
<Setter Property="FontSize" Value="18" />
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Focused">
<VisualState.Setters>
<Setter Property="FontSize" Value="36" />
<Setter Property="BackgroundColor" Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Disabled">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="Pink" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
<Style TargetType="Label">
<Setter Property="Margin" Value="20, 30, 20, 0" />
<Setter Property="FontSize" Value="Large" />
</Style>
</StackLayout.Resources>
<Label Text="Normal Entry:" />
<Entry />
<Label Text="Entry with VSM: " />
<Entry>
<Entry.Triggers>
<DataTrigger TargetType="Entry"
Binding="{Binding Source={x:Reference entry3},
Path=Text.Length}"
Value="0">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Entry.Triggers>
</Entry>
<Label Text="Entry to enable 2nd Entry:" />
<Entry x:Name="entry3"
Text=""
Placeholder="Type something to enable 2nd Entry" />
</StackLayout>
</ContentPage>
Sekarang semua Entry
tampilan di halaman ini merespons cara yang sama dengan status visual mereka. Perhatikan juga bahwa status "Berfokus" sekarang mencakup detik Setter
yang memberikan setiap Entry
latar belakang kapur juga ketika memiliki fokus input:
Status visual dalam Xamarin.Forms
Tabel berikut mencantumkan status visual yang ditentukan dalam Xamarin.Forms:
Kelas | Status | Informasi Selengkapnya |
---|---|---|
Button |
Pressed |
Status visual tombol |
CheckBox |
IsChecked |
Status visual Kotak Centang |
CarouselView |
DefaultItem , , CurrentItem PreviousItem ,NextItem |
Status visual CarouselView |
ImageButton |
Pressed |
Status visual ImageButton |
RadioButton |
Checked , Unchecked |
Status visual RadioButton |
Switch |
On , Off |
Mengalihkan status visual |
VisualElement |
Normal , , Disabled Focused ,Selected |
Status umum |
Masing-masing status ini dapat diakses melalui grup status visual bernama CommonStates
.
Selain itu, mengimplementasikan CollectionView
Selected
status. Untuk informasi selengkapnya, lihat Mengubah warna item yang dipilih.
Mengatur status pada beberapa elemen
Dalam contoh sebelumnya, status visual dilampirkan dan dioperasikan pada elemen tunggal. Namun, dimungkinkan juga untuk membuat status visual yang dilampirkan ke satu elemen, tetapi yang mengatur properti pada elemen lain dalam cakupan yang sama. Ini menghindari harus mengulangi status visual pada setiap elemen yang dioperasikan oleh status.
Jenis Setter
memiliki TargetName
properti, jenis string
, yang mewakili elemen target yang akan dimanipulasi Setter
untuk status visual. TargetName
Ketika properti didefinisikan, Setter
set Property
elemen yang ditentukan menjadi TargetName
Value
:
<Setter TargetName="label"
Property="Label.TextColor"
Value="Red" />
Dalam contoh ini, nama Label
label
akan memiliki propertinya TextColor
yang diatur ke Red
. Saat mengatur TargetName
properti, Anda harus menentukan jalur lengkap ke properti di Property
. Oleh karena itu, untuk mengatur TextColor
properti pada Label
, Property
ditentukan sebagai Label.TextColor
.
Catatan
Properti apa pun yang Setter
direferensikan oleh objek harus didukung oleh properti yang dapat diikat.
Halaman VSM dengan Setter TargetName dalam sampel menunjukkan cara mengatur status pada beberapa elemen, dari satu grup status visual. File XAML terdiri dari elemen yang StackLayout
Label
berisi, Entry
, dan :Button
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="VsmDemos.VsmSetterTargetNamePage"
Title="VSM with Setter TargetName">
<StackLayout Margin="10">
<Label Text="What is the capital of France?" />
<Entry x:Name="entry"
Placeholder="Enter answer" />
<Button Text="Reveal answer">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Property="Scale"
Value="0.8" />
<Setter TargetName="entry"
Property="Entry.Text"
Value="Paris" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Button>
</StackLayout>
</ContentPage>
Markup VSM dilampirkan ke StackLayout
. Ada dua status yang saling eksklusif, bernama "Normal" dan "Ditekan", dengan setiap status berisi VisualState
tag.
Status "Normal" aktif saat Button
tidak ditekan, dan respons terhadap pertanyaan dapat dimasukkan:
Status "Ditekan" menjadi aktif saat ditekan Button
:
"Ditekan" VisualState
menentukan bahwa ketika Button
ditekan, propertinya Scale
akan diubah dari nilai default 1 menjadi 0,8. Selain itu, yang Entry
bernama entry
akan memiliki propertinya Text
diatur ke Paris. Oleh karena itu, hasilnya adalah bahwa ketika Button
ditekan, diskalakan ulang menjadi sedikit lebih kecil, dan Entry
menampilkan Paris. Kemudian, ketika Button
dirilis, itu diskalakan ulang ke nilai default 1, dan Entry
menampilkan teks yang dimasukkan sebelumnya.
Penting
Jalur properti saat ini tidak didukung dalam Setter
elemen yang menentukan TargetName
properti .
Tentukan status visual Anda sendiri
Setiap kelas yang berasal dari VisualElement
mendukung status umum "Normal", "Fokus", dan "Dinonaktifkan". Selain itu, CollectionView
kelas mendukung status "Dipilih". Secara internal, VisualElement
kelas mendeteksi kapan kelas diaktifkan atau dinonaktifkan, atau berfokus atau tidak fokus, dan memanggil metode statis VisualStateManager.GoToState
:
VisualStateManager.GoToState(this, "Focused");
Ini adalah satu-satunya kode Visual State Manager yang akan Anda temukan di VisualElement
kelas . Karena GoToState
dipanggil untuk setiap objek berdasarkan setiap kelas yang berasal dari VisualElement
, Anda dapat menggunakan Visual State Manager dengan objek apa pun VisualElement
untuk menanggapi perubahan ini.
Menariknya, nama grup status visual "CommonStates" tidak secara eksplisit dirujuk dalam VisualElement
. Nama grup bukan bagian dari API untuk Visual State Manager. Dalam salah satu dari dua program sampel yang ditampilkan sejauh ini, Anda dapat mengubah nama grup dari "CommonStates" menjadi hal lain, dan program masih akan berfungsi. Nama grup hanyalah deskripsi umum tentang status dalam grup tersebut. Secara implisit dipahami bahwa status visual dalam grup mana pun saling eksklusif: Satu status dan hanya satu status saat ini kapan saja.
Jika Anda ingin menerapkan status visual Anda sendiri, Anda harus memanggil VisualStateManager.GoToState
dari kode. Paling sering Anda akan melakukan panggilan ini dari file code-behind dari kelas halaman Anda.
Halaman Validasi VSM dalam sampel menunjukkan cara menggunakan Visual State Manager sehubungan dengan validasi input. File XAML terdiri dari StackLayout
dua Label
elemen, Entry
, dan :Button
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="VsmDemos.VsmValidationPage"
Title="VSM Validation">
<StackLayout x:Name="stackLayout"
Padding="10, 10">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="ValidityStates">
<VisualState Name="Valid">
<VisualState.Setters>
<Setter TargetName="helpLabel"
Property="Label.TextColor"
Value="Transparent" />
<Setter TargetName="entry"
Property="Entry.BackgroundColor"
Value="Lime" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Invalid">
<VisualState.Setters>
<Setter TargetName="entry"
Property="Entry.BackgroundColor"
Value="Pink" />
<Setter TargetName="submitButton"
Property="Button.IsEnabled"
Value="False" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Label Text="Enter a U.S. phone number:"
FontSize="Large" />
<Entry x:Name="entry"
Placeholder="555-555-5555"
FontSize="Large"
Margin="30, 0, 0, 0"
TextChanged="OnTextChanged" />
<Label x:Name="helpLabel"
Text="Phone number must be of the form 555-555-5555, and not begin with a 0 or 1" />
<Button x:Name="submitButton"
Text="Submit"
FontSize="Large"
Margin="0, 20"
VerticalOptions="Center"
HorizontalOptions="Center" />
</StackLayout>
</ContentPage>
Markup VSM dilampirkan ke StackLayout
(bernama stackLayout
). Ada dua status yang saling eksklusif, bernama "Valid" dan "Invalid", dengan setiap status berisi VisualState
tag.
Entry
Jika tidak berisi nomor telepon yang valid, maka status saat ini adalah "Tidak Valid", sehingga Entry
memiliki latar belakang merah muda, yang kedua Label
terlihat, dan dinonaktifkanButton
:
Ketika nomor telepon yang valid dimasukkan, maka status saat ini menjadi "Valid". mendapatkan Entry
latar belakang kapur, yang kedua Label
menghilang, dan Button
sekarang diaktifkan:
File code-behind bertanggung jawab untuk menangani TextChanged
peristiwa dari Entry
. Handler menggunakan ekspresi reguler untuk menentukan apakah string input valid atau tidak. Metode dalam file code-behind bernama GoToState
memanggil metode statis VisualStateManager.GoToState
untuk stackLayout
:
public partial class VsmValidationPage : ContentPage
{
public VsmValidationPage()
{
InitializeComponent();
GoToState(false);
}
void OnTextChanged(object sender, TextChangedEventArgs args)
{
bool isValid = Regex.IsMatch(args.NewTextValue, @"^[2-9]\d{2}-\d{3}-\d{4}$");
GoToState(isValid);
}
void GoToState(bool isValid)
{
string visualState = isValid ? "Valid" : "Invalid";
VisualStateManager.GoToState(stackLayout, visualState);
}
}
Perhatikan juga bahwa metode dipanggil GoToState
dari konstruktor untuk menginisialisasi status. Harus selalu ada status saat ini. Tetapi di mana pun dalam kode ada referensi ke nama grup status visual, meskipun dirujuk dalam XAML sebagai "ValidationStates" untuk tujuan kejelasan.
Perhatikan bahwa file code-behind hanya perlu memperhitungkan objek pada halaman yang menentukan status visual, dan untuk memanggil VisualStateManager.GoToState
objek ini. Ini karena kedua status visual menargetkan beberapa objek di halaman.
Anda mungkin bertanya-tanya: Jika file code-behind harus mereferensikan objek di halaman yang menentukan status visual, mengapa file code-behind tidak dapat mengakses ini dan objek lainnya secara langsung? Pasti bisa. Namun, keuntungan menggunakan VSM adalah Anda dapat mengontrol bagaimana elemen visual bereaksi terhadap status yang berbeda sepenuhnya di XAML, yang menyimpan semua desain UI di satu lokasi. Ini menghindari pengaturan tampilan visual dengan mengakses elemen visual langsung dari kode di belakang.
Pemicu status visual
Status visual mendukung pemicu status, yang merupakan grup pemicu khusus yang menentukan kondisi di mana VisualState
harus diterapkan.
Pemicu status ditambahkan ke StateTriggers
kumpulan VisualState
. Koleksi ini dapat berisi pemicu status tunggal, atau beberapa pemicu status. VisualState
Akan diterapkan ketika setiap pemicu status dalam koleksi aktif.
Saat menggunakan pemicu status untuk mengontrol status visual, Xamarin.Forms menggunakan aturan prioritas berikut untuk menentukan pemicu mana (dan yang VisualState
sesuai ) yang akan aktif:
- Pemicu apa pun yang berasal dari
StateTriggerBase
. - Diaktifkan
AdaptiveTrigger
karena kondisi terpenuhiMinWindowWidth
. - Diaktifkan
AdaptiveTrigger
karena kondisi terpenuhiMinWindowHeight
.
Jika beberapa pemicu aktif secara bersamaan (misalnya, dua pemicu kustom) maka pemicu pertama yang dideklarasikan dalam markup lebih diutamakan.
Untuk informasi selengkapnya tentang pemicu status, lihat Pemicu status.
Menggunakan Visual State Manager untuk tata letak adaptif
Aplikasi Xamarin.Forms yang berjalan di ponsel biasanya dapat dilihat dalam rasio aspek potret atau lanskap, dan program yang Xamarin.Forms berjalan di desktop dapat diubah ukurannya untuk mengasumsikan banyak ukuran dan rasio aspek yang berbeda. Aplikasi yang dirancang dengan baik mungkin menampilkan kontennya secara berbeda untuk berbagai faktor bentuk halaman atau jendela ini.
Teknik ini terkadang dikenal sebagai tata letak adaptif. Karena tata letak adaptif hanya melibatkan visual program, ini adalah aplikasi ideal dari Visual State Manager.
Contoh sederhana adalah aplikasi yang menampilkan kumpulan kecil tombol yang memengaruhi konten aplikasi. Dalam mode potret, tombol-tombol ini mungkin ditampilkan dalam baris horizontal di bagian atas halaman:
Dalam mode lanskap, array tombol mungkin dipindahkan ke satu sisi, dan ditampilkan dalam kolom:
Dari atas ke bawah, program berjalan di Platform Windows Universal, Android, dan iOS.
Halaman Tata Letak Adaptif VSM dalam sampel menentukan grup bernama "OrientationStates" dengan dua status visual bernama "Portrait" dan "Landscape". (Pendekatan yang lebih kompleks mungkin didasarkan pada beberapa halaman atau lebar jendela yang berbeda.)
Markup VSM terjadi di empat tempat dalam file XAML. Nama StackLayout
mainStack
berisi menu dan konten, yang merupakan Image
elemen. Ini StackLayout
harus memiliki orientasi vertikal dalam mode potret dan orientasi horizontal dalam mode lanskap:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="VsmDemos.VsmAdaptiveLayoutPage"
Title="VSM Adaptive Layout">
<StackLayout x:Name="mainStack">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="OrientationStates">
<VisualState Name="Portrait">
<VisualState.Setters>
<Setter Property="Orientation" Value="Vertical" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Landscape">
<VisualState.Setters>
<Setter Property="Orientation" Value="Horizontal" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ScrollView x:Name="menuScroll">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="OrientationStates">
<VisualState Name="Portrait">
<VisualState.Setters>
<Setter Property="Orientation" Value="Horizontal" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Landscape">
<VisualState.Setters>
<Setter Property="Orientation" Value="Vertical" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<StackLayout x:Name="menuStack">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="OrientationStates">
<VisualState Name="Portrait">
<VisualState.Setters>
<Setter Property="Orientation" Value="Horizontal" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Landscape">
<VisualState.Setters>
<Setter Property="Orientation" Value="Vertical" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<StackLayout.Resources>
<Style TargetType="Button">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup Name="OrientationStates">
<VisualState Name="Portrait">
<VisualState.Setters>
<Setter Property="HorizontalOptions" Value="CenterAndExpand" />
<Setter Property="Margin" Value="10, 5" />
</VisualState.Setters>
</VisualState>
<VisualState Name="Landscape">
<VisualState.Setters>
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="Margin" Value="10" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</StackLayout.Resources>
<Button Text="Banana"
Command="{Binding SelectedCommand}"
CommandParameter="Banana.jpg" />
<Button Text="Face Palm"
Command="{Binding SelectedCommand}"
CommandParameter="FacePalm.jpg" />
<Button Text="Monkey"
Command="{Binding SelectedCommand}"
CommandParameter="monkey.png" />
<Button Text="Seated Monkey"
Command="{Binding SelectedCommand}"
CommandParameter="SeatedMonkey.jpg" />
</StackLayout>
</ScrollView>
<Image x:Name="image"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand" />
</StackLayout>
</ContentPage>
Bagian dalam ScrollView
bernama menuScroll
dan yang StackLayout
bernama menuStack
mengimplementasikan menu tombol. Orientasi tata letak ini berlawanan dengan mainStack
. Menu harus horizontal dalam mode potret dan vertikal dalam mode lanskap.
Bagian keempat markup VSM berada dalam gaya implisit untuk tombol itu sendiri. Markup ini menetapkan VerticalOptions
properti , HorizontalOptions
, dan Margin
khusus untuk orientasi potret dan lanskap.
File code-behind mengatur BindingContext
properti untuk menuStack
mengimplementasikan Button
perintah, dan juga melampirkan handler ke SizeChanged
peristiwa halaman:
public partial class VsmAdaptiveLayoutPage : ContentPage
{
public VsmAdaptiveLayoutPage ()
{
InitializeComponent ();
SizeChanged += (sender, args) =>
{
string visualState = Width > Height ? "Landscape" : "Portrait";
VisualStateManager.GoToState(mainStack, visualState);
VisualStateManager.GoToState(menuScroll, visualState);
VisualStateManager.GoToState(menuStack, visualState);
foreach (View child in menuStack.Children)
{
VisualStateManager.GoToState(child, visualState);
}
};
SelectedCommand = new Command<string>((filename) =>
{
image.Source = ImageSource.FromResource("VsmDemos.Images." + filename);
});
menuStack.BindingContext = this;
}
public ICommand SelectedCommand { private set; get; }
}
Handler SizeChanged
memanggil VisualStateManager.GoToState
dua StackLayout
elemen dan ScrollView
, dan kemudian mengulangi anak-anak menuStack
untuk Button
memanggil VisualStateManager.GoToState
elemen.
Tampaknya seolah-olah file code-behind dapat menangani perubahan orientasi lebih langsung dengan mengatur properti elemen dalam file XAML, tetapi Visual State Manager jelas merupakan pendekatan yang lebih terstruktur. Semua visual disimpan dalam file XAML, di mana mereka menjadi lebih mudah untuk memeriksa, memelihara, dan memodifikasi.
Visual State Manager dengan Xamarin.University
Xamarin.Forms Video 3.0 Visual State Manager