Xamarin.Forms Visual State Manager

Koddan ayarlanan görsel durumlarına göre XAML öğelerinde değişiklik yapmak için Visual State Manager'ı kullanın.

Visual State Manager (VSM), koddan kullanıcı arabiriminde görsel değişiklikler yapmak için yapılandırılmış bir yol sağlar. Çoğu durumda, uygulamanın kullanıcı arabirimi XAML'de tanımlanır ve bu XAML, Visual State Manager'ın kullanıcı arabiriminin görsellerini nasıl etkilediğini açıklayan işaretlemeleri içerir.

VSM, görsel durum kavramını tanıtır. Xamarin.Forms gibi bir Button görünüm, temel alınan durumuna bağlı olarak birkaç farklı görsel görünüme sahip olabilir ( devre dışı bırakılmış veya basılmış veya giriş odağına sahip olabilir). Bunlar düğmenin durumlarıdır.

Görsel durumlar görsel durum gruplarında toplanır. Görsel durum grubundaki tüm görsel durumlar birbirini dışlar. Hem görsel durumlar hem de görsel durum grupları basit metin dizeleriyle tanımlanır.

Xamarin.Forms Visual State Manager, "CommonStates" adlı bir görsel durum grubunu aşağıdaki görsel durumlarıyla tanımlar:

  • "Normal"
  • "Devre dışı"
  • "Odaklanmış"
  • "Seçili"

Bu görsel durum grubu, ve Pageiçin temel sınıf olan öğesinden VisualElementtüretilen tüm sınıflar için View desteklenir.

Bu makalede gösterildiği gibi kendi görsel durum gruplarınızı ve görsel durumlarınızı da tanımlayabilirsiniz.

Not

Xamarin.Formstetikleyicileri bilen geliştiriciler, tetikleyicilerin görünümün özelliklerindeki değişikliklere veya olayların tetiklenmelerine bağlı olarak kullanıcı arabirimindeki görsellerde de değişiklik yapabileceklerini bilir. Ancak, tetikleyicileri kullanarak bu değişikliklerin çeşitli birleşimleriyle başa çıkmak oldukça kafa karıştırıcı olabilir. Geçmişte Visual State Manager, görsel durum bileşimlerinden kaynaklanan karışıklığı azaltmak için Windows XAML tabanlı ortamlarda kullanıma sunulmuştur. VSM ile görsel durum grubu içindeki görsel durumlar her zaman birbirini dışlar. Her zaman, her grupta yalnızca bir durum geçerli durumdur.

Ortak durumlar

Visual State Manager, XAML dosyanıza, görünüm normal veya devre dışıysa veya giriş odağına sahipse görünümün görünümünü değiştirebilecek işaretlemeler eklemenize olanak tanır. Bunlar ortak durumlar olarak bilinir.

Örneğin, sayfanızda bir Entry görünüm olduğunu ve öğesinin görsel görünümünün Entry aşağıdaki yollarla değişmesini istediğinizi varsayalım:

  • Entry devre dışı bırakıldığında Entry , pembe bir arka plana sahip olmalıdır.
  • Normalde Entry kireç arka planına sahip olmalıdır.
  • Entry giriş odağı olduğunda normal yüksekliğinin iki katına genişletilmelidir.

VSM işaretlemesini tek bir görünüme ekleyebilir veya birden çok görünüm için geçerliyse bir stilde tanımlayabilirsiniz. Sonraki iki bölümde bu yaklaşımlar açıklanmaktadır.

Görünümde VSM işaretlemesi

Görünüme VSM işaretlemesi eklemek için Entry önce başlangıç ve bitiş etiketlerini Entry birbirinden ayırın:

<Entry FontSize="18">

</Entry>

Durumlardan biri içindeki metnin Entryboyutunu iki katına getirmek için özelliğini kullanacağındanFontSize, bu boyuta açık bir yazı tipi boyutu verilir.

Ardından, bu etiketlerin arasına etiketler ekleyin VisualStateManager.VisualStateGroups :

