Xamarin.Forms Visual State Manager

Örneği İndir Örneği indirme

Koddan ayarlanmış 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şaretlemeyi içerir.

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

Görsel durumları, görsel durum gruplarında toplanır. Bir görsel durum grubu içindeki tüm görsel durumları birbirini dışlar. Hem görsel durumları hem de görsel durum grupları basit metin dizeleri tarafından tanımlanır.

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

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

Bu görsel durum grubu, ve için temel sınıf olan 'den VisualElement türeten tüm sınıflar için View de desteklemektedir. Page

Ayrıca, bu makalede de gösterecek şekilde kendi görsel durum gruplarınızı ve görsel durumlarınızı tanımlayabilirsiniz.

Not

Xamarin.Forms Tetikleyicilere Xamarin.Forms geliştiriciler, tetikleyicilerin bir görünümün özelliklerinde yapılan değişikliklere veya olayların tetiklenene göre kullanıcı arabiriminde görsellerde de değişiklik yapabilirsiniz. Ancak, bu değişikliklerin çeşitli birleşimleriyle başa olmak için tetikleyicilerin kullanımı kafa karıştırıcı olabilir. Geçmişte Görsel Durum Yöneticisi, görsel durum Windows karışıklığı hafifletmek için XAML tabanlı ortamlarda tanıtıldı. VSM ile, bir görsel durum grubu içindeki görsel durumları her zaman birbirini dışlar. Herhangi bir anda, her grupta yalnızca bir durum geçerli durum olur.

Ortak eyaletler

Visual State Manager, XAML dosyanıza işaretlemeyi dahil etmek için görünümün normal veya devre dışı olması veya giriş odağı olması durumunun görünümün görsel görünümünü değiştirmesini sağlar. Bunlar yaygın durumları olarak bilinir.

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

  • devre Entry dışı bırakılmıştır, pembe bir arka Entry plan olması gerekir.
  • normalde Entry arka plan arka planına sahip olması gerekir.
  • , Entry giriş odağına sahip olduğunda normal yüksekliğinin iki katına genişlemesi gerekir.

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

Görünümde VSM işaretlemesi

Bir görünüme VSM işaretlemesi Entry eklemek için önce başlangıç ve bitiş Entry etiketlerine ayırabilirsiniz:

<Entry FontSize="18">

</Entry>

Açık bir yazı tipi boyutu verilir çünkü eyaletlerden biri özelliği kullanarak içinde metnin boyutunu iki FontSize katına Entry çıkar.

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

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

    </VisualStateManager.VisualStateGroups>
</Entry>

VisualStateGroups , sınıfı tarafından tanımlanan bağlı bir bağlanabilir VisualStateManager özelliktir. (Ekli bağlanabilir özellikler hakkında daha fazla bilgi için Ekli özellikler makalesine bakın.) Özelliğin VisualStateGroups nesnesine bu şekilde Entry ekli olduğu.

VisualStateGroupsözelliği, nesne VisualStateGroupList koleksiyonu olan VisualStateGroup türündedir. Etiketlerin VisualStateManager.VisualStateGroups içine, eklemek istediğiniz VisualStateGroup her görsel durumları grubu için bir etiket çifti ekleyin:

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

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

VisualStateGroupEtiketin, grubun adını belirten bir x:Name özniteliğine sahip olduğunu farkedin. sınıfı, VisualStateGroup bunun Name yerine kullanabileceğiniz bir özelliği tanımlar:

<VisualStateGroup Name="CommonStates">

Aynı öğede x:Name ya Name da kullanabilirsiniz ancak ikisini birden kullanabilirsiniz.

sınıfı, VisualStateGroup bir nesne koleksiyonu olan Xamarin_Forms VisualStateGroup _VisualStateGroup_States" data-linktype="absolute-path">adlı bir özelliği StatesVisualState tanımlar. States , StatesVisualStateGroups etiketlerin arasına dahil etmek için içerik VisualStateVisualStateGroup özelliğidir. (İçerik özellikleri Temel XAML Söz Dizimi makalesinde ele alınmıştır.)

Sonraki adım, bu gruptaki her görsel durumu için bir etiket çifti eklemektir. Bunlar ayrıca veya kullanılarak da x:Name belirlen Name olabilir:

<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, bir nesne koleksiyonu olan Xamarin_Forms VisualState _VisualState_Setters" data-linktype="absolute-path">Setters adlı bir özelliği Setter tanımlar. Bunlar, bir Setter nesnesinde kullanmakta olduğu Style nesnelerdir.

Setters , Setters içerik özelliği VisualState değildir, bu nedenle özelliği için özellik öğesi etiketlerini dahil etmek Setters 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 çifti arasına Setter bir veya daha fazla nesne Setters ebilirsiniz. Bunlar daha Setter önce açıklanan görsel durumları tanımlayan nesnelerdir:

