Xamarin.Forms Režim vazby

Download Sample Stažení ukázky

V předchozím článkuse alternativní vazba kódu a alternativní stránky vazby XAML , které jsou vybrany s vlastností vázanými na vlastnost prvku Slider . Vzhledem k tomu Slider , že počáteční hodnota je 0, způsobila se, že Scale vlastnost je Label nastavena na hodnotu 0 místo 1 a Label zmizela.

V ukázce DataBindingDemos je stránka zpětné vazby podobná programům v předchozím článku, s tím rozdílem, že datová vazba je definována na místo na :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.ReverseBindingPage"
             Title="Reverse Binding">
    <StackLayout Padding="10, 0">

        <Label x:Name="label"
               Text="TEXT"
               FontSize="80"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <Slider x:Name="slider"
                VerticalOptions="CenterAndExpand"
                Value="{Binding Source={x:Reference label},
                                Path=Opacity}" />
    </StackLayout>
</ContentPage>

Zpočátku se to může zdát zpět: teď Label je to zdroj vazby dat a Slider je cílem. Vazba odkazuje na Opacity vlastnost Label , která má výchozí hodnotu 1.

Jak je možné očekávat, Slider je inicializována na hodnotu 1 z počáteční Opacity hodnoty Label . Zobrazuje se na snímku iOS na levé straně:

Reverse Binding

Je ale možné, že budete překvapeni, že Slider i nadále funguje, jak ukazuje snímek obrazovky Android. To znamená, že je vhodné navrhnout, aby datová vazba lépe fungovala, pokud Slider je cílem vazby, nikoli z důvodu, že Label inicializace funguje, jako bychom mohli očekávat.

Rozdíl mezi ukázkou zpětné vazby a předchozími ukázkami zahrnuje režim vazby.

Výchozí režim vazby

Režim vazby je určen členem BindingMode výčtu:

  • Default
  • TwoWay – data přecházejí mezi zdrojem a cílem.
  • OneWay – data přecházejí ze zdroje do cíle.
  • OneWayToSource – data přecházejí z cíle do zdroje.
  • OneTime – data přecházejí ze zdroje do cíle, ale pouze v případě BindingContext změn (novinek s Xamarin.Forms 3,0)

Každá vlastnost s možností vazby má výchozí režim vazby, který je nastaven při vytvoření vlastnosti s možností vazby, která je k dispozici z DefaultBindingMode vlastnosti BindableProperty objektu. Tento výchozí režim vazby označuje režim, ve kterém platí, pokud je tato vlastnost cílem datové vazby.

Výchozí režim vazby pro většinu vlastností, jako jsou Rotation , Scale a OpacityOneWay . Pokud jsou tyto vlastnosti cíli vazby dat, je vlastnost target nastavena ze zdroje.

Výchozí režim vazby pro Value vlastnost Slider je však TwoWay . To znamená, že pokud Value je vlastnost cílovou datovou vazbou, pak je cíl nastaven ze zdroje (jako obvykle), ale zdroj je také nastaven z cíle. To umožňuje, aby se Slider nastavila z počáteční Opacity hodnoty.

Tato Obousměrná vazba se může zdát, že vytvoří nekonečnou smyčku, ale to neproběhne. Vlastnosti s možností vazby nesignalizují změnu vlastnosti, pokud se ve skutečnosti nemění vlastnost. Tím zabráníte nekonečné smyčce.

Two-Way vazby

Většina vlastností s možností vazby má výchozí režim vazby, OneWay ale následující vlastnosti mají výchozí režim vazby TwoWay :

  • Date vlastnost DatePicker
  • Text vlastnost Editor , Entry , SearchBar a EntryCell
  • IsRefreshing vlastnost ListView
  • SelectedItem vlastnost MultiPage
  • SelectedIndex a SelectedItem vlastnosti Picker
  • Value vlastnost Slider a Stepper
  • IsToggled vlastnost Switch
  • On vlastnost SwitchCell
  • Time vlastnost TimePicker

Tyto konkrétní vlastnosti jsou definovány jako TwoWay pro velmi dobrý důvod:

Při použití datových vazeb s aplikační architekturou Model-View-ViewModel (MVVM) je třída ViewModel zdrojem vazby dat a zobrazení, které se skládá z zobrazení jako Slider , jsou cíle datové vazby. Vazby MVVM připomínají ukázku zpětné vazby více než vazby v předchozích ukázkách. Je velmi vhodné, aby každé zobrazení na stránce bylo inicializováno s hodnotou odpovídající vlastnosti v ViewModel, ale změny v zobrazení měly vliv také na vlastnost ViewModel.