<Entry FontSize="18">
    <VisualStateManager.VisualStateGroups>

    </VisualStateManager.VisualStateGroups>
</Entry>

VisualStateGroups , sınıfı tarafından VisualStateManager tanımlanan ekli bir bağlanabilir özelliktir. (Ekli bağlanabilir özellikler hakkında daha fazla bilgi için makaleye bakınEkli özellikler.) Özelliği nesneye VisualStateGroupsEntry bu şekilde eklenir.

VisualStateGroups özelliği, nesne koleksiyonu VisualStateGroup olan türündedirVisualStateGroupList. Etiketlerin içine VisualStateManager.VisualStateGroups , eklemek istediğiniz her görsel durum grubu için bir çift VisualStateGroup etiket ekleyin:

<Entry FontSize="18">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="CommonStates">

        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Entry>

Etiketin VisualStateGroup , grubun adını gösteren bir x:Name özniteliği olduğuna dikkat edin. sınıfı bunun VisualStateGroup yerine kullanabileceğiniz bir Name özellik tanımlar:

<VisualStateGroup Name="CommonStates">

Aynı öğede ikisini birden x:Name veya Name her ikisini birden kullanabilirsiniz.

VisualStateGroup sınıfı, bir nesne koleksiyonu VisualState olan adlı Statesbir özellik tanımlar. States, etiketleri doğrudan etiketler arasına ekleyebilmeniz VisualState için öğesinin VisualStateGroup içerik özelliğidirVisualStateGroups. (İçerik özellikleri makalede ele alınıyorTemel XAML Sözdizimi.)

Sonraki adım, söz konusu gruptaki her görsel durum için bir çift etiket eklemektir. Bunlar veya Namekullanılarak x:Name da tanımlanabilir:

<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, adlı bir nesne koleksiyonu Setter olan bir özelliği Setterstanımlar. Bunlar, Setter bir Style nesnede kullandığınız nesnelerdir.

Settersöğesinin içerik özelliği VisualStateolmadığından özelliği için özellik öğesi etiketlerinin Setters eklenmesi gerekir:

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

Artık her etiket çiftinin Setters arasına bir veya daha fazla Setter nesne ekleyebilirsiniz. Bunlar, daha önce açıklanan görsel durumları tanımlayan nesnelerdir Setter :

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

Her Setter etiket, bu durum geçerli olduğunda belirli bir özelliğin değerini gösterir. Bir nesne tarafından başvurulan herhangi bir Setter özellik, bağlanabilir bir özellik tarafından yedeklenmelidir.

Buna benzer işaretleme, örnek programdaki Görünüm sayfasındaki VSM'nin temelini oluşturur. Sayfada üç Entry görünüm bulunur, ancak yalnızca ikincisinde VSM işaretlemesi eklenir:

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

İkincisinde Entry de koleksiyonunun bir DataTrigger parçası Trigger olduğuna dikkat edin. Bu, üçüncü Entryöğesine bir şey yazılana kadar öğesinin devre dışı bırakılmasına neden olurEntry. iOS, Android ve Evrensel Windows Platformu (UWP) üzerinde çalışan başlangıçtaki sayfa aşağıdadır:

Görünümde VSM: Devre Dışı

Geçerli görsel durumu "Devre dışı" olduğundan, ikincinin Entry arka planı iOS ve Android ekranlarında pembe olur. UWP uygulaması Entry , devre dışı bırakıldığında arka plan renginin ayarlanmasına Entry izin vermez.

Üçüncüye Entrybir metin girdiğinizde, ikinci Entry "Normal" durumuna geçer ve arka plan şimdi kireç olur:

Görünümde VSM: Normal

İkincisine Entrydokunduğunuzda, giriş odağı elde eder. "Odaklanmış" durumuna geçer ve yüksekliğinin iki katına genişletir:

Görünümde VSM: Odaklanmış

