Bagikan melalui


Xamarin.Forms Pengikatan Dasar

Pengikatan Xamarin.Forms data menautkan sepasang properti di antara dua objek, setidaknya salah satunya biasanya merupakan objek antarmuka pengguna. Kedua objek ini disebut target dan sumbernya:

  • Target adalah objek (dan properti) tempat pengikatan data diatur.
  • Sumbernya adalah objek (dan properti) yang dirujuk oleh pengikatan data.

Perbedaan ini terkadang bisa sedikit membingungkan: Dalam kasus paling sederhana, data mengalir dari sumber ke target, yang berarti bahwa nilai properti target diatur dari nilai properti sumber. Namun, dalam beberapa kasus, data dapat secara alternatif mengalir dari target ke sumber, atau di kedua arah. Untuk menghindari kebingungan, perlu diingat bahwa target selalu merupakan objek tempat pengikatan data diatur meskipun menyediakan data daripada menerima data.

Pengikatan dengan Konteks Pengikatan

Meskipun pengikatan data biasanya ditentukan sepenuhnya dalam XAML, instruktif untuk melihat pengikatan data dalam kode. Halaman Pengikatan Kode Dasar berisi file XAML dengan Label dan Slider:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicCodeBindingPage"
             Title="Basic Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="48"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

Slider diatur untuk rentang 0 hingga 360. Tujuan dari program ini adalah untuk memutar dengan memanipulasi LabelSlider.

Tanpa pengikatan data, Anda akan mengatur ValueChanged peristiwa Slider ke penanganan aktivitas yang mengakses Value properti dan Slider menetapkan nilai tersebut ke Rotation properti .Label Pengikatan data mengotomatiskan pekerjaan tersebut; penanganan aktivitas dan kode di dalamnya tidak lagi diperlukan.

Anda dapat mengatur pengikatan pada instans kelas apa pun yang berasal dari BindableObject, yang mencakup Elementturunan , , VisualElementView, dan View . Pengikatan selalu diatur pada objek target. Pengikatan mereferensikan objek sumber. Untuk mengatur pengikatan data, gunakan dua anggota kelas target berikut:

Dalam contoh ini, Label adalah target pengikatan, dan Slider adalah sumber pengikatan. Perubahan sumber Slider memengaruhi rotasi Label target. Data mengalir dari sumber ke target.

Metode yang SetBinding ditentukan oleh BindableObject memiliki argumen jenis BindingBase dari mana Binding kelas berasal, tetapi ada metode lain SetBinding yang ditentukan oleh BindableObjectExtensions kelas. File code-behind dalam sampel Pengikatan Kode Dasar menggunakan metode ekstensi yang lebih SetBinding sederhana dari kelas ini.

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

        label.BindingContext = slider;
        label.SetBinding(Label.RotationProperty, "Value");
    }
}

Objek Label adalah target pengikatan sehingga itulah objek tempat properti ini diatur dan di mana metode dipanggil. Properti BindingContext menunjukkan sumber pengikatan, yaitu Slider.

Metode SetBinding ini dipanggil pada target pengikatan tetapi menentukan properti target dan properti sumber. Properti target ditentukan sebagai BindableProperty objek: Label.RotationProperty. Properti sumber ditentukan sebagai string dan menunjukkan Value properti .Slider

Metode ini SetBinding mengungkapkan salah satu aturan pengikatan data yang paling penting:

Properti target harus didukung oleh properti yang dapat diikat.

Aturan ini menyiratkan bahwa objek target harus merupakan instans kelas yang berasal dari BindableObject. Lihat artikel Properti yang Dapat Diikat untuk gambaran umum objek yang dapat diikat dan properti yang dapat diikat.

Tidak ada aturan seperti itu untuk properti sumber, yang ditentukan sebagai string. Secara internal, refleksi digunakan untuk mengakses properti aktual. Namun, dalam hal ini, Value properti juga didukung oleh properti yang dapat diikat.

Kode dapat disederhanakan agak: Properti RotationProperty yang dapat diikat ditentukan oleh VisualElement, dan diwariskan oleh Label dan ContentPage juga, sehingga nama kelas tidak diperlukan dalam SetBinding panggilan:

label.SetBinding(RotationProperty, "Value");

Namun, termasuk nama kelas adalah pengingat yang baik tentang objek target.

Saat Anda memanipulasi Slider, rotasi Label yang sesuai:

Pengikatan Kode Dasar

Halaman Pengikatan Xaml Dasar identik dengan Pengikatan Kode Dasar kecuali mendefinisikan seluruh pengikatan data di XAML:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicXamlBindingPage"
             Title="Basic XAML Binding">
    <StackLayout Padding="10, 0">
        <Label Text="TEXT"
               FontSize="80"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand"
               BindingContext="{x:Reference Name=slider}"
               Rotation="{Binding Path=Value}" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

Sama seperti dalam kode, pengikatan data diatur pada objek target, yaitu Label. Dua ekstensi markup XAML terlibat. Ini langsung dikenali oleh pemisah kurung kurawal:

  • Ekstensi x:Reference markup diperlukan untuk mereferensikan objek sumber, yang bernama Sliderslider.
  • Ekstensi Binding markup menautkan Rotation properti ke LabelValue properti .Slider

Lihat artikel Ekstensi Markup XAML untuk informasi selengkapnya tentang ekstensi markup XAML. Ekstensi x:Reference markup didukung oleh ReferenceExtension kelas; Binding didukung oleh BindingExtension kelas . Seperti yang ditunjukkan oleh awalan namespace XML, x:Reference adalah bagian dari spesifikasi XAML 2009, sementara Binding merupakan bagian Xamarin.Formsdari . Perhatikan bahwa tidak ada tanda kutip yang muncul dalam kurung kurawal.

Mudah untuk melupakan x:Reference ekstensi markup saat mengatur BindingContext. Umum untuk secara keliru mengatur properti langsung ke nama sumber pengikatan seperti ini:

BindingContext="slider"

Tapi itu tidak benar. Markup tersebut mengatur properti ke BindingContextstring objek yang karakternya mengeja "penggelis"!

Perhatikan bahwa properti sumber ditentukan dengan Path properti BindingExtension, yang sesuai dengan Path properti Binding kelas.

Markup yang ditampilkan pada halaman Pengikatan XAML Dasar dapat disederhanakan: Ekstensi markup XAML seperti x:Reference dan Binding dapat memiliki atribut properti konten yang ditentukan, yang untuk ekstensi markup XAML berarti bahwa nama properti tidak perlu muncul. Properti Name adalah properti konten , x:Referencedan Path properti adalah properti konten dari Binding, yang berarti bahwa properti tersebut dapat dihilangkan dari ekspresi:

<Label Text="TEXT"
       FontSize="80"
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand"
       BindingContext="{x:Reference slider}"
       Rotation="{Binding Value}" />

Pengikatan tanpa Konteks Pengikatan

Properti BindingContext adalah komponen penting dari pengikatan data, tetapi tidak selalu diperlukan. Objek sumber dapat ditentukan dalam SetBinding panggilan atau Binding ekstensi markup.

Ini ditunjukkan dalam sampel Pengikatan Kode Alternatif. File XAML mirip dengan sampel Pengikatan Kode Dasar kecuali bahwa Slider didefinisikan untuk mengontrol Scale properti .Label Untuk alasan itu Slider , diatur untuk rentang –2 hingga 2:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeCodeBindingPage"
             Title="Alternative Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

File code-behind mengatur pengikatan dengan metode yang SetBinding ditentukan oleh BindableObject. Argumen adalah konstruktor untuk Binding kelas :

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

        label.SetBinding(Label.ScaleProperty, new Binding("Value", source: slider));
    }
}

Binding Konstruktor memiliki 6 parameter, sehingga source parameter ditentukan dengan argumen bernama. Argumen adalah slider objek .

Menjalankan program ini mungkin sedikit mengejutkan:

Pengikatan Kode Alternatif

Layar iOS di sebelah kiri menunjukkan tampilan layar saat halaman pertama kali muncul. Dimana ?Label

Masalahnya adalah bahwa Slider memiliki nilai awal 0. Ini menyebabkan Scale properti yang Label juga diatur ke 0, mengganti nilai defaultnya 1. Ini menghasilkan Label awalnya tidak terlihat. Seperti yang ditunjukkan oleh tangkapan layar Android, Anda dapat memanipulasi Slider untuk membuat Label muncul lagi, tetapi hilangnya awalnya memisahkan.

Anda akan menemukan di artikel berikutnya cara menghindari masalah ini dengan menginisialisasi Slider dari nilai Scale default properti.

Catatan

Kelas ini VisualElement juga mendefinisikan dan ScaleY properti, yang dapat menskalakan ScaleXVisualElement secara berbeda dalam arah horizontal dan vertikal.

Halaman Pengikatan XAML Alternatif menunjukkan pengikatan yang setara sepenuhnya di XAML:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeXamlBindingPage"
             Title="Alternative XAML Binding">
    <StackLayout Padding="10, 0">
        <Label Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand"
               Scale="{Binding Source={x:Reference slider},
                               Path=Value}" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

Binding Sekarang ekstensi markup memiliki dua kumpulan properti, Source dan Path, dipisahkan oleh koma. Mereka dapat muncul di baris yang sama jika Anda lebih suka:

Scale="{Binding Source={x:Reference slider}, Path=Value}" />

Properti Source diatur ke ekstensi markup tersemat x:Reference yang jika tidak memiliki sintaks yang sama dengan mengatur BindingContext. Perhatikan bahwa tidak ada tanda kutip yang muncul dalam kurung kurawal, dan bahwa kedua properti harus dipisahkan oleh koma.

Properti Binding konten ekstensi markup adalah Path, tetapi Path= bagian dari ekstensi markup hanya dapat dihilangkan jika ini adalah properti pertama dalam ekspresi. Untuk menghilangkan bagian tersebut Path= , Anda perlu menukar dua properti:

Scale="{Binding Value, Source={x:Reference slider}}" />

Meskipun ekstensi markup XAML biasanya dibatasi oleh kurung kurawal, ekstensi markup XAML juga dapat diekspresikan sebagai elemen objek:

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

Source Sekarang properti dan Path adalah atribut XAML reguler: Nilai muncul dalam tanda kutip dan atribut tidak dipisahkan oleh koma. Ekstensi x:Reference markup juga dapat menjadi elemen objek:

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand">
    <Label.Scale>
        <Binding Path="Value">
            <Binding.Source>
                <x:Reference Name="slider" />
            </Binding.Source>
        </Binding>
    </Label.Scale>
</Label>

Sintaks ini tidak umum, tetapi terkadang diperlukan ketika objek kompleks terlibat.

Contoh yang diperlihatkan sejauh ini mengatur BindingContext properti dan Source properti ke Bindingx:Reference ekstensi markup untuk mereferensikan tampilan lain di halaman. Kedua properti ini berjenis Object, dan dapat diatur ke objek apa pun yang mencakup properti yang cocok untuk sumber pengikatan.

Dalam artikel di depan, Anda akan menemukan bahwa Anda dapat mengatur BindingContext properti atau Source ke x:Static ekstensi markup untuk mereferensikan nilai properti atau bidang statis, atau StaticResource ekstensi markup untuk mereferensikan objek yang disimpan dalam kamus sumber daya, atau langsung ke objek, yang umumnya (tetapi tidak selalu) instans ViewModel.

BindingContext Properti juga dapat diatur ke Binding objek sehingga Source properti dan Path menentukan Binding konteks pengikatan.

Pewarisan Konteks Pengikatan

Dalam artikel ini, Anda telah melihat bahwa Anda dapat menentukan objek sumber menggunakan BindingContext properti atau Source properti Binding objek. Jika keduanya diatur, Source properti yang Binding lebih diutamakan daripada BindingContext.

Properti BindingContext ini memiliki karakteristik yang sangat penting:

Pengaturan BindingContext properti diwariskan melalui pohon visual.

Seperti yang akan Anda lihat, ini bisa sangat berguna untuk menyederhanakan ekspresi pengikatan, dan dalam beberapa kasus — terutama dalam skenario Model-View-ViewModel (MVVM) - sangat penting.

Sampel Warisan Konteks Pengikatan adalah demonstrasi sederhana dari warisan konteks pengikatan:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BindingContextInheritancePage"
             Title="BindingContext Inheritance">
    <StackLayout Padding="10">

        <StackLayout VerticalOptions="FillAndExpand"
                     BindingContext="{x:Reference slider}">

            <Label Text="TEXT"
                   FontSize="80"
                   HorizontalOptions="Center"
                   VerticalOptions="EndAndExpand"
                   Rotation="{Binding Value}" />

            <BoxView Color="#800000FF"
                     WidthRequest="180"
                     HeightRequest="40"
                     HorizontalOptions="Center"
                     VerticalOptions="StartAndExpand"
                     Rotation="{Binding Value}" />
        </StackLayout>

        <Slider x:Name="slider"
                Maximum="360" />

    </StackLayout>
</ContentPage>

Properti BindingContext diatur StackLayout ke slider objek . Konteks pengikatan ini diwariskan oleh Label dan BoxView, yang keduanya memiliki properti yang Rotation diatur ke Value properti Sliderdari :

Pewarisan Konteks Pengikatan

Di artikel berikutnya, Anda akan melihat bagaimana mode pengikatan dapat mengubah aliran data antara objek target dan sumber.

Temukan video Xamarin lainnya di Channel 9 dan YouTube.