<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, durum geçerli olduğunda belirli bir özelliğin değerini gösterir. Bir nesne tarafından başvurulan Setter herhangi bir özellik, bağlanabilir bir özellik tarafından desteklenebilir.

Buna benzer işaretleme, VsmDemos örnek programının Görünüm sayfasında VSM'nin temelini sağlar. Sayfada üç görünüm Entry vardır ancak yalnızca ikinci görünümde VSM işaretlemesi ekli olur:

<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 de Entry koleksiyonunun bir DataTrigger parçası olarak yer alan bir Trigger vardır. Bu, üçüncü Entry türüne bir şey yazana kadar devre dışı bırakılabilir. Entry iOS, Android ve Universal Windows Platform'da (UWP) çalışan başlangıçtaki sayfa:

Görünümde VSM: Görünümde

Geçerli görsel durumu "Devre Dışı" olduğu için iOS ve Android ekranlarında ikincinin Entry arka planı pembedir. 'nin UWP Entry uygulaması devre dışı bırakılmıştır, arka plan renginin Entry ayarına izin vermez.

Üçüncüye bir metin Entry girerken, ikinci Entry "Normal" durumuna geçiş eder ve arka plan şu anda şöyle olur:

Görünümde VSM: Görünümde Normal VSM

İkinciye dokunduğunda Entry giriş odağı olur. "Odaklanmış" durumuna geçiş yaptı ve yüksekliğinin iki katına çıktı:

Görünümde VSM: Görünüme

giriş Entry odağında arka planı korumaz. Görsel Durum Yöneticisi, görsel durumları arasında geçişe geçerek önceki durum tarafından ayarlanmış olan özelliklerin ayarlanmamış olduğunu gösterir. Görsel durumları birbirini dışlar. "Normal" durumu yalnızca etkin olduğu Entry anlamına gelir. Bu, etkin Entry olduğu ve giriş odağına sahip olmadığını gösterir.

"Odaklanmış" durumda bir arka plan arka planına sahip olmak Entry için bu görsel Setter durumuna bir tane daha ekleyin:

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

Bu nesnelerin düzgün Setter çalışması için, bu VisualStateGroup gruptaki VisualState tüm eyaletler için nesneleri içermesi gerekir. Nesne içeren bir görsel durumu yoksa boş Setter bir etiket olarak ekleyin:

<VisualState x:Name="Normal" />

Stilde Visual State Manager işaretlemesi

Genellikle aynı Visual State Manager kar payını iki veya daha fazla görünüm arasında paylaşmak gerekir. Bu durumda işaretlemeyi bir tanıma koymak Style gerekir.

VsM Görünüm sayfasındaki Style öğeler Entry için mevcut örtülü Style

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

Bağlı Setter bağlanabilir özellik için etiketler VisualStateManager.VisualStateGroups ekleyin:

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

    </Setter>
</Style>

için içerik SetterValue özelliğidir, bu nedenle Value özelliğin değeri doğrudan bu etiketlerin içinde belirtilebilir. Bu özellik VisualStateGroupList türündedir:

<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 nesne VisualStateGroup dahil edin:

<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şaretlemenin geri kalanı öncekiyle aynıdır.

Tam VSM işaretlemeyi gösteren Stilde VSM sayfası şu şekildedir:

<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 Entry sayfada yer alan tüm görünümler, görsel durumlarına aynı şekilde yanıt verir. "Odaklanmış" durumunun artık giriş odağı olduğunda her biri için bir arka plan veren bir saniyeyi SetterEntry de içerir:

Stil VSM'de VSM

içinde görsel durumları Xamarin.Forms

Aşağıdaki tabloda, içinde tanımlanan görsel durumları Xamarin.Forms listele:

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ı değiştirme
VisualElement Normal, Disabled, Focused, Selected Ortak eyaletler

Bu durumların her biri adlı görsel durum grubu aracılığıyla CommonStates erişilebilir.

Ayrıca, CollectionView durumu da Selected uygulanır. 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 ekli ve bu öğeler üzerinde çalıştırmıştı. Ancak, tek bir öğeye eklenmiş olan ancak aynı kapsam içindeki diğer öğelerde özellikleri ayaran görsel durumları oluşturmak da mümkündür. Bu durum, durumların üzerinde çalışılması gereken her öğede görsel durumları yinelemek zorunda kalmamak için kullanılır.

SetterTürün, TargetName görsel durumu için string işleyecek hedef öğeyi temsil Setter eden türünde bir özelliği vardır. özelliği TargetName tanımlandığı zaman, Setter içinde tanımlanan Property öğesinin öğesini olarak TargetNameValue ayarlar:

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