Entry giriş odağını aldığında kireç arka planını tutmadığını fark edin. Visual State Manager görsel durumları arasında geçiş yaparken, önceki duruma göre ayarlanan özellikler ayarlanmamış olur. Görsel durumların birbirini dışladığını unutmayın. "Normal" durumu yalnızca öğesinin Entry etkinleştirildiği anlamına gelmez. Bu, Entry etkin olduğu ve giriş odağının olmadığı anlamına gelir.

öğesinin Entry "Odaklanmış" durumda bir kireç arka planı olmasını istiyorsanız, bu görsel duruma bir tane daha Setter ekleyin:

<VisualState x:Name="Focused">
    <VisualState.Setters>
        <Setter Property="FontSize" Value="36" />
        <Setter Property="BackgroundColor" Value="Lime" />
    </VisualState.Setters>
</VisualState>

Bu Setter nesnelerin düzgün çalışması için, bir VisualStateGroup gruptaki tüm durumlara yönelik nesneler içermelidir VisualState . Herhangi Setter bir nesnesi olmayan bir görsel durum varsa, yine de boş etiket olarak ekleyin:

<VisualState x:Name="Normal" />

Stilde Visual State Manager işaretlemesi

Aynı Visual State Manager işaretlemesinin iki veya daha fazla görünüm arasında paylaşılması genellikle gereklidir. Bu durumda, işaretlemeyi bir Style tanıma koymak istersiniz.

Görünümde VSM sayfasındaki öğeler için Entry var olan örtük Style öğe aşağıdadır:

<Style TargetType="Entry">
    <Setter Property="Margin" Value="20, 0" />
    <Setter Property="FontSize" Value="18" />
</Style>

Ekli bağlanabilir özellik için VisualStateManager.VisualStateGroups etiketler ekleyinSetter:

<Style TargetType="Entry">
    <Setter Property="Margin" Value="20, 0" />
    <Setter Property="FontSize" Value="18" />
    <Setter Property="VisualStateManager.VisualStateGroups">

    </Setter>
</Style>

için Setter içerik özelliği şeklindedir Value, bu nedenle özelliğin Value değeri doğrudan bu etiketler içinde belirtilebilir. Bu özellik türündedir VisualStateGroupList:

<Style TargetType="Entry">
    <Setter Property="Margin" Value="20, 0" />
    <Setter Property="FontSize" Value="18" />
    <Setter Property="VisualStateManager.VisualStateGroups">
        <VisualStateGroupList>

        </VisualStateGroupList>
    </Setter>
</Style>

Bu etiketlere daha fazla VisualStateGroup nesneden birini ekleyebilirsiniz:

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

VSM işaretlemesinin geri kalanı öncekiyle aynıdır.

Tam VSM işaretlemesini gösteren Stildeki VSM sayfası aşağıdadır:

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

Artık bu sayfadaki tüm Entry görünümler görsel durumlarına aynı şekilde yanıt veriyor. "Odaklanmış" durumunun artık giriş odağı olduğunda da her Entry bir kireç arka planı sağlayan bir saniye Setter içerdiğine dikkat edin:

Stilde VSM

içindeki görsel durumlar Xamarin.Forms

Aşağıdaki tabloda, içinde Xamarin.Formstanımlanan görsel durumları listelenmiştir:

Sınıf Durumlar Daha Fazla Bilgi
Button Pressed Düğme görsel durumları
CheckBox IsChecked CheckBox görsel durumları
CarouselView DefaultItem, CurrentItem, PreviousItem, NextItem CarouselView görsel durumları
ImageButton Pressed ImageButton görsel durumları
RadioButton Checked, Unchecked RadioButton görsel durumları
Switch On, Off Görsel durumlarını değiştirme
VisualElement Normal, Disabled, Focused, Selected Ortak durumlar

Bu durumların her birine adlı CommonStatesgörsel durum grubu aracılığıyla erişilebilir.

Buna ek olarak, CollectionView durumu uygular Selected . Daha fazla bilgi için bkz . Seçili öğe rengini değiştirme.

Birden çok öğede durumu ayarlama