Vlastnosti s výchozími režimy vazby TwoWay jsou tyto vlastnosti, které jsou pravděpodobně používány v MVVM scénářích.

Vazby jednosměrového zdroje

Vlastnosti s možností vazby jen pro čtení mají výchozí režim vazby OneWayToSource . Existuje pouze jedna vlastnost s možností vazby pro čtení a zápis, která má výchozí režim vazby OneWayToSource :

  • SelectedItem vlastnost ListView

Racionální je, že vazba na SelectedItem vlastnost by měla mít za následek nastavení zdroje vazby. Příklad dále v tomto článku toto chování potlačí.

One-Time vazby

Několik vlastností má výchozí režim vazby OneTime , včetně IsTextPredictionEnabled vlastnosti Entry .

Vlastnosti cíle s režimem vazby OneTime se aktualizují pouze v případě, že se změní kontext vazby. Pro vazby na tyto vlastnosti cíle Tato vlastnost zjednodušuje infrastrukturu vazeb, protože není nutné sledovat změny ve vlastnostech zdroje.

Oznámení ViewModels a Property-Change

Jednoduchá stránka pro Výběr barev ukazuje použití jednoduchého ViewModel. Datové vazby umožňují uživateli vybrat barvu s použitím tří Slider prvků pro odstín, sytost a Světlost.

ViewModel je zdroj vázání dat. ViewModel nedefinuje vlastnosti , které lze svázat, ale implementuje mechanismus oznámení, který umožňuje oznamování infrastruktury vazby při změně hodnoty vlastnosti. Tento mechanismus oznámení je INotifyPropertyChanged rozhraní, které definuje jednu událost s názvem PropertyChanged . Třída, která implementuje toto rozhraní obecně, vyvolá událost, když se jedna z jejích veřejných vlastností změní na hodnotu. Událost nemusí být vyvolána, pokud se vlastnost nikdy nemění. ( INotifyPropertyChanged Rozhraní je implementováno také pomocí BindableObject a PropertyChanged událost je vyvolána vždy, když se změní hodnota vlastnosti s možností vazby.)

HslColorViewModelTřída definuje pět vlastností: HueSaturation vlastnosti,, Luminosity a Color jsou vzájemně propojené. Když jedna ze tří součástí barvy změní hodnotu, Color vlastnost se přepočítá a PropertyChanged události se aktivují pro všechny čtyři vlastnosti:

public class HslColorViewModel : INotifyPropertyChanged
{
    Color color;
    string name;

    public event PropertyChangedEventHandler PropertyChanged;

    public double Hue
    {
        set
        {
            if (color.Hue != value)
            {
                Color = Color.FromHsla(value, color.Saturation, color.Luminosity);
            }
        }
        get
        {
            return color.Hue;
        }
    }

    public double Saturation
    {
        set
        {
            if (color.Saturation != value)
            {
                Color = Color.FromHsla(color.Hue, value, color.Luminosity);
            }
        }
        get
        {
            return color.Saturation;
        }
    }

    public double Luminosity
    {
        set
        {
            if (color.Luminosity != value)
            {
                Color = Color.FromHsla(color.Hue, color.Saturation, value);
            }
        }
        get
        {
            return color.Luminosity;
        }
    }

    public Color Color
    {
        set
        {
            if (color != value)
            {
                color = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Hue"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Saturation"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Luminosity"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Color"));

                Name = NamedColor.GetNearestColorName(color);
            }
        }
        get
        {
            return color;
        }
    }

    public string Name
    {
        private set
        {
            if (name != value)
            {
                name = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
            }
        }
        get
        {
            return name;
        }
    }
}

Při Color změně vlastnosti statická GetNearestColorName Metoda ve NamedColor třídě (také obsažená v řešení Color ) získá nejbližší pojmenovanou barvu a nastaví Name vlastnost. Tato Name vlastnost má privátní set přistupující objekt, takže nemůže být nastavena vně třídy.

Když je ViewModel nastaveno jako zdroj vazby, infrastruktura vazby připojí obslužnou rutinu k PropertyChanged události. Tímto způsobem může být vazba upozorněna na změny vlastností a následně může nastavit cílové vlastnosti ze změněných hodnot.