Bu örnekte, adlandırılmış Label bir label değerin özelliği TextColor olarak Red ayarlanmıştır. özelliğini TargetName ayarlarken özelliğin tam yolunu içinde belirtmeniz Property gerekir. Bu nedenle, üzerinde TextColor özelliğini ayarlamak için olarak LabelPropertyLabel.TextColor belirtilir.

Not

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

VsmDemosörneğinde Setter TargetName içeren VSM sayfası, tek bir görsel durum grubundan birden çok öğede durum ayarlamayı gösterir. XAML dosyası bir StackLayout öğesi, bir ve Label içeren bir EntryButton oluşur:

<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, 'ye StackLayout ekli. Her durumu etiket içeren "Normal" ve "Basılmış" adlı birbirini dışlar iki durum VisualState vardır.

"Normal" durumu, Button basıldığında etkindir ve soruya bir yanıt girilebilir:

VSM Ayarıcı Hedef Adı: Normal Durum

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

VSM Setter TargetName: Basıldı Durum

"Pressed" VisualState değerine basıldığında özelliğinin varsayılan değer olan ButtonScale 1'den 0,8'e değiştir olacağını belirtir. Buna ek olarak, Entry adlı entry değerin özelliği Text Paris olarak ayarlanmıştır. Bu nedenle, basıldığında biraz daha küçük olacak şekilde yeniden ölçeklenmiş ve Paris görüntülenmiş ButtonEntry olur. Ardından, serbest Button bırakıldıklarında varsayılan değeri olan 1'e yeniden ölçekler ve daha Entry önce girilen tüm metinleri görüntüler.

Önemli

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

Kendi görsel durumları tanımlama

'den türeten her VisualElement sınıf "Normal", "Focused" ve "Disabled" ortak durumlarını destekler. Buna ek olarak, CollectionView sınıfı "Seçili" durumunu destekler. Dahili olarak, Xamarin.Forms /blob/master/ Xamarin.Forms . Core/VisualElement.cs" data-linktype="external">sınıfı etkinleştirildiğinde veya devre dışı olduğunda ya da odaklanmış ya da odaklanmamış olduğunu algılar ve VisualElement statik Xamarin_Forms _VisualStateManager_GoToState_ Xamarin.FormsXamarin_Forms _VisualElement_System_String_" data-linktype="absolute-path">VisualStateManager.GoToState yöntemini çağırıyor:

VisualStateManager.GoToState(this, "Focused");

Bu, sınıfında buluna tek Visual State Manager VisualElement kodudur. , 'den türetilen her sınıfa göre her nesne için çağrıldıklarından, bu değişikliklere yanıt vermek için herhangi bir nesneyle GoToStateVisualElement Visual State Manager VisualElement kullanabilirsiniz.

İlginç olan, "CommonStates" görsel durum grubunun adına açıkça içinde VisualElement başvurulmamasıdır. Grup adı, Visual State Manager IÇIN API'nin bir parçası değildir. Şu ana kadar gösterilen iki örnek programdan birinin içinde grubun adını "CommonStates" olarak değiştirebilirsiniz ve program çalışmaya devam eder. Grup adı yalnızca o gruptaki eyaletlerin genel bir açıklamasıdır. Herhangi bir gruptaki görsel durumların birbirini dışladığını örtülü olarak anlaşılabilir: Herhangi bir anda bir durum ve yalnızca bir durum geçerli olur.

Kendi görsel durumları uygulamak için koddan VisualStateManager.GoToState çağırmanız gerekir. Çoğu zaman bu çağrıyı sayfa sınıfınızda arka arkasındaki kod dosyasından yapacaktır.

VsmDemos örneğinin VSM Doğrulama sayfası, giriş doğrulamasıyla bağlantılı olarak Visual State Manager'ın nasıl kullanıcağnı gösterir. XAML dosyası , ve StackLayout olmak için iki öğe içeren bir LabelEntry dosyadan Button oluşur:

<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 ,'ye StackLayout ekli stackLayout (adlandırılmıştır). Her durumu etiket içeren "Valid" ve "Invalid" adlı birbirini dışlar iki durum VisualState vardır.

geçerli bir telefon numarası içermezse geçerli durum "Geçersiz" olur ve bu nedenle pembe arka plan, ikinci görünür ve devre EntryEntry dışı LabelButton bırakılır:

VSM Doğrulaması: Geçersiz Durum

Geçerli bir telefon numarası girilirse geçerli durum "Geçerli" olur. Entryarka planı alır, ikincisi Label kaybolur ve artık Button etkindir:

VSM Doğrulaması: Geçerli Durum