Önceki örneklerde görsel durumlar tek öğelere eklenmiş ve üzerinde çalıştırılmıştır. Bununla birlikte, tek bir öğeye eklenmiş ancak aynı kapsamdaki diğer öğelerde özellikleri ayarlayan görsel durumlar oluşturmak da mümkündür. Bu, durumların üzerinde çalıştığı her öğede görsel durumları yinelemek zorunda kalmamasını sağlar.

türündeSetter, görsel durumunun işleyecek hedef öğesini Setter temsil eden türünde stringbir özelliği vardırTargetName. TargetName özelliği tanımlandığında, Setter öğesinde TargetName tanımlanan öğesini olarak ValueayarlarProperty:

<Setter TargetName="label"
        Property="Label.TextColor"
        Value="Red" />

Bu örnekte, adlandırılmış bir Label ada label ait TextColor özelliği olarak Redayarlanır. Özelliği ayarlarken TargetName içindeki özelliğin Propertytam yolunu belirtmeniz gerekir. Bu nedenle, üzerinde LabelProperty özelliğini ayarlamak TextColor için olarak Label.TextColorbelirtilir.

Not

Bir nesne tarafından başvurulan herhangi bir Setter özellik, bağlanabilir bir özellik tarafından yedeklenmelidir.

Örnekteki Setter TargetName ile VSM sayfası, tek bir görsel durum grubundan birden çok öğede durumun nasıl ayarlandığını gösterir. XAML dosyası bir öğesi, bir StackLayoutLabel ve içeren bir EntryButtoniçerir:

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

VSM işaretlemesi öğesine StackLayouteklenir. "Normal" ve "Pressed" adlı iki birbirini dışlayan durum vardır ve her durum etiket içerir VisualState .

"Normal" durumu, tuşuna basılmadığında Button etkindir ve soruya yanıt girilebilir:

VSM Ayarlayıcısı Hedef Adı: Normal Durum

"Basıldı" durumu, tuşuna Button basıldığında etkin hale gelir:

VSM Ayarlayıcısı Hedef Adı: Basılan Durum

"Basıldı" VisualState ayarına basıldığında Button özelliğinin Scale varsayılan değer olan 1'den 0,8'e değiştirileceğini belirtir. Buna ek olarak, Entry adlandırılmış entryText özelliği Paris olarak ayarlanır. Bu nedenle, sonuç tuşuna basıldığında Button biraz daha küçük olacak şekilde yeniden ölçeklendirilir ve Paris'i Entry görüntüler. Ardından, serbest bırakıldığında Button varsayılan değeri 1 olarak yeniden ölçeklendirilir ve Entry daha önce girilen tüm metinler görüntülenir.

Önemli

Özelliği belirten TargetName öğelerde Setter özellik yolları şu anda desteklenmiyor.

Kendi görsel durumlarınızı tanımlama

öğesinden VisualElement türetilen her sınıf "Normal", "Odaklanmış" ve "Devre Dışı" ortak durumlarını destekler. Buna ek olarak, CollectionView sınıfı "Selected" durumunu destekler. Dahili olarak, VisualElement sınıf etkinleştirildiğinde veya devre dışı bırakıldığında ya da odaklanmış veya odaklanmadığında algılar ve statik VisualStateManager.GoToState yöntemi çağırır:

VisualStateManager.GoToState(this, "Focused");

Bu, sınıfında bulabileceğiniz tek Visual State Manager kodudur VisualElement . öğesinden GoToState türetilen her sınıfı temel alan her nesne için çağrıldığından VisualElement, bu değişikliklere yanıt vermek için Visual State Manager'ı herhangi bir VisualElement nesneyle birlikte kullanabilirsiniz.

İlginç bir şekilde, "CommonStates" görsel durum grubunun adına açıkça VisualElementbaşvurulmuyor. Grup adı, Visual State Manager API'sinin bir parçası değildir. Şu ana kadar gösterilen iki örnek programdan birinde, grubun adını "CommonStates" yerine başka bir şeyle değiştirebilirsiniz ve program çalışmaya devam eder. Grup adı yalnızca bu gruptaki durumların genel bir açıklamasıdır. Herhangi bir gruptaki görsel durumların birbirini dışlayıcı olduğu örtük olarak anlaşılmaktadır: Herhangi bir anda bir durum ve yalnızca bir durum geçerli olur.