Nicméně pokud cílová vlastnost (nebo Binding definice na cílové vlastnosti) má BindingMode z OneTime , není nutné, aby infrastruktura vazby připojila obslužnou rutinu PropertyChanged události. Vlastnost target je aktualizována pouze v případě, že dojde ke změně BindingContext vlastnosti source a nikoli.

Jednoduchý soubor XAML pro Selektory barev vytvoří instanci ve slovníku prostředků stránky a inicializuje Color vlastnost. BindingContextVlastnost Grid je nastavena na StaticResource rozšíření vazby, které odkazuje na prostředek:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DataBindingDemos"
             x:Class="DataBindingDemos.SimpleColorSelectorPage">

    <ContentPage.Resources>
        <ResourceDictionary>
            <local:HslColorViewModel x:Key="viewModel"
                                     Color="MediumTurquoise" />

            <Style TargetType="Slider">
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <Grid BindingContext="{StaticResource viewModel}">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <BoxView Color="{Binding Color}"
                 Grid.Row="0" />

        <StackLayout Grid.Row="1"
                     Margin="10, 0">

            <Label Text="{Binding Name}"
                   HorizontalTextAlignment="Center" />

            <Slider Value="{Binding Hue}" />

            <Slider Value="{Binding Saturation}" />

            <Slider Value="{Binding Luminosity}" />
        </StackLayout>
    </Grid>
</ContentPage>

BoxViewZobrazení, Label a tři Slider zobrazení dědí kontext vazby z Grid . Tato zobrazení jsou všechny cíle vazby, které odkazují na vlastnosti zdroje v ViewModel. Pro Color vlastnost BoxView a Text vlastnost Label , datové vazby jsou OneWay : vlastnosti v zobrazení jsou nastaveny z vlastností v ViewModel.

ValueVlastnost Slider je však TwoWay . Tím umožníte Slider , aby se všechny nastavily z ViewModel, a také pro nastavení ViewModel z každého Slider .

Při prvním spuštění programu BoxViewLabelSlider jsou všechny prvky, a tři nastaveny z ViewModel založené na počáteční Color Vlastnosti nastavené při vytváření instance ViewModel. Zobrazuje se na snímku obrazovky iOS vlevo:

Simple Color Selector

Při manipulaci s posuvníky se BoxViewLabel odpovídajícím způsobem aktualizují a, jak je znázorněno na snímku obrazovky Android.

Vytvoření instance ViewModel ve slovníku prostředků je jedním ze společného přístupu. Je také možné vytvořit instanci ViewModel v rámci značek elementu vlastnosti pro BindingContext vlastnost. V souboru XAML pro výběr jednoduchých barev zkuste odebrat ze slovníku prostředků a nastavit jej na BindingContext vlastnost Grid podobné této:

<Grid>
    <Grid.BindingContext>
        <local:HslColorViewModel Color="MediumTurquoise" />
    </Grid.BindingContext>

    ···

</Grid>

Kontext vazby lze nastavit různými způsoby. V některých případech je soubor kódu na pozadí vytvořen jako instance ViewModel a nastavuje se na BindingContext vlastnost stránky. Jedná se o všechny platné přístupy.

Přepsání režimu vazby

Pokud výchozí režim vazby ve vlastnosti target není vhodný pro konkrétní datovou vazbu, je možné ji přepsat nastavením Mode vlastnosti Binding (nebo Mode vlastnosti Binding rozšíření označení) na jeden z členů BindingMode výčtu.

Nicméně nastavení Mode vlastnosti na TwoWay ne vždy funguje, jak očekáváte. Zkuste například změnit alternativní soubor XAML vazby XAML tak, aby zahrnoval definici vazby:

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand"
       Scale="{Binding Source={x:Reference slider},
                       Path=Value,
                       Mode=TwoWay}" />

Může být očekáváno, že Slider by byla inicializována na počáteční hodnotu Scale vlastnosti, která je 1, ale to neproběhne. Při TwoWay inicializaci vazby se cíl nastaví ze zdroje jako první, což znamená, že Scale vlastnost je nastavena na Slider výchozí hodnotu 0. Když TwoWay je vazba nastavena na Slider , pak Slider je zpočátku nastavena ze zdroje.

Můžete nastavit režim vazby OneWayToSource v OneWayToSource :

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand"
       Scale="{Binding Source={x:Reference slider},
                       Path=Value,
                       Mode=OneWayToSource}" />

Nyní Slider je inicializována na hodnotu 1 (výchozí hodnota Scale ), ale manipulace Slider nemá vliv na Scale vlastnost, takže to není velmi užitečné.

Poznámka

VisualElementTřída také definuje ScaleX a ScaleY vlastnosti, které mohou škálovat VisualElement odlišně v horizontálním a svislém směru.

Velmi užitečná aplikace přepisování výchozího režimu vazeb s TwoWay zahrnuje SelectedItem vlastnost ListView . Výchozí režim vazby je OneWayToSource . Když je datová vazba nastavena na SelectedItem vlastnost, aby odkazovala na vlastnost zdroje v ViewModel, pak je tato vlastnost zdroje nastavena z ListView výběru. V některých případech ale může být také vhodné ListView inicializovat z ViewModel.

tato technika ukazuje ukázkovou Nastavení stránku. Tato stránka představuje jednoduchou implementaci nastavení aplikace, která je velmi často definována v ViewModel, jako je například tento SampleSettingsViewModel soubor:

public class SampleSettingsViewModel : INotifyPropertyChanged
{
    string name;
    DateTime birthDate;
    bool codesInCSharp;
    double numberOfCopies;
    NamedColor backgroundNamedColor;

    public event PropertyChangedEventHandler PropertyChanged;

    public SampleSettingsViewModel(IDictionary<string, object> dictionary)
    {
        Name = GetDictionaryEntry<string>(dictionary, "Name");
        BirthDate = GetDictionaryEntry(dictionary, "BirthDate", new DateTime(1980, 1, 1));
        CodesInCSharp = GetDictionaryEntry<bool>(dictionary, "CodesInCSharp");
        NumberOfCopies = GetDictionaryEntry(dictionary, "NumberOfCopies", 1.0);
        BackgroundNamedColor = NamedColor.Find(GetDictionaryEntry(dictionary, "BackgroundNamedColor", "White"));
    }

    public string Name
    {
        set { SetProperty(ref name, value); }
        get { return name; }
    }

    public DateTime BirthDate
    {
        set { SetProperty(ref birthDate, value); }
        get { return birthDate; }
    }

    public bool CodesInCSharp
    {
        set { SetProperty(ref codesInCSharp, value); }
        get { return codesInCSharp; }
    }

    public double NumberOfCopies
    {
        set { SetProperty(ref numberOfCopies, value); }
        get { return numberOfCopies; }
    }

    public NamedColor BackgroundNamedColor
    {
        set
        {
            if (SetProperty(ref backgroundNamedColor, value))
            {
                OnPropertyChanged("BackgroundColor");
            }
        }
        get { return backgroundNamedColor; }
    }

    public Color BackgroundColor
    {
        get { return BackgroundNamedColor?.Color ?? Color.White; }
    }

    public void SaveState(IDictionary<string, object> dictionary)
    {
        dictionary["Name"] = Name;
        dictionary["BirthDate"] = BirthDate;
        dictionary["CodesInCSharp"] = CodesInCSharp;
        dictionary["NumberOfCopies"] = NumberOfCopies;
        dictionary["BackgroundNamedColor"] = BackgroundNamedColor.Name;
    }

    T GetDictionaryEntry<T>(IDictionary<string, object> dictionary, string key, T defaultValue = default(T))
    {
        return dictionary.ContainsKey(key) ? (T)dictionary[key] : defaultValue;
    }

    bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (object.Equals(storage, value))
            return false;

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Každé nastavení aplikace je vlastnost, která je uložena do Xamarin.Forms slovníku vlastností v metodě s názvem SaveState a načtena z tohoto slovníku do konstruktoru. Směrem ke spodní části třídy jsou dvě metody, které zjednodušují ViewModels a jejich méně náchylné k chybám. OnPropertyChangedMetoda v dolní části má volitelný parametr, který je nastaven na vlastnost Call. Tím se zabrání v pravopisných chybách při zadání názvu vlastnosti jako řetězce.

SetPropertyMetoda ve třídě ještě více porovnává hodnotu, která je nastavena na vlastnost s hodnotou uloženou jako pole a volá pouze OnPropertyChanged v případě, že tyto dvě hodnoty nejsou stejné.

SampleSettingsViewModelTřída definuje dvě vlastnosti barvy pozadí: BackgroundNamedColor vlastnost je typu NamedColor , což je třída, která je také obsažena v řešení SampleSettingsViewModel . BackgroundColorVlastnost je typu Color a je získána z Color vlastnosti NamedColor objektu.

NamedColorTřída používá reflexi .NET k zobrazení výčtu všech statických veřejných polí ve Xamarin.FormsColor struktuře a jejich uložení se svými názvy v kolekci přístupné ze statické All vlastnosti:

public class NamedColor : IEquatable<NamedColor>, IComparable<NamedColor>
{
    // Instance members
    private NamedColor()
    {
    }

    public string Name { private set; get; }

    public string FriendlyName { private set; get; }

    public Color Color { private set; get; }

    public string RgbDisplay { private set; get; }

    public bool Equals(NamedColor other)
    {
        return Name.Equals(other.Name);
    }

    public int CompareTo(NamedColor other)
    {
        return Name.CompareTo(other.Name);
    }

    // Static members
    static NamedColor()
    {
        List<NamedColor> all = new List<NamedColor>();
        StringBuilder stringBuilder = new StringBuilder();

        // Loop through the public static fields of the Color structure.
        foreach (FieldInfo fieldInfo in typeof(Color).GetRuntimeFields())
        {
            if (fieldInfo.IsPublic &&
                fieldInfo.IsStatic &&
                fieldInfo.FieldType == typeof(Color))
            {
                // Convert the name to a friendly name.
                string name = fieldInfo.Name;
                stringBuilder.Clear();
                int index = 0;

                foreach (char ch in name)
                {
                    if (index != 0 && Char.IsUpper(ch))
                    {
                        stringBuilder.Append(' ');
                    }
                    stringBuilder.Append(ch);
                    index++;
                }

                // Instantiate a NamedColor object.
                Color color = (Color)fieldInfo.GetValue(null);

                NamedColor namedColor = new NamedColor
                {
                    Name = name,
                    FriendlyName = stringBuilder.ToString(),
                    Color = color,
                    RgbDisplay = String.Format("{0:X2}-{1:X2}-{2:X2}",
                                                (int)(255 * color.R),
                                                (int)(255 * color.G),
                                                (int)(255 * color.B))
                };

                // Add it to the collection.
                all.Add(namedColor);
            }
        }
        all.TrimExcess();
        all.Sort();
        All = all;
    }

    public static IList<NamedColor> All { private set; get; }

    public static NamedColor Find(string name)
    {
        return ((List<NamedColor>)All).Find(nc => nc.Name == name);
    }

    public static string GetNearestColorName(Color color)
    {
        double shortestDistance = 1000;
        NamedColor closestColor = null;

        foreach (NamedColor namedColor in NamedColor.All)
        {
            double distance = Math.Sqrt(Math.Pow(color.R - namedColor.Color.R, 2) +
                                        Math.Pow(color.G - namedColor.Color.G, 2) +
                                        Math.Pow(color.B - namedColor.Color.B, 2));

            if (distance < shortestDistance)
            {
                shortestDistance = distance;
                closestColor = namedColor;
            }
        }
        return closestColor.Name;
    }
}

AppTřída v projektu App definuje vlastnost s názvem Settings typu SampleSettingsViewModel . Tato vlastnost je inicializována při App vytvoření instance třídy a SaveState Metoda je volána při OnSleep volání metody:

public partial class App : Application
{
    public App()
    {
        InitializeComponent();

        Settings = new SampleSettingsViewModel(Current.Properties);

        MainPage = new NavigationPage(new MainPage());
    }

    public SampleSettingsViewModel Settings { private set; get; }

    protected override void OnStart()
    {
        // Handle when your app starts
    }

    protected override void OnSleep()
    {
        // Handle when your app sleeps
        Settings.SaveState(Current.Properties);
    }

    protected override void OnResume()
    {
        // Handle when your app resumes
    }
}

Další informace o metodách životního cyklu aplikace najdete v článku životní cyklusaplikace.

V souboru SampleSettingsPage. XAML se zpracovává skoro všechno ostatní. BindingContextStránka je nastavena pomocí Binding rozšíření značek: zdroj vazby je statická Application.Current vlastnost, která je instancí App třídy v projektu, a Path je nastavena na Settings vlastnost, což je SampleSettingsViewModel objekt:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DataBindingDemos"
             x:Class="DataBindingDemos.SampleSettingsPage"
             Title="Sample Settings"
             BindingContext="{Binding Source={x:Static Application.Current},
                                      Path=Settings}">

    <StackLayout BackgroundColor="{Binding BackgroundColor}"
                 Padding="10"
                 Spacing="10">

        <StackLayout Orientation="Horizontal">
            <Label Text="Name: "
                   VerticalOptions="Center" />

            <Entry Text="{Binding Name}"
                   Placeholder="your name"
                   HorizontalOptions="FillAndExpand"
                   VerticalOptions="Center" />
        </StackLayout>

        <StackLayout Orientation="Horizontal">
            <Label Text="Birth Date: "
                   VerticalOptions="Center" />

            <DatePicker Date="{Binding BirthDate}"
                        HorizontalOptions="FillAndExpand"
                        VerticalOptions="Center" />
        </StackLayout>

        <StackLayout Orientation="Horizontal">
            <Label Text="Do you code in C#? "
                   VerticalOptions="Center" />

            <Switch IsToggled="{Binding CodesInCSharp}"
                    VerticalOptions="Center" />
        </StackLayout>

        <StackLayout Orientation="Horizontal">
            <Label Text="Number of Copies: "
                   VerticalOptions="Center" />

            <Stepper Value="{Binding NumberOfCopies}"
                     VerticalOptions="Center" />

            <Label Text="{Binding NumberOfCopies}"
                   VerticalOptions="Center" />
        </StackLayout>

        <Label Text="Background Color:" />

        <ListView x:Name="colorListView"
                  ItemsSource="{x:Static local:NamedColor.All}"
                  SelectedItem="{Binding BackgroundNamedColor, Mode=TwoWay}"
                  VerticalOptions="FillAndExpand"
                  RowHeight="40">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Orientation="Horizontal">
                            <BoxView Color="{Binding Color}"
                                     HeightRequest="32"
                                     WidthRequest="32"
                                     VerticalOptions="Center" />

                            <Label Text="{Binding FriendlyName}"
                                   FontSize="24"
                                   VerticalOptions="Center" />
                        </StackLayout>                        
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

Všechny podřízené položky stránky dědí kontext vazby. Většina ostatních vazeb na této stránce má vlastnosti v SampleSettingsViewModel . BackgroundColorVlastnost se používá k nastavení BackgroundColor vlastnosti StackLayout a EntryDatePicker vlastnosti,, Switch a Stepper jsou všechny vázány na jiné vlastnosti v ViewModel.

ItemsSourceVlastnost ListView je nastavena na statickou NamedColor.All vlastnost. Tím se vyplní ListView všechny NamedColor instance. Pro každou položku v je ListView kontext vazby pro položku nastaven na NamedColor objekt. BoxViewA Label v ViewCell jsou vázány na vlastnosti v NamedColor .

SelectedItemVlastnost ListView je typu NamedColor a je vázána na BackgroundNamedColor vlastnost SampleSettingsViewModel :

SelectedItem="{Binding BackgroundNamedColor, Mode=TwoWay}"

Výchozí režim vazby pro SelectedItem je OneWayToSource , který nastavuje vlastnost ViewModel z vybrané položky. TwoWayRežim umožňuje SelectedItem inicializaci z ViewModel.

Pokud SelectedItem je však nastavena tato možnost, nedojde ListView k automatickému posunutí, aby se zobrazila vybraná položka. V souboru kódu na pozadí je nutný malý kód:

public partial class SampleSettingsPage : ContentPage
{
    public SampleSettingsPage()
    {
        InitializeComponent();

        if (colorListView.SelectedItem != null)
        {
            colorListView.ScrollTo(colorListView.SelectedItem,
                                   ScrollToPosition.MakeVisible,
                                   false);
        }
    }
}

Snímek obrazovky iOS na levé straně zobrazuje program při jeho prvním spuštění. Konstruktor v SampleSettingsViewModel inicializuje barvu pozadí na bílou a co je vybrán v ListView :

Sample Settings

Druhý snímek obrazovky ukazuje změněné nastavení. Při experimentování s touto stránkou nezapomeňte uvést program do režimu spánku nebo ho ukončit na zařízení nebo emulátoru, na kterém je spuštěný. ukončení programu z ladicího programu Visual Studio nebude způsobovat OnSleep volání přepsání ve App třídě.

V dalším článku se dozvíte, jak určit formátování řetězců datových vazeb, které jsou nastaveny u vlastnosti .