Arka kod dosyası, dosyasından olayı TextChanged işlemeden Entry sorumludur. İşleyici, giriş dizesinin geçerli olup olmadığını belirlemek için bir normal ifade kullanır. adlı arka kod dosyasındaki yöntemi GoToState için statik VisualStateManager.GoToState yöntemini stackLayout ç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 GoToState için yönteminin oluşturucudan çağrılmış olduğunu da fark edersiniz. Her zaman geçerli bir durum olması gerekir. Ancak, netlik sağlamak amacıyla XAML'de "ValidationStates" olarak başvurulsa da kodda görsel durum grubunun adına herhangi bir başvuru vardır.

Arka arkasındaki kod dosyasının yalnızca görsel durumları tanımlayan sayfada nesnenin hesabını ve bu nesne için çağrısı yapılması gerektiğini VisualStateManager.GoToState görebilirsiniz. Bunun nedeni her iki görselin de sayfada birden çok nesne hedeflemesidir.

Merak ediyor olabilirsiniz: Arkadaki kod dosyası görsel durumları tanımlayan sayfada nesneye başvursunsa, arkadaki kod dosyası neden bu ve diğer nesnelere doğrudan erişesin? Kesinlikle olabilir. Ancak, VSM kullanmanın avantajı, görsel öğelerin tamamen XAML'de farklı duruma nasıl tepki vereceğini kontrol etmektir ve bu da tüm kullanıcı arabirimi tasarımını tek bir konumda tutar. Bu, doğrudan arka koddan görsel öğelere erişerek görsel görünümü ayarlamayı önler.

Görsel durum tetikleyicileri

Görsel durumlar, hangi koşulların uygulanması gerektiğini tanımlayan özel bir tetikleyici grubu olan durum VisualState tetikleyicilerini destekler.

Durum tetikleyicileri, Xamarin_Forms _VisualState_StateTriggers" data-linktype="absolute-path">StateTriggers koleksiyonuna VisualState eklenir. Bu koleksiyon tek bir durum tetikleyicisi veya birden çok durum tetikleyicisi içerebilir. Koleksiyonda VisualState herhangi bir durum tetikleyicisi etkin olduğunda bir uygulanır.

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

  1. 'den türeten herhangi bir StateTriggerBase tetikleyici.
  2. AdaptiveTriggerAdaptiveTrigger "data-linktype="absolute-path"Xamarin_Forms _AdaptiveTrigger_MinWindowWidth" koşulu karşı >MinWindowWidth etkinleştirildi.
  3. AdaptiveTriggerAdaptiveTrigger "data-linktype="absolute-path"Xamarin_Forms _AdaptiveTrigger_MinWindowHeight" koşulu karşı >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 kullanma

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

Bu teknik bazen uyarlamalı düzen olarak da bilinir. Uyarlamalı düzen yalnızca bir programın görsellerini içerdiği için 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 uygulamadır. Dikey modda bu düğmeler sayfanın üst kısmında yatay bir satırda görüntülenebilir:

VSM Uyarlamalı Düzen: Dikey

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

VSM Uyarlamalı Düzeni: Yatay

Program, Universal Windows Platform, Android ve iOS üzerinde çalışıyor.

VsmDemos örneğinin VSM Uyarlamalı Düzeni sayfası, "Portrait" ve "Landscape" adlı iki görsel durumu olan "OrientationStates" adlı 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 öğesi hem menüyü hem de bir öğe olan içeriği Image içerir. Dikey StackLayout modda dikey yönlendirme ve yatay modda yatay yönlendirme olması gerekir:

<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 adı menuScroll ve StackLayout adlandırılmış, menuStack düğmelerin menüsünü uygulama. Bu düzenlerin yönü, 'nin mainStack tersidir. Menü dikey modda yatay, yatay modda ise dikey olması gerekir.

VSM işaretlemenin dördüncü bölümü, düğmeler için örtülü bir stildedir. Bu işaretleme dikey VerticalOptionsHorizontalOptions ve yatay Margin yönlendirmelere özgü , ve özelliklerini ayarlar.

Arkadan kod dosyası, komutunu uygulamak için özelliğini ayarlar ve ayrıca sayfanın BindingContextmenuStackButton olayına bir SizeChanged işleyicisi de iliştirer:

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

SizeChangedİşleyici, iki ve öğelerini VisualStateManager.GoToStateStackLayoutScrollView çağırarak öğeleri için çağrısı yapmak için öğelerinin öğeleri menuStack arasında VisualStateManager.GoToStateButton döngüler sağlar.

Arka alınan kod dosyası, XAML dosyasındaki öğelerin özelliklerini ayarerek yönlendirme değişikliklerini daha doğrudan işleyene gibi görünebilir, ancak Visual State Manager kesinlikle daha yapılandırılmış bir yaklaşımdır. Tüm görseller XAML dosyasında tutulur ve bu dosyada inceleme, bakım ve değiştirme daha kolay hale geldi.

Xamarin.University ile Visual State Manager

3.0 Visual State Manager videosu