Bagian 1. Memulai XAML
Dalam aplikasi Xamarin.Forms , XAML sebagian besar digunakan untuk menentukan konten visual halaman dan bekerja sama dengan file kode C# di belakang.
File code-behind menyediakan dukungan kode untuk markup. Bersama-sama, kedua file ini berkontribusi pada definisi kelas baru yang mencakup tampilan anak dan inisialisasi properti. Dalam file XAML, kelas dan properti direferensikan dengan elemen dan atribut XML, dan tautan antara markup dan kode dibuat.
Membuat Solusi
Untuk mulai mengedit file XAML pertama Anda, gunakan Visual Studio atau Visual Studio untuk Mac untuk membuat solusi baru Xamarin.Forms . (Pilih tab di bawah ini yang sesuai dengan lingkungan Anda.)
Di Windows, luncurkan Visual Studio 2019, dan di jendela mulai klik Buat proyek baru untuk membuat proyek baru:
Di jendela Buat proyek baru, pilih Seluler di menu drop-down Jenis proyek, pilih templat Aplikasi Seluler (Xamarin.Forms), dan klik tombol Berikutnya :
Di jendela Konfigurasikan proyek baru Anda, atur Nama proyek ke XamlSamples (atau apa pun pilihan Anda), dan klik tombol Buat.
Dalam dialog Aplikasi Lintas Platform Baru, klik Kosong, dan klik tombol OK:
Empat proyek dibuat dalam solusi: pustaka XamlSamples .NET Standard, XamlSamples.Android, XamlSamples.iOS, dan solusi Platform Windows Universal, XamlSamples.UWP.
Setelah membuat solusi XamlSamples , Anda mungkin ingin menguji lingkungan pengembangan dengan memilih berbagai proyek platform sebagai proyek startup solusi, dan membangun dan menyebarkan aplikasi sederhana yang dibuat oleh templat proyek di emulator telepon atau perangkat nyata.
Kecuali Anda perlu menulis kode khusus platform, proyek pustaka XamlSamples .NET Standard bersama adalah tempat Anda akan menghabiskan hampir semua waktu pemrograman Anda. Artikel-artikel ini tidak akan berdasar di luar proyek tersebut.
Anatomi File XAML
Dalam pustaka XamlSamples .NET Standard adalah sepasang file dengan nama berikut:
- App.xaml, file XAML; dan
- App.xaml.cs, file kode C# di belakang yang terkait dengan file XAML.
Anda harus mengklik panah di samping App.xaml untuk melihat file code-behind.
App.xaml dan App.xaml.cs berkontribusi pada kelas bernama App
yang berasal dari Application
. Sebagian besar kelas lain dengan file XAML berkontribusi pada kelas yang berasal dari ContentPage
; file tersebut menggunakan XAML untuk menentukan konten visual seluruh halaman. Ini benar dari dua file lain dalam proyek XamlSamples :
- MainPage.xaml, file XAML; dan
- MainPage.xaml.cs, file C# code-behind.
File MainPage.xaml terlihat seperti ini (meskipun pemformatannya mungkin sedikit berbeda):
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamlSamples"
x:Class="XamlSamples.MainPage">
<StackLayout>
<!-- Place new controls here -->
<Label Text="Welcome to Xamarin Forms!"
VerticalOptions="Center"
HorizontalOptions="Center" />
</StackLayout>
</ContentPage>
Dua deklarasi namespace XML (xmlns
) mengacu pada URI, yang pertama tampaknya di situs web Xamarin dan yang kedua di Microsoft. Jangan repot-repot memeriksa tujuan URI tersebut. Tidak ada apa-apa di sana. Mereka hanya URI yang dimiliki oleh Xamarin dan Microsoft, dan pada dasarnya berfungsi sebagai pengidentifikasi versi.
Deklarasi namespace XML pertama berarti bahwa tag yang ditentukan dalam file XAML tanpa awalan mengacu pada kelas di Xamarin.Forms, misalnya ContentPage
. Deklarasi namespace kedua mendefinisikan awalan .x
Ini digunakan untuk beberapa elemen dan atribut yang intrinsik untuk XAML itu sendiri dan yang didukung oleh implementasi XAML lainnya. Namun, elemen dan atribut ini sedikit berbeda tergantung pada tahun yang disematkan dalam URI. Xamarin.Forms mendukung spesifikasi XAML 2009, tetapi tidak semuanya.
local
Deklarasi namespace memungkinkan Anda mengakses kelas lain dari proyek pustaka .NET Standard.
Di akhir tag pertama tersebut, awalan x
digunakan untuk atribut bernama Class
. Karena penggunaan awalan ini x
hampir universal untuk namespace XAML, atribut XAML seperti Class
hampir selalu disebut sebagai x:Class
.
Atribut x:Class
menentukan nama kelas .NET yang sepenuhnya memenuhi syarat: MainPage
kelas di XamlSamples
namespace. Ini berarti bahwa file XAML ini mendefinisikan kelas baru bernama MainPage
di XamlSamples
namespace layanan yang berasal dari ContentPage
—tag tempat x:Class
atribut muncul.
Atribut x:Class
hanya dapat muncul di elemen akar file XAML untuk menentukan kelas C# turunan. Ini adalah satu-satunya kelas baru yang ditentukan dalam file XAML. Segala sesuatu yang muncul dalam file XAML hanya dibuat dari kelas yang ada dan diinisialisasi.
File MainPage.xaml.cs terlihat seperti ini (selain dari arahan yang tidak digunakan using
):
using Xamarin.Forms;
namespace XamlSamples
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
}
Kelas MainPage
berasal dari ContentPage
, tetapi perhatikan partial
definisi kelas. Ini menunjukkan bahwa harus ada definisi kelas parsial lain untuk MainPage
, tetapi di mana itu? Dan metode apa itu InitializeComponent
?
Saat Visual Studio membangun proyek, Visual Studio mengurai file XAML untuk menghasilkan file kode C#. Jika Anda melihat direktori XamlSamples\XamlSamples\obj\Debug , Anda akan menemukan file bernama XamlSamples.MainPage.xaml.g.cs. 'g' adalah singkatan dari yang dihasilkan. Ini adalah definisi kelas parsial lainnya yang MainPage
berisi definisi metode yang InitializeComponent
disebut dari MainPage
konstruktor. Kedua definisi kelas parsial MainPage
ini kemudian dapat dikompilasi bersama-sama. Tergantung pada apakah XAML dikompilasi atau tidak, baik file XAML atau bentuk biner file XAML disematkan dalam file yang dapat dieksekusi.
Pada runtime, kode dalam proyek platform tertentu memanggil metode, meneruskannya instans LoadApplication
App
baru kelas di pustaka .NET Standard. Konstruktor App
kelas membuat instans MainPage
. Konstruktor dari kelas tersebut memanggil InitializeComponent
, yang kemudian memanggil LoadFromXaml
metode yang mengekstrak file XAML (atau biner yang dikompilasi) dari pustaka Standar .NET. LoadFromXaml
menginisialisasi semua objek yang ditentukan dalam file XAML, menghubungkan semuanya bersama-sama dalam hubungan induk-anak, melampirkan penanganan aktivitas yang ditentukan dalam kode ke peristiwa yang diatur dalam file XAML, dan mengatur pohon objek yang dihasilkan sebagai konten halaman.
Meskipun Anda biasanya tidak perlu menghabiskan banyak waktu dengan file kode yang dihasilkan, terkadang pengecualian runtime dinaikkan pada kode dalam file yang dihasilkan, jadi Anda harus terbiasa dengannya.
Saat Anda mengkompilasi dan menjalankan program ini, Label
elemen muncul di tengah halaman seperti yang disarankan XAML:
Untuk visual yang lebih menarik, yang Anda butuhkan adalah XAML yang lebih menarik.
Menambahkan Halaman XAML Baru
Untuk menambahkan kelas berbasis ContentPage
XAML lainnya ke proyek Anda, pilih proyek pustaka XamlSamples .NET Standard, klik kanan, dan pilih Tambahkan > Item Baru.... Dalam dialog Tambahkan Item Baru, pilih Halaman Konten Item >>Xamarin.FormsVisual C# (bukan Halaman Konten (C#), yang membuat halaman khusus kode, atau Tampilan Konten, yang bukan halaman). Beri nama halaman, misalnya, HelloXamlPage:
Dua file ditambahkan ke proyek, HelloXamlPage.xaml dan file code-behind HelloXamlPage.xaml.cs.
Menyetel Isi Halaman
Edit file HelloXamlPage.xaml sehingga satu-satunya tag adalah tag untuk ContentPage
dan ContentPage.Content
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.HelloXamlPage">
<ContentPage.Content>
</ContentPage.Content>
</ContentPage>
Tag ContentPage.Content
adalah bagian dari sintaksis unik XAML. Pada awalnya, xml mungkin tampak tidak valid, tetapi bersifat legal. Periode bukan karakter khusus dalam XML.
Tag ContentPage.Content
disebut tag elemen properti. Content
adalah properti , ContentPage
dan umumnya diatur ke satu tampilan atau tata letak dengan tampilan anak. Biasanya properti menjadi atribut di XAML, tetapi akan sulit untuk mengatur Content
atribut ke objek yang kompleks. Untuk alasan itu, properti dinyatakan sebagai elemen XML yang terdiri dari nama kelas dan nama properti yang dipisahkan oleh titik. Content
Sekarang properti dapat diatur di ContentPage.Content
antara tag, seperti ini:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.HelloXamlPage"
Title="Hello XAML Page">
<ContentPage.Content>
<Label Text="Hello, XAML!"
VerticalOptions="Center"
HorizontalTextAlignment="Center"
Rotation="-15"
IsVisible="true"
FontSize="Large"
FontAttributes="Bold"
TextColor="Blue" />
</ContentPage.Content>
</ContentPage>
Perhatikan juga bahwa Title
atribut telah diatur pada tag akar.
Saat ini, hubungan antara kelas, properti, dan XML harus terbukti: Kelas Xamarin.Forms (seperti ContentPage
atau Label
) muncul dalam file XAML sebagai elemen XML. Properti kelas tersebut—termasuk Title
di ContentPage
dan tujuh properti Label
—biasanya muncul sebagai atribut XML.
Banyak pintasan yang ada untuk mengatur nilai properti ini. Beberapa properti adalah jenis data dasar: Misalnya, properti dan berjenis String
, Rotation
berjenis Double
, dan IsVisible
(yang true
secara default dan diatur di sini hanya untuk ilustrasi) berjenis Boolean
.Text
Title
Properti HorizontalTextAlignment
berjenis TextAlignment
, yang merupakan enumerasi. Untuk properti dari jenis enumerasi apa pun, yang perlu Anda berikan adalah nama anggota.
Namun, untuk properti dari jenis yang lebih kompleks, konverter digunakan untuk mengurai XAML. Ini adalah kelas dalam Xamarin.Forms yang berasal dari TypeConverter
. Banyak yang kelas publik tetapi beberapa tidak. Untuk file XAML khusus ini, beberapa kelas ini memainkan peran di belakang layar:
LayoutOptionsConverter
VerticalOptions
untuk propertiFontSizeConverter
FontSize
untuk propertiColorTypeConverter
TextColor
untuk properti
Pengonversi ini mengatur sintaks pengaturan properti yang diizinkan.
dapat ThicknessTypeConverter
menangani satu, dua, atau empat angka yang dipisahkan oleh koma. Jika satu angka disediakan, itu berlaku untuk keempat sisi. Dengan dua angka, yang pertama adalah padding kiri dan kanan, dan yang kedua adalah atas dan bawah. Empat angka berada dalam urutan kiri, atas, kanan, dan bawah.
LayoutOptionsConverter
dapat mengonversi nama bidang statis publik dari LayoutOptions
struktur menjadi nilai jenis LayoutOptions
.
FontSizeConverter
dapat menangani NamedSize
anggota atau ukuran font numerik.
ColorTypeConverter
menerima nama bidang statis publik dari Color
struktur atau nilai RGB heksadesimal, dengan atau tanpa saluran alfa, didahului dengan tanda angka (#). Berikut sintaks tanpa saluran alfa:
TextColor="#rrggbb"
Masing-masing huruf kecil adalah digit heksadesimal. Berikut adalah bagaimana saluran alfa disertakan:
TextColor="#aarrggbb">
Untuk saluran alfa, perlu diingat bahwa FF sepenuhnya buram dan 00 sepenuhnya transparan.
Dua format lainnya memungkinkan Anda menentukan hanya satu digit heksadesimal untuk setiap saluran:
TextColor="#rgb"
TextColor="#argb"
Dalam kasus ini, digit diulang untuk membentuk nilai . Misalnya, #CF3 adalah warna RGB CC-FF-33.
Navigasi Halaman
Saat Anda menjalankan program XamlSamples , MainPage
program ditampilkan. Untuk melihat yang baru HelloXamlPage
, Anda dapat mengaturnya sebagai halaman startup baru di file App.xaml.cs , atau menavigasi ke halaman baru dari MainPage
.
Untuk menerapkan navigasi, pertama-tama ubah kode di konstruktor App.xaml.cs sehingga NavigationPage
objek dibuat:
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
Di konstruktor MainPage.xaml.cs, Anda dapat membuat yang sederhana Button
dan menggunakan penanganan aktivitas untuk menavigasi ke HelloXamlPage
:
public MainPage()
{
InitializeComponent();
Button button = new Button
{
Text = "Navigate!",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
};
button.Clicked += async (sender, args) =>
{
await Navigation.PushAsync(new HelloXamlPage());
};
Content = button;
}
Content
Mengatur properti halaman menggantikan pengaturan Content
properti dalam file XAML. Saat Anda mengkompilasi dan menyebarkan versi baru program ini, tombol akan muncul di layar. Menekannya menavigasi ke HelloXamlPage
. Berikut adalah halaman yang dihasilkan di i Telepon, Android, dan UWP:
Anda dapat menavigasi kembali menggunakan MainPage
< tombol Kembali di iOS, menggunakan panah kiri di bagian atas halaman atau di bagian bawah ponsel di Android, atau menggunakan panah kiri di bagian atas halaman pada Windows 10.
Jangan ragu untuk bereksperimen dengan XAML untuk berbagai cara untuk merender Label
. Jika Anda perlu menyematkan karakter Unicode apa pun ke dalam teks, Anda dapat menggunakan sintaks XML standar. Misalnya, untuk meletakkan salam dalam tanda kutip cerdas, gunakan:
<Label Text="“Hello, XAML!”" … />
Berikut tampilannya:
Interaksi XAML dan Kode
Sampel HelloXamlPage hanya berisi satu Label
di halaman, tetapi ini sangat tidak biasa. Sebagian besar ContentPage
turunan mengatur Content
properti ke tata letak semacam itu, seperti StackLayout
. Properti Children
dari StackLayout
didefinisikan berjenis IList<View>
tetapi sebenarnya merupakan objek jenis ElementCollection<View>
, dan koleksi tersebut dapat diisi dengan beberapa tampilan atau tata letak lainnya. Di XAML, hubungan induk-turunan ini dibuat dengan hierarki XML normal. Berikut adalah file XAML untuk halaman baru bernama XamlPlusCodePage:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.XamlPlusCodePage"
Title="XAML + Code Page">
<StackLayout>
<Slider VerticalOptions="CenterAndExpand" />
<Label Text="A simple Label"
Font="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Button Text="Click Me!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>
File XAML ini secara sintis selesai, dan seperti inilah tampilannya:
Namun, Anda cenderung menganggap program ini kekurangan fungsional. Slider
Mungkin yang seharusnya menyebabkan Label
menampilkan nilai saat ini, dan Button
mungkin dimaksudkan untuk melakukan sesuatu dalam program.
Seperti yang akan Anda lihat di Bagian 4. Dasar-Dasar Pengikatan Data, pekerjaan menampilkan Slider
nilai menggunakan Label
dapat ditangani sepenuhnya di XAML dengan pengikatan data. Tetapi berguna untuk melihat solusi kode terlebih dahulu. Meskipun demikian, menangani Button
klik pasti memerlukan kode. Ini berarti bahwa file code-behind untuk XamlPlusCodePage
harus berisi handler untuk ValueChanged
peristiwa Slider
dan Clicked
peristiwa Button
. Mari kita tambahkan:
namespace XamlSamples
{
public partial class XamlPlusCodePage
{
public XamlPlusCodePage()
{
InitializeComponent();
}
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
}
void OnButtonClicked(object sender, EventArgs args)
{
}
}
}
Penanganan aktivitas ini tidak perlu di publik.
Kembali ke file XAML, Slider
tag dan Button
perlu menyertakan atribut untuk ValueChanged
peristiwa dan Clicked
yang mereferensikan handler ini:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.XamlPlusCodePage"
Title="XAML + Code Page">
<StackLayout>
<Slider VerticalOptions="CenterAndExpand"
ValueChanged="OnSliderValueChanged" />
<Label Text="A simple Label"
Font="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Button Text="Click Me!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Clicked="OnButtonClicked" />
</StackLayout>
</ContentPage>
Perhatikan bahwa menetapkan handler ke peristiwa memiliki sintaks yang sama dengan menetapkan nilai ke properti.
Jika handler untuk ValueChanged
peristiwa Slider
akan menggunakan Label
untuk menampilkan nilai saat ini, handler perlu mereferensikan objek tersebut dari kode. Membutuhkan Label
nama, yang ditentukan dengan x:Name
atribut .
<Label x:Name="valueLabel"
Text="A simple Label"
Font="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
Awalan x
x:Name
atribut menunjukkan bahwa atribut ini intrinsik dengan XAML.
Nama yang Anda tetapkan ke x:Name
atribut memiliki aturan yang sama dengan nama variabel C#. Misalnya, harus dimulai dengan huruf atau garis bawah dan tidak berisi spasi yang disematkan.
Sekarang penanganan ValueChanged
aktivitas dapat mengatur Label
untuk menampilkan nilai baru Slider
. Nilai baru tersedia dari argumen peristiwa:
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
valueLabel.Text = args.NewValue.ToString("F3");
}
Atau, handler dapat memperoleh Slider
objek yang menghasilkan peristiwa ini dari sender
argumen dan mendapatkan Value
properti dari itu:
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
valueLabel.Text = ((Slider)sender).Value.ToString("F3");
}
Ketika Anda pertama kali menjalankan program, Label
tidak menampilkan Slider
nilai karena ValueChanged
peristiwa belum diaktifkan. Tetapi setiap manipulasi penyebab Slider
nilai ditampilkan:
Sekarang untuk Button
. Mari kita simulasi respons terhadap Clicked
peristiwa dengan menampilkan pemberitahuan dengan tombol Text
. Penanganan aktivitas dapat dengan aman melemparkan sender
argumen ke dan Button
kemudian mengakses propertinya:
async void OnButtonClicked(object sender, EventArgs args)
{
Button button = (Button)sender;
await DisplayAlert("Clicked!",
"The button labeled '" + button.Text + "' has been clicked",
"OK");
}
Metode ini didefinisikan sebagai async
karena DisplayAlert
metode ini asinkron dan harus diawali dengan await
operator, yang kembali ketika metode selesai. Karena metode ini mendapatkan Button
peristiwa penembakan dari sender
argumen, handler yang sama dapat digunakan untuk beberapa tombol.
Anda telah melihat bahwa objek yang ditentukan dalam XAML dapat mengaktifkan peristiwa yang ditangani dalam file code-behind, dan bahwa file code-behind dapat mengakses objek yang ditentukan dalam XAML menggunakan nama yang ditetapkan untuknya dengan x:Name
atribut . Ini adalah dua cara mendasar bahwa kode dan XAML berinteraksi.
Beberapa wawasan tambahan tentang cara kerja XAML dapat dipancarkan dengan memeriksa file XamlPlusCode.xaml.g.cs yang baru dibuat, yang sekarang menyertakan nama apa pun yang ditetapkan ke atribut apa pun x:Name
sebagai bidang privat. Berikut adalah versi file yang disederhanakan:
public partial class XamlPlusCodePage : ContentPage {
private Label valueLabel;
private void InitializeComponent() {
this.LoadFromXaml(typeof(XamlPlusCodePage));
valueLabel = this.FindByName<Label>("valueLabel");
}
}
Deklarasi bidang ini memungkinkan variabel untuk digunakan secara bebas di mana saja dalam XamlPlusCodePage
file kelas parsial di bawah yurisdiksi Anda. Pada runtime, bidang ditetapkan setelah XAML diurai. Ini berarti bahwa valueLabel
bidang adalah null
ketika XamlPlusCodePage
konstruktor dimulai tetapi valid setelah InitializeComponent
dipanggil.
Setelah InitializeComponent
mengembalikan kontrol kembali ke konstruktor, visual halaman telah dibangun seolah-olah telah dibuat dan diinisialisasi dalam kode. File XAML tidak lagi memainkan peran apa pun di kelas . Anda dapat memanipulasi objek ini di halaman dengan cara apa pun yang Anda inginkan, misalnya, dengan menambahkan tampilan ke StackLayout
, atau mengatur Content
properti halaman ke sesuatu yang lain sepenuhnya. Anda dapat "berjalan di pohon" dengan memeriksa Content
properti halaman dan item dalam Children
koleksi tata letak. Anda dapat mengatur properti pada tampilan yang diakses dengan cara ini, atau menetapkan penanganan aktivitas kepada mereka secara dinamis.
Jangan ragu. Ini adalah halaman Anda, dan XAML hanyalah alat untuk membangun kontennya.
Ringkasan
Dengan pengenalan ini, Anda telah melihat bagaimana file XAML dan file kode berkontribusi pada definisi kelas, dan bagaimana XAML dan file kode berinteraksi. Tetapi XAML juga memiliki fitur sintetis unik sendiri yang memungkinkannya digunakan dengan cara yang sangat fleksibel. Anda dapat mulai menjelajahi ini di Bagian 2. Sintaks XAML penting.