Xamarin.Forms Režim vazby

Download Sample Stažení ukázky

V předchozím článku jsou alternativní stránky vazby kódu a alternativní vazby XAML označené Label vlastností Scale svázanou s Value vlastností objektu Slider. Vzhledem k tomu, že Slider počáteční hodnota je 0, způsobila Scale to, že vlastnost Label byla 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 výjimkou toho, že datová vazba je definována na Slider místo na Label:

<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 zdroj datové vazby a Slider cíl. Vazba odkazuje na Opacity vlastnost Label, která má výchozí hodnotu 1.

Jak můžete očekávat, inicializuje Slider se na hodnotu 1 z počáteční Opacity hodnoty .Label Zobrazí se na snímku obrazovky s iOSem na levé straně:

Reverse Binding

Možná vás ale překvapilo, že Slider stále funguje, jak ukazuje snímek obrazovky s Androidem. Zdá se, že datová vazba funguje lépe, když Slider je cíl vazby spíše než Label proto, že inicializace funguje stejně, jako bychom mohli očekávat.

Rozdíl mezi ukázkou zpětné vazby a dřívějšími ukázkami zahrnuje režim vazby.

Výchozí režim vazby

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

  • Default
  • TwoWay – data prochází oběma způsoby mezi zdrojem a cílem.
  • OneWay – data pocházejí ze zdroje do cíle.
  • OneWayToSource – data pocházejí z cíle na zdroj.
  • OneTime – data pocházejí ze zdroje do cíle, ale pouze při změnách BindingContext (nové 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 bindable a který je k dispozici z DefaultBindingMode vlastnosti objektu BindableProperty . Tento výchozí režim vazby označuje režim, který se projeví v případě, že tato vlastnost je cílem datové vazby.

Výchozí režim vazby pro většinu vlastností, jako Rotationje , Scalea Opacity je OneWay. Pokud jsou tyto vlastnosti cíle datové vazby, pak je cílová vlastnost nastavena ze zdroje.

Výchozí režim vazby pro Value vlastnost Slider je TwoWayvšak . To znamená, že když Value je vlastnost cílem datové vazby, pak je cíl nastaven ze zdroje (jako obvykle), ale zdroj je také nastaven z cíle. To umožňuje Slider nastavit počáteční Opacity hodnotu.

Tato obousměrná vazba se může zdát, že vytváří neomezenou smyčku, ale to se nestane. Vlastnosti s možností vazby nepřiznakují změnu vlastnosti, pokud se vlastnost ve skutečnosti nezmění. Tím zabráníte nekonečné smyčce.

vazby Two-Way

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
  • Textmajetku Editor, , Entrya SearchBarEntryCell
  • IsRefreshing vlastnost ListView
  • SelectedItem vlastnost MultiPage
  • SelectedIndex a SelectedItem vlastnosti Picker
  • Value majetku Slider a Stepper
  • IsToggled vlastnost Switch
  • On vlastnost SwitchCell
  • Time vlastnost TimePicker

Tyto konkrétní vlastnosti jsou definovány z TwoWay velmi dobrého důvodu:

Při použití datových vazeb s architekturou aplikace Model-View-ViewModel (MVVM) je třída ViewModel zdrojem datové vazby a zobrazení, které se skládá z zobrazení, jako Sliderjsou cíle datové vazby. Vazby MVVM se podobají ukázce zpětné vazby více než vazby v předchozích ukázkách. Je velmi pravděpodobné, že chcete, aby se každé zobrazení na stránce inicializovalo s hodnotou odpovídající vlastnosti v ViewModel, ale změny v zobrazení by měly mít vliv také na vlastnost ViewModel.

Vlastnosti s výchozími režimy TwoWay vazeb jsou tyto vlastnosti pravděpodobně použity ve scénářích MVVM.

Jednosměrné vazby na zdroj

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

  • SelectedItem vlastnost ListView

Důvodem je, že vazba na SelectedItem vlastnost by měla vést k nastavení zdroje vazby. Příklad dále v tomto článku přepíše toto chování.

vazby One-Time

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

Cílové vlastnosti s režimem vazby OneTime se aktualizují pouze v případě, že se změní kontext vazby. Pro vazby u těchto cílových vlastností to zjednodušuje infrastrukturu vazeb, protože není nutné monitorovat změny ve zdrojových vlastnostech.

Zobrazení modelů a oznámení Property-Change

Stránka Jednoduchý výběr barev ukazuje použití jednoduchého modelu ViewModel. Datové vazby umožňují uživateli vybrat barvu pomocí tří Slider prvků pro odstín, sytost a světelnost.

Model ViewModel je zdroj datových vazeb. ViewModel nedefinuje vlastnosti svázatelné, ale implementuje mechanismus oznámení, který umožňuje informovat infrastrukturu vazeb, když se hodnota vlastnosti změní. Tento mechanismus oznámení je INotifyPropertyChanged rozhraní, které definuje jednu událost s názvem PropertyChanged. Třída, která implementuje toto rozhraní obecně aktivuje událost, když jedna z jejích veřejných vlastností změní hodnotu. Událost se nemusí aktivovat, pokud se vlastnost nikdy nezmění. INotifyPropertyChanged(Rozhraní je také implementováno BindableObject a PropertyChanged událost se aktivuje vždy, když se změní hodnota svázatelné vlastnosti.)

Třída HslColorViewModel definuje pět vlastností: The Hue, , SaturationLuminositya Color properties are interrelated. Když některý ze tří barevných komponent 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;
        }
    }
}