Kendi görsel durumlarınızı uygulamak istiyorsanız koddan çağırmanız VisualStateManager.GoToState gerekir. Çoğu zaman bu çağrıyı sayfa sınıfınızın arka planda kod dosyasından yaparsınız.

Örnekteki VSM Doğrulama sayfasında, giriş doğrulamasıyla bağlantılı olarak Visual State Manager'ın nasıl kullanılacağı gösterilir. XAML dosyası, bir ve Buttonolmak üzere iki Label öğeden EntryoluşurStackLayout:

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

VSM işaretlemesi öğesine (adlı) stackLayouteklenir StackLayout . "Geçerli" ve "Geçersiz" adlı iki birbirini dışlayan durum vardır ve her durum etiket içerir VisualState .

Entry geçerli bir telefon numarası içermiyorsa, geçerli durum "Geçersiz" olur ve bu nedenle Entry pembe bir arka plana sahiptir, ikincisi Label görünür ve Button devre dışı bırakılır:

VSM Doğrulaması: Geçersiz Durum

Geçerli bir telefon numarası girildiğinde geçerli durum "Geçerli" olur. Entry bir kireç arka planı alır, ikincisi Label kaybolur ve Button şimdi etkinleştirilir:

VSM Doğrulaması: Geçerli Durum

Arka planda kod dosyası, olayını dosyasından TextChanged işlemekten Entrysorumludur. İşleyici, giriş dizesinin geçerli olup olmadığını belirlemek için normal bir ifade kullanır. adlı GoToState arka planda kod dosyasındaki yöntemi için stackLayoutstatik VisualStateManager.GoToState yöntemi çağırır:

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

Ayrıca, durumu başlatmak için oluşturucudan yönteminin çağrıldığına da GoToState dikkat edin. Her zaman geçerli bir durum olmalıdır. Ancak kodun hiçbir yerinde görsel durum grubunun adına herhangi bir başvuru yoktur, ancak netlik amacıyla XAML'de "ValidationStates" olarak başvurulur.

Arka planda kod dosyasının yalnızca görsel durumlarını tanımlayan sayfadaki nesneyi hesaba eklemesi ve bu nesneyi çağırması VisualStateManager.GoToState gerektiğini unutmayın. Bunun nedeni, her iki görsel durumu da sayfadaki birden çok nesneyi hedeflemesidir.

Merak edebilirsiniz: Arka planda kod dosyasının görsel durumlarını tanımlayan sayfadaki nesneye başvurması gerekiyorsa, neden arka planda kod dosyası bu ve diğer nesnelere doğrudan erişemiyor? Kesinlikle olabilir. Ancak VSM kullanmanın avantajı, tüm kullanıcı arabirimi tasarımını tek bir konumda tutan XAML'de görsel öğelerin farklı duruma nasıl tepki vermelerini denetleyebilmenizdir. Bu, görsel öğelere doğrudan arka planda koddan erişerek görsel görünümü ayarlamayı önler.

Görsel durum tetikleyicileri

Görsel durumlar, geçerli olması gereken koşulları tanımlayan özel bir tetikleyici grubu olan VisualState durum tetikleyicilerini destekler.

Durum tetikleyicileri bir VisualStatekoleksiyonuna StateTriggers eklenir. Bu koleksiyon tek bir durum tetikleyicisi veya birden çok durum tetikleyicisi içerebilir. VisualState Bir, koleksiyondaki durum tetikleyicileri etkin olduğunda uygulanır.

