Bagikan melalui


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

Settersbukan properti konten , VisualStatesehingga 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):

VSM pada Tampilan: Dinonaktifkan

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:

VSM pada Tampilan: Normal

Ketika Anda menyentuh yang kedua Entry, itu mendapatkan fokus input. Ini beralih ke status "Terfokus" dan meluas ke dua kali tingginya:

VSM pada Tampilan: Berfokus

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:

VSM dalam Gaya

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, , CurrentItemPreviousItem,NextItem Status visual CarouselView
ImageButton Pressed Status visual ImageButton
RadioButton Checked, Unchecked Status visual RadioButton
Switch On, Off Mengalihkan status visual
VisualElement Normal, , DisabledFocused,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:

VSM Setter TargetName: Status Normal

Status "Ditekan" menjadi aktif saat ditekan Button :

VSM Setter TargetName: Status Ditekan

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

Validasi VSM: Status Tidak Valid

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:

Validasi VSM: Status Valid

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 VisualStatesesuai ) yang akan aktif:

  1. Pemicu apa pun yang berasal dari StateTriggerBase.
  2. Diaktifkan AdaptiveTrigger karena kondisi terpenuhi MinWindowWidth .
  3. Diaktifkan AdaptiveTrigger karena kondisi terpenuhi MinWindowHeight .

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:

Tata Letak Adaptif VSM: Potret

Dalam mode lanskap, array tombol mungkin dipindahkan ke satu sisi, dan ditampilkan dalam kolom:

Tata Letak Adaptif VSM: Lanskap

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