Sdílet prostřednictvím


Xamarin.Forms Režim vazby

V předchozím článku, alternativní kód vazby a alternativní XAML vazby stránky s Label jeho Scale vlastnost vázána na Value vlastnost .Slider Vzhledem k tomu, že Slider počáteční hodnota je 0, způsobila to Scale , že vlastnost Label byla nastavena na hodnotu 0 místo 1 a Label zmizela.

Stránka Zpětné vazby je podobná programům v předchozím článku s tím rozdílem, že datová vazba je definována spíše než Slider 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ětně: Teď Label je zdrojem datové vazby a Slider cílem je. Vazba odkazuje na Opacity vlastnost Label, která má výchozí hodnotu 1.

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

Zpětná vazba

Možná vás ale překvapí, že Slider i nadále funguje, jak ukazuje snímek obrazovky s Androidem. Zdá se, že datové vazby fungují lépe, když Slider je cílem vazby, a ne Label proto, že inicializace funguje stejně, jako bychom očekávali.

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 se mezi zdrojem a cílem jdou oběma způsoby.
  • 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 v případě, že BindingContext se změny změní (s Xamarin.Forms 3,0)

Každá vlastnost bindable má výchozí režim vazby, který je nastaven při vytvoření bindable vlastnost, a který je k dispozici z DefaultBindingMode vlastnosti objektu BindableProperty . Tento výchozí režim vazby označuje režim, který má účinek, pokud je tato vlastnost 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 vazby dat, pak je cílová vlastnost nastavena ze zdroje.

Výchozí režim vazby pro Value vlastnost Slider je TwoWayvšak . To znamená, že pokud Value je vlastnost cíl vazby dat, 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 vytvoří nekonečnou smyčku, ale to se nestane. Vlastnosti s možností vázání nepřiznaují změnu vlastnosti, pokud se tato vlastnost skutečně nezmění. Tím zabráníte nekonečné smyčce.

Obousměrné vazby

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

  • Date majetku DatePicker
  • Textmajetku Editor, , SearchBarEntryaEntryCell
  • IsRefreshing majetku ListView
  • SelectedItem majetku MultiPage
  • SelectedIndex a SelectedItem vlastnosti Picker
  • Value majetku Slider a Stepper
  • IsToggled majetku Switch
  • On majetku SwitchCell
  • Time majetku TimePicker

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

Pokud se datové vazby používají s architekturou aplikace Model-View-ViewModel (MVVM), třída ViewModel je zdroj datové vazby a Zobrazení, které se skládá ze zobrazení, jako Sliderjsou například 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 každé zobrazení na stránce bylo inicializováno s hodnotou odpovídající vlastnosti v Modelu ViewModel, ale změny v zobrazení by také měly ovlivnit ViewModel vlastnost.

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

Jednosměrné vazby ke zdroji

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

  • SelectedItem majetku ListView

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

Jednorázové vazby

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

Cílové vlastnosti s režimem OneTime vazby se aktualizují pouze v případech, kdy se kontext vazby změní. 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.

ViewModels and Property-Change Notifications

Stránka jednoduchého výběru 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 vazby dat. Model ViewModel nedefinuje vlastnosti vázání, ale implementuje mechanismus oznámení, který umožňuje informovat infrastrukturu vazeb 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ě 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í. (Rozhraní INotifyPropertyChanged je také implementováno BindableObject a PropertyChanged událost se aktivuje vždy, když bindable vlastnost změní hodnotu.)

Třída HslColorViewModel definuje pět vlastností: The Hue, Saturation, Luminositya Color vlastnosti jsou vzájemně propojeny. Když některá ze tří barevných součástí 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řístup, takže ji nelze nastavit mimo třídu.

Pokud 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 BindingMode OneTime, není nutné, aby infrastruktura vazby připojila obslužnou rutinu události PropertyChanged . Cílová vlastnost se aktualizuje pouze v případech, kdy BindingContext se změny změní, a ne když se změní samotná zdrojová vlastnost.

Soubor XAML jednoduchého výběru barev vytvoří HslColorViewModel instanci ve slovníku prostředků stránky a inicializuje Color vlastnost. Vlastnost BindingContext objektu Grid je nastavena na StaticResource rozšíření vazby odkazující 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>

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

SliderMajetek Value však je TwoWay. To umožňuje nastavit každý Slider z modelu ViewModel a také nastavit model ViewModel z každého Slider.

Při prvním spuštění programu , BoxViewLabel, a tři Slider elementy jsou nastaveny z ViewModel na základě počáteční Color vlastnost set při Vytvoření ViewModel vytvoření instance. Tento snímek obrazovky se zobrazuje na snímku obrazovky s iOSem vlevo:

Jednoduchý selektor barev

Při práci s posuvníky BoxView se odpovídajícím Label způsobem aktualizují, jak je znázorněno na snímku obrazovky Androidu.

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 elementu vlastnosti pro BindingContext vlastnost. V souboru XAML pro výběr jednoduchých barev zkuste odebrat HslColorViewModel slovník prostředků a nastavit ho Grid na BindingContext vlastnost tohoto typu:

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

    ···

</Grid>

Kontext vazby lze nastavit různými způsoby. Soubor s kódem někdy vytvoří instanci modelu ViewModel a nastaví ho na BindingContext vlastnost stránky. Toto jsou všechny platné přístupy.

Přepsání režimu vazby

Pokud výchozí režim vazby pro cílovou vlastnost není vhodný pro konkrétní datovou vazbu, je možné jej přepsat nastavením Mode vlastnosti (nebo Mode vlastnosti Binding Binding rozšíření značek) na jeden ze členů výčtuBindingMode.

Nastavení Mode vlastnosti TwoWay ale nebude vždy fungovat tak, jak byste očekávali. Zkuste například upravit alternativní soubor XAML vazby XAML tak, aby zahrnoval TwoWay v definici vazby:

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

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

Režim OneWayToSource vazby můžete nastavit v 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 hodnotu 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 definuje také vlastnosti ScaleX a ScaleY, které můžou měnit měřítko objektu VisualElement odlišně ve vodorovném a svislém směru.

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 u vlastnosti nastavena SelectedItem datová vazba, která odkazuje na zdrojovou vlastnost v modelu ViewModel, je tato zdrojová vlastnost nastavena ListView z výběru. V některých případech ale můžete chtít ListView , aby se inicializovala také 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 uložená do slovníku Xamarin.Forms vlastností v metodě pojmenované 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 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, která je nastavena na vlastnost s hodnotou uloženou jako pole, a volá OnPropertyChanged pouze v případě, že tyto dvě hodnoty nejsou stejné.

Třída SampleSettingsViewModel definuje dvě vlastnosti pro barvu pozadí: Vlastnost BackgroundNamedColor je typu NamedColor, což je třída také zahrnuta v 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 slouží k nastavení BackgroundColor vlastnosti StackLayout, a Entry, , DatePickerSwitch, a Stepper vlastnosti jsou vázány na ostatní vlastnosti v Modelu ViewModel.

Vlastnost ItemsSource objektu ListView je nastavena na statickou NamedColor.All vlastnost. Tím se ListView vyplní všechny NamedColor instance. Pro každou položku v objektu ListViewje kontext vazby položky nastaven na NamedColor objekt. A BoxView v ViewCell sadě jsou svázány s vlastnostmi v NamedColor.Label

Vlastnost SelectedItem ListView je typu NamedColora je vázána na BackgroundNamedColor 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 inicializaci z modelu ViewModel.

Pokud je však SelectedItem nastaven tímto způsobem, ListView nebude se automaticky posouvat, 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

Ukázková nastavení

Druhý snímek obrazovky ukazuje změněná nastavení. Při experimentování s touto stránkou nezapomeňte program přesunout do režimu spánku nebo ho ukončit na zařízení nebo emulátoru, na kterém běží. Ukončení programu z ladicího programu sady Visual Studio nezpůsobí OnSleep zavolání přepsání třídy App .

V dalším článku se dozvíte, jak zadat Formátování řetězce datových vazeb, které jsou nastaveny na Text vlastnost Label.