Aracılığıyla paylaş


Xamarin.Forms Bağlama Modu

Önceki makalede, Alternatif Kod Bağlama ve Alternatif XAML Bağlama sayfaları, özelliği bir Label özelliğine Value bağlı olan Scale bir Sliderözelliğine sahiptir. Slider İlk değer 0 olduğundan, bu, özelliğinin Scale Label 1 yerine 0 olarak ayarlanmasına neden oldu ve Label kayboldu.

Ters Bağlama sayfası, önceki makaledeki programlara benzer, ancak veri bağlaması yerine Labelüzerinde Slider tanımlanmıştır:

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

İlk başta, bu geriye dönük görünebilir: Şimdi Label veri bağlama kaynağı ve Slider hedeftir. Bağlama, varsayılan değeri 1 olan öğesinin özelliğine LabelbaşvururOpacity.

Bekleyebileceğiniz gibi, Slider ilk Opacity değerinden 1 değerine Labelbaşlatılır. Bu, soldaki iOS ekran görüntüsünde gösterilir:

Ters Bağlama

Ancak Android ekran görüntüsünde Slider gösterildiği gibi çalışmaya devam etmesi sizi şaşırtabilir. Bu, veri bağlamanın bağlama hedefi yerine bağlama hedefi Label olduğunda Slider daha iyi çalıştığını gösteriyor çünkü başlatma beklediğiniz gibi çalışıyor.

Ters Bağlama örneği ile önceki örnekler arasındaki fark bağlama modunu içerir.

Varsayılan Bağlama Modu

Bağlama modu, numaralandırmanın BindingMode bir üyesiyle belirtilir:

  • Default
  • TwoWay – veriler kaynak ve hedef arasında her iki yolu da kullanır
  • OneWay – veriler kaynaktan hedefe gider
  • OneWayToSource – veriler hedeften kaynağa gider
  • OneTime – veriler kaynaktan hedefe gider, ancak yalnızca değişiklikler olduğunda BindingContext (3.0 ile Xamarin.Forms yeni)

Her bağlanabilir özelliğin, bağlanabilir özellik oluşturulduğunda ayarlanan ve nesnenin BindableProperty özelliğinden DefaultBindingMode kullanılabilen varsayılan bağlama modu vardır. Bu varsayılan bağlama modu, bu özellik bir veri bağlama hedefi olduğunda modun etkin olduğunu gösterir.

, ve Opacity gibi RotationScaleözelliklerin çoğu için varsayılan bağlama modudurOneWay. Bu özellikler veri bağlama hedefleri olduğunda hedef özelliği kaynaktan ayarlanır.

Ancak özelliği için Value Slider varsayılan bağlama modu şeklindedir TwoWay. Bu, özellik bir veri bağlama hedefi olduğunda Value , hedef kaynaktan (her zamanki gibi) ayarlanır, ancak kaynak da hedeften ayarlanır. başlangıç değerinden Slider ayarlanmasını Opacity sağlayan budur.

Bu iki yönlü bağlama sonsuz bir döngü oluşturuyor gibi görünebilir, ancak bu gerçekleşmez. Bağlanabilir özellikler, özellik gerçekten değişmediği sürece bir özellik değişikliğine işaret etmez. Bu, sonsuz döngünün önüne geçer.

İki Yönlü Bağlamalar

Çoğu bağlanabilir özelliğin OneWay varsayılan bağlama modu vardır, ancak aşağıdaki özellikler varsayılan bağlama moduna TwoWaysahiptir:

  • Date özelliği DatePicker
  • TextEditor, , EntrySearchBarve özelliğiEntryCell
  • IsRefreshing özelliği ListView
  • SelectedItem özelliği MultiPage
  • SelectedIndex ve SelectedItem özellikleri Picker
  • Valueve özelliğinin SliderStepper
  • IsToggled özelliği Switch
  • On özelliği SwitchCell
  • Time özelliği TimePicker

Bu belirli özellikler çok iyi bir nedenden dolayı tanımlanır TwoWay :

Veri bağlamaları Model-View-ViewModel (MVVM) uygulama mimarisiyle kullanıldığında, ViewModel sınıfı veri bağlama kaynağıdır ve gibi Slidergörünümlerden oluşan Görünüm, veri bağlama hedefleridir. MVVM bağlamaları Ters Bağlama örneğine önceki örneklerdeki bağlamalardan daha çok benzemektedir. Sayfadaki her görünümün ViewModel'deki ilgili özelliğin değeriyle başlatılmasını büyük olasılıkla istersiniz, ancak görünümdeki değişiklikler ViewModel özelliğini de etkilemelidir.

Varsayılan bağlama modlarına TwoWay sahip özellikler, MVVM senaryolarında kullanılma olasılığı en yüksek olan özelliklerdir.

Tek Yönlü Kaynak Bağlamaları

Salt okunur bağlanabilir özellikler varsayılan bağlama moduna OneWayToSourcesahiptir. Varsayılan bağlama moduna OneWayToSourcesahip yalnızca bir okuma/yazma bağlanabilir özelliği vardır:

  • SelectedItem özelliği ListView

Rasyonalite, özelliğindeki bir bağlamanın SelectedItem bağlama kaynağının ayarlanmasına neden olmasıdır. Bu makalenin devamında yer alan bir örnek, bu davranışı geçersiz kılar.

Tek Seferlik Bağlamalar

Çeşitli özelliklerin OneTimeözelliği dahil olmak üzere IsTextPredictionEnabled varsayılan bağlama modu vardır Entry.

Bağlama modu OneTime olan hedef özellikler yalnızca bağlama bağlamı değiştiğinde güncelleştirilir. Bu hedef özelliklerdeki bağlamalar için bu, kaynak özelliklerdeki değişiklikleri izlemek gerekmediğinden bağlama altyapısını basitleştirir.

ViewModels ve Özellik Değiştirme Bildirimleri

Basit Renk Seçici sayfası, basit bir ViewModel kullanımını gösterir. Veri bağlamaları, kullanıcının ton, doygunluk ve parlaklık için üç Slider öğe kullanarak bir renk seçmesine olanak tanır.

ViewModel, veri bağlama kaynağıdır. ViewModel, bağlanabilir özellikleri tanımlamaz, ancak bir özelliğin değeri değiştiğinde bağlama altyapısının bilgilendirilmesini sağlayan bir bildirim mekanizması uygular. Bu bildirim mekanizması, adlı PropertyChangedtek bir olayı tanımlayan arabirimdirINotifyPropertyChanged. Bu arabirimi uygulayan bir sınıf genellikle ortak özelliklerinden biri değeri değiştirdiğinde olayı tetikler. Özelliğin hiçbir zaman değişmemesi durumunda olayın tetiklenmiş olması gerekmez. (Arabirimi INotifyPropertyChanged de tarafından BindableObject uygulanır ve PropertyChanged bir bağlanabilir özellik değeri değiştirildiğinde bir olay tetiklenir.)

HslColorViewModel sınıfı beş özellik tanımlar: Hue, Saturation, Luminosityve Color özellikleri birbiriyle ilişkilidir. Üç renk bileşeninden herhangi biri değeri değiştirdiğinde, Color özellik yeniden hesaplanır ve PropertyChanged dört özelliğin tümü için olaylar tetiklenir:

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

Color Özelliği değiştiğinde, sınıfındaki NamedColor statik GetNearestColorName yöntem (DataBindingDemos çözümüne de dahildir) en yakın adlandırılmış rengi alır ve özelliğini ayarlarName. Bu Name özelliğin özel set bir erişimcisi olduğundan sınıfın dışından ayarlanamaz.

Bir ViewModel bağlama kaynağı olarak ayarlandığında, bağlama altyapısı olaya bir işleyici PropertyChanged ekler. Bu şekilde bağlama, özelliklerdeki değişikliklerden haberdar edilebilir ve ardından değiştirilen değerlerden hedef özellikleri ayarlayabilir.

Ancak, bir hedef özelliğin (veya bir hedef özelliğindeki tanımın Binding OneTime) bir BindingMode 'i olduğunda, bağlama altyapısının olaya bir işleyici eklemesi PropertyChanged gerekli değildir. Hedef özellik yalnızca değiştiğinde BindingContext güncelleştirilir ve kaynak özelliğin kendisi değiştiğinde güncelleştirilmez.

Basit Renk Seçici XAML dosyası, sayfanın kaynak sözlüğünde öğesinin örneğini HslColorViewModel oluşturur ve özelliğini başlatırColor. BindingContext özelliğiGrid, bu kaynağa başvurmak için bağlama StaticResource uzantısına ayarlanır:

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

BoxView, Labelve üç Slider görünüm bağlama bağlamını öğesinden Griddevralır. Bu görünümlerin tümü ViewModel'deki kaynak özelliklere başvuran bağlama hedefleridir. Color özelliğinin BoxViewve Text özelliğinin Labelveri bağlamaları şunlardırOneWay: Görünümdeki özellikler ViewModel'deki özelliklerden ayarlanır.

Value Ancak özelliğinin SliderözelliğidirTwoWay. Bu, her Slider birinin ViewModel'den ve ayrıca ViewModel'in her Sliderbirinden ayarlanmasına olanak tanır.

Program ilk kez çalıştırıldığında, BoxView, ve üç Slider öğe, ViewModel örneği oluşturulurken ayarlanan ilk Color özellik temelinde ViewModel'den Labelayarlanır. Bu, soldaki iOS ekran görüntüsünde gösterilir:

Basit Renk Seçici

Kaydırıcıları değiştirdiğinizde veLabel, BoxView Android ekran görüntüsünde gösterildiği gibi uygun şekilde güncelleştirilir.

Kaynak sözlüğünde ViewModel örneği oluşturma yaygın bir yaklaşımdır. Özelliğin özellik öğesi etiketleri içinde ViewModel örneğini BindingContext de başlatmak mümkündür. Basit Renk Seçici XAML dosyasında, kaynak sözlüğünden öğesini kaldırmayı HslColorViewModel deneyin ve şunun BindingContext Grid özelliğine ayarlayın:

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

    ···

</Grid>

Bağlama bağlamı çeşitli yollarla ayarlanabilir. Bazen arka planda kod dosyası ViewModel örneğini oluşturur ve sayfanın özelliğine BindingContext ayarlar. Bunların tümü geçerli yaklaşımlardır.

Bağlama Modunu Geçersiz Kılma

Hedef özelliğindeki varsayılan bağlama modu belirli bir veri bağlaması için uygun değilse, öğesinin Binding özelliğini (veya işaretleme uzantısının Binding Mode özelliğini) numaralandırmanın BindingMode üyelerinden birine ayarlayarak Mode bunu geçersiz kılmak mümkündür.

Ancak özelliğini olarak Mode TwoWay ayarlamak her zaman beklediğiniz gibi çalışmaz. Örneğin, Alternatif XAML Bağlama XAML dosyasını bağlama tanımına eklenecek TwoWay şekilde değiştirmeyi deneyin:

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

özelliğinin Slider 1 olan ilk değerine Scale başlatılması beklenebilir, ancak bu gerçekleşmez. Bağlama TwoWay başlatıldığında hedef ilk olarak kaynaktan ayarlanır ve bu da özelliğin Scale varsayılan 0 değerine ayarlandığı Slider anlamına gelir. TwoWay Bağlama üzerinde SliderSlider ayarlandığında, ilk olarak kaynağından ayarlanır.

Bağlama modunu OneWayToSource Alternatif XAML Bağlama örneğinde olarak ayarlayabilirsiniz:

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

Şimdi değeri Slider 1 (varsayılan değeri Scale) olarak başlatılır, ancak öğesinin manipülesi Slider özelliği etkilemez Scale , bu nedenle bu çok kullanışlı değildir.

Not

VisualElement sınıfı ayrıca ScaleX ve ScaleY özelliklerini tanımlar. Bu özellikler, VisualElement öğesini yatay ve dikey yönlerde farklı biçimde ölçeklendirebilir.

ile TwoWay varsayılan bağlama modunu geçersiz kılmanın çok kullanışlı bir uygulaması özelliğini ListViewiçerirSelectedItem. Varsayılan bağlama modu şeklindedir OneWayToSource. ViewModel'deki bir kaynak özelliğe başvurmak için özelliğinde SelectedItem bir veri bağlama ayarlandığında, bu kaynak özellik seçimden ListView ayarlanır. Ancak bazı durumlarda, öğesinin ListView ViewModel'den başlatılmasını da isteyebilirsiniz.

Örnek Ayarlar sayfasında bu teknik gösterilir. Bu sayfa, bu dosya gibi SampleSettingsViewModel bir ViewModel'de çok sık tanımlanan uygulama ayarlarının basit bir uygulamasını temsil eder:

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

Her uygulama ayarı, adlı SaveState ve oluşturucudaki Xamarin.Forms bu sözlükten yüklenen bir yöntemde özellikler sözlüğüne kaydedilen bir özelliktir. Sınıfının en altına doğru ViewModel'leri kolaylaştırmaya yardımcı olan ve hatalara daha az eğilimli hale getiren iki yöntem vardır. Alttaki OnPropertyChanged yöntemin, çağıran özelliğine ayarlanmış isteğe bağlı bir parametresi vardır. Bu, özelliğin adını dize olarak belirtirken yazım hatalarını önler.

SetProperty sınıfındaki yöntemi daha da fazlasını yapar: Özelliğine ayarlanan değeri alan olarak depolanan değerle karşılaştırır ve yalnızca iki değer eşit olmadığında çağırırOnPropertyChanged.

SampleSettingsViewModel sınıfı arka plan rengi için iki özellik tanımlar: BackgroundNamedColor özelliği türündedir NamedColorve DataBindingDemos çözümüne de dahil edilen bir sınıftır. BackgroundColor özelliği türündedir Colorve nesnesinin Color özelliğinden NamedColor alınır.

sınıfı, NamedColor yapıdaki Xamarin.FormsColor tüm statik ortak alanları listelemek ve statik özelliğinden erişilebilen bir koleksiyonda adlarıyla depolamak için .NET yansımasını All kullanır:

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

App DataBindingDemos projesindeki sınıfı, türünde SampleSettingsViewModeladlı Settings bir özellik tanımlar. Bu özellik, sınıf örneği oluşturulurken App başlatılır ve SaveState yöntem çağrıldığında OnSleep yöntemi çağrılır:

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

Uygulama yaşam döngüsü yöntemleri hakkında daha fazla bilgi için Uygulama Yaşam Döngüsü makalesine bakın.

Diğer hemen her şey SampleSettingsPage.xaml dosyasında işlenir. BindingContext Sayfanın adı bir Binding işaretleme uzantısı kullanılarak ayarlanır: Bağlama kaynağı, projedeki sınıfın App örneği olan statik Application.Current özelliktir ve Path nesnesi olan SampleSettingsViewModel özelliğine Settings ayarlanır:

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

Sayfanın tüm alt öğeleri bağlama bağlamını devralır. Bu sayfadaki diğer bağlamaların çoğu içindeki SampleSettingsViewModelözelliklere yöneliktir. BackgroundColor özelliği, özelliğini StackLayoutayarlamak BackgroundColor için kullanılır ve Entry, DatePicker, Switchve Stepper özelliklerinin tümü ViewModel'deki diğer özelliklere bağlıdır.

ItemsSource özelliği ListView statik NamedColor.All özelliğine ayarlanır. Bu, öğesini ListView tüm NamedColor örneklerle doldurur. içindeki ListViewher öğe için öğenin bağlama bağlamı bir NamedColor nesne olarak ayarlanır. BoxView içindeki ViewCell ve Label içindeki özelliklerine NamedColorbağlıdır.

SelectedItem öğesinin ListView özelliği türündedir NamedColorve özelliğine BackgroundNamedColor SampleSettingsViewModelbağlıdır:

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

için SelectedItem varsayılan bağlama modu, seçili öğeden ViewModel özelliğini ayarlayan modudur OneWayToSource. Modu, TwoWay ViewModel'den başlatılmasını sağlar SelectedItem .

Ancak, SelectedItem bu şekilde ayarlandığında, ListView seçili öğeyi göstermek için otomatik olarak kaydırılmaz. Arka planda kod dosyasında küçük bir kod gereklidir:

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

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

Sol taraftaki iOS ekran görüntüsü, programı ilk kez çalıştırıldığında gösterir. içindeki SampleSettingsViewModel oluşturucu arka plan rengini beyaz olarak başlatır ve içinde seçilen ListViewbudur:

Örnek Ayarlar

Diğer ekran görüntüsünde değiştirilmiş ayarlar gösterilir. Bu sayfayla denemeler yaparken, programı uyku moduna geçirmeyi veya çalışmakta olduğu cihazda veya öykünücüde sonlandırmayı unutmayın. Visual Studio hata ayıklayıcısından programı sonlandırmak, sınıftaki geçersiz kılmanın OnSleep App çağrılmasına neden olmaz.

Sonraki makalede özelliğinde ayarlanan veri bağlamalarının Dize Biçimlendirmesini Labelbelirtmeyi Text öğreneceksiniz.