Když se Color vlastnost změní, statická GetNearestColorName metoda ve NamedColor třídě (zahrnutá také v řešení DataBindingDemos ) získá nejbližší pojmenovanou barvu a nastaví Name vlastnost. Tato Name vlastnost má privátní set příslušenství, takže jej nelze nastavit mimo třídu.

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

Pokud však cílová vlastnost (nebo Binding definice cílové vlastnosti) má hodnotu BindingModeOneTime, není nutné, aby infrastruktura vazby připojila obslužnou rutinu události PropertyChanged . Cílová vlastnost se aktualizuje pouze v případě, že BindingContext se změní, a ne v případě, že se změní samotná zdrojová vlastnost.

Soubor XAML jednoduché barvy vytvoří instanci HslColorViewModel ve slovníku prostředků stránky a inicializuje Color vlastnost. Vlastnost BindingContext objektu Grid je nastavena na StaticResource rozšíření vazby pro odkaz na tento 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>

Zobrazení BoxView, Labela tři Slider zobrazení dědí kontext vazby z objektu Grid. Tato zobrazení jsou všechny cíle vazby, které odkazují na zdrojové vlastnosti v modelu ViewModel. Color Pro vlastnost , a Text vlastnost BoxViewLabel, datové vazby jsou OneWay: Vlastnosti v zobrazení jsou nastaveny z vlastností v ViewModel.

Vlastnost ValueSlidervšak je TwoWay. To umožňuje nastavit jednotlivé Slider objekty z modelu ViewModel a také nastavit model ViewModel z každého Slider.

Při prvním spuštění programu jsou všechny elementy BoxView, Labela tři Slider elementy nastaveny z ViewModel na základě počáteční Color sady vlastností při vytvoření instance ViewModel. Zobrazí se na snímku obrazovky s iOSem na levé straně:

Simple Color Selector

Když pracujete s posuvníky, aktualizuje se BoxView a Label aktualizuje se odpovídajícím způsobem, jak je znázorněno na snímku obrazovky s Androidem.

Vytvoření instance modelu ViewModel ve slovníku prostředků je jedním z běžných přístupů. Je také možné vytvořit instanci ViewModel v rámci značek elementů vlastností pro BindingContext vlastnost. V souboru XAML jednoduchého výběru barev zkuste odebrat HslColorViewModel ze slovníku prostředků a nastavit ho na BindingContext vlastnost podobné Grid tomuto:

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

    ···

</Grid>

Kontext vazby lze nastavit různými způsoby. Někdy soubor s kódem vytvoří instanci Modelu ViewModel a nastaví ho 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 u cílové vlastnosti není vhodný pro konkrétní datovou vazbu, je možné jej přepsat nastavením Mode vlastnosti (nebo Mode vlastnosti BindingBinding rozšíření revize) na některý ze členů výčtuBindingMode.

Nastavení Mode vlastnosti TwoWay ale nefunguje vždy podle očekávání. Zkuste například upravit alternativní soubor XAML vazby XAML tak, aby zahrnoval TwoWay do definice vazby:

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

Je možné očekávat, že Slider by se inicializovala na počáteční hodnotu Scale vlastnosti, což je 1, ale to se nestane. TwoWay Při inicializaci vazby je cíl nejprve nastaven ze zdroje, což znamená, že Scale vlastnost je nastavena Slider na výchozí hodnotu 0. Když je vazba nastavena TwoWay na Slider, pak Slider je původně nastavena ze zdroje.