Görsel durumları denetlemek için durum tetikleyicileri kullanılırken, Xamarin.Forms hangi tetikleyicinin (ve karşılık gelen VisualState) etkin olacağını belirlemek için aşağıdaki öncelik kurallarını kullanır:

  1. 'den StateTriggerBasetüretilen tüm tetikleyiciler.
  2. AdaptiveTrigger Koşul karşılandığından MinWindowWidth etkinleştirildi.
  3. AdaptiveTrigger Koşul karşılandığından MinWindowHeight etkinleştirildi.

Birden çok tetikleyici aynı anda etkinse (örneğin, iki özel tetikleyici), işaretlemede bildirilen ilk tetikleyici önceliklidir.

Durum tetikleyicileri hakkında daha fazla bilgi için bkz . Durum tetikleyicileri.

Uyarlamalı düzen için Visual State Manager'i kullanma

Xamarin.Forms Telefonda çalışan bir uygulama genellikle dikey veya yatay en boy oranında görüntülenebilir ve masaüstünde çalışan bir Xamarin.Forms program birçok farklı boyut ve en boy oranı varsayılacak şekilde yeniden boyutlandırılabilir. İyi tasarlanmış bir uygulama, içeriğini bu çeşitli sayfa veya pencere formu faktörleri için farklı görüntüleyebilir.

Bu teknik bazen uyarlamalı düzen olarak bilinir. Uyarlamalı düzen yalnızca bir programın görsellerini içerdiğinden, Visual State Manager'ın ideal bir uygulamasıdır.

Basit bir örnek, uygulamanın içeriğini etkileyen küçük bir düğme koleksiyonu görüntüleyen bir uygulamadır. Dikey modda, bu düğmeler sayfanın üst kısmındaki yatay bir satırda görüntülenebilir:

VSM Uyarlamalı Düzeni: Dikey

Yatay modda, düğme dizisi bir tarafa taşınabilir ve bir sütunda görüntülenebilir:

VSM Uyarlamalı Düzeni: Yatay

Yukarıdan aşağıya, program Evrensel Windows Platformu, Android ve iOS üzerinde çalışıyor.

Örnekteki VSM Uyarlamalı Düzen sayfası, "OrientationStates" adlı ve "Dikey" ve "Yatay" adlı iki görsel durumu olan bir grup tanımlar. (Daha karmaşık bir yaklaşım birkaç farklı sayfa veya pencere genişliğine dayalı olabilir.)

VSM işaretlemesi XAML dosyasında dört yerde gerçekleşir. Adlandırılmış StackLayoutmainStack , hem menüyü hem de bir Image öğe olan içeriği içerir. Bunun StackLayout dikey modda dikey yönlendirmesi ve yatay modda yatay yönlendirmesi olmalıdır:

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

İç ScrollView adlı menuScroll ve StackLayout adlandırılmış menuStack düğme menüsünü uygular. Bu düzenlerin yönü ile tam tersidir mainStack. Menü dikey modda yatay ve yatay modda dikey olmalıdır.

VSM işaretlemesinin dördüncü bölümü, düğmelerin kendileri için örtük bir stildedir. Bu işaretleme, dikey ve Margin yatay yönlendirmelere özgü , HorizontalOptionsve özelliklerini ayarlarVerticalOptions.

Arka planda kod dosyası komutunu uygulamak Button için özelliğini menuStack ayarlar BindingContext ve ayrıca sayfanın olayına SizeChanged bir işleyici ekler:

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

İşleyiciSizeChanged, iki StackLayout ve ScrollView öğelerini çağırır VisualStateManager.GoToState ve öğeleri çağırmak VisualStateManager.GoToState için öğesinin menuStack alt öğeleri arasında döngüler Button oluşturur.

Arka planda kod dosyası, XAML dosyasındaki öğelerin özelliklerini ayarlayarak yönlendirme değişikliklerini daha doğrudan işleyebilir gibi görünebilir, ancak Visual State Manager kesinlikle daha yapılandırılmış bir yaklaşımdır. Tüm görseller, incelenmesi, bakımı ve değiştirilmesinin daha kolay hale geldiği XAML dosyasında tutulur.

Xamarin.University ile Visual State Manager

Xamarin.Forms 3.0 Visual State Manager videosu