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 Label
Slider
.
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 Element
turunan , , VisualElement
View
, dan View
. Pengikatan selalu diatur pada objek target. Pengikatan mereferensikan objek sumber. Untuk mengatur pengikatan data, gunakan dua anggota kelas target berikut:
- Properti
BindingContext
menentukan objek sumber. - Metode
SetBinding
menentukan properti target dan properti sumber.
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:
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 bernamaSlider
slider
. - Ekstensi
Binding
markup menautkanRotation
properti keLabel
Value
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 BindingContext
string
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:Reference
dan 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:
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 ScaleX
VisualElement
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 Binding
x: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 Slider
dari :
Di artikel berikutnya, Anda akan melihat bagaimana mode pengikatan dapat mengubah aliran data antara objek target dan sumber.