Režim vazby můžete nastavit v OneWayToSource ukázce alternativní vazby XAML :

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

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

Poznámka

Třída VisualElement také definuje ScaleX a ScaleY vlastnosti, které mohou různě škálovat VisualElement ve vodorovných a svislých směrech.

Velmi užitečná použití přepsání výchozího režimu vazby SelectedItem zahrnuje TwoWay vlastnost ListView. Výchozí režim vazby je OneWayToSource. Pokud je datová vazba nastavena SelectedItem na vlastnost odkazovat na zdroj vlastnost v Modelu ViewModel, pak je tato zdrojová vlastnost nastavena z ListView výběru. V některých případech ale můžete chtít, aby se inicializovala také ListView z modelu ViewModel.

Tato technika ukazuje stránka Ukázková Nastavení. Tato stránka představuje jednoduchou implementaci nastavení aplikace, která jsou velmi často definována v modelu ViewModel, například v tomto SampleSettingsViewModel souboru:

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 slovníku Xamarin.Forms vlastností v metodě s názvem SaveState a načten z daného slovníku v konstruktoru. V dolní části třídy jsou dvě metody, které pomáhají zjednodušit Modely ViewModel a z nich jsou méně náchylné k chybám. Metoda OnPropertyChanged v dolní části má volitelný parametr, který je nastaven na volající vlastnost. Tím se zabrání pravopisným chybám při zadávání názvu vlastnosti jako řetězce.

Metoda SetProperty ve třídě ještě více: Porovná hodnotu nastavenou na vlastnost s hodnotou uloženou jako pole a volá OnPropertyChanged pouze v případě, že se tyto dvě hodnoty nerovnají.

Třída SampleSettingsViewModel definuje dvě vlastnosti pro barvu pozadí: Vlastnost BackgroundNamedColor je typu NamedColor, což je třída také součástí DataBindingDemos řešení. Vlastnost BackgroundColor je typu Colora je získána z Color vlastnosti objektu NamedColor .

Třída NamedColor používá reflexi .NET k vytvoření výčtu všech statických veřejných polí ve Xamarin.FormsColor struktuře a k jejich uložení s 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;
    }
}

Třída App v projektu DataBindingDemos 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 zavolá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í cyklus aplikace.

Téměř všechno ostatní se zpracovává v souboru SampleSettingsPage.xaml . Stránka BindingContext je nastavena pomocí Binding rozšíření značek: Zdroj vazby je statická Application.Current vlastnost, což je instance 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 je vlastností v SampleSettingsViewModel. Vlastnost BackgroundColor se používá k nastavení BackgroundColor vlastnosti StackLayout, a Entry, , DatePickerSwitcha Stepper vlastnosti jsou vázány na ostatní vlastnosti v Modelu ViewModel.

Vlastnost ItemsSource objektu je nastavena ListView na statickou NamedColor.All vlastnost. Tím se vyplní ListView všechny NamedColor instance. Pro každou položku v objektu ListViewje kontext vazby pro položku nastaven na NamedColor objekt. A BoxView in the ViewCell are bound to properties in NamedColor.Label

Vlastnost SelectedItemListView je typu NamedColora je vázána BackgroundNamedColor na vlastnost SampleSettingsViewModel:

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

Výchozí režim vazby pro SelectedItem je OneWayToSource, který nastaví ViewModel vlastnost z vybrané položky. Režim TwoWay umožňuje SelectedItem inicializovat model ViewModel.

Pokud SelectedItem je však nastaven tímto způsobem, ListView automaticky se nepřesouvejte, aby se zobrazila vybraná položka. V souboru s kódem je potřeba trochu kódu:

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

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

Snímek obrazovky s iOSem na levé straně zobrazuje program při prvním spuštění. Konstruktor inicializuje SampleSettingsViewModel barvu pozadí na bílou a to je to, co je vybrané v :ListView

Sample Settings

Druhý snímek obrazovky ukazuje změněná nastavení. Při experimentování s touto stránkou nezapomeňte program umístit do režimu spánku nebo ho ukončit v zařízení nebo emulátoru, který je spuštěný. Ukončení programu z ladicího programu Visual Studio nezpůsobí OnSleep zavolá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 na Text vlastnost Label.