Bagikan melalui


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:

Jendela Solusi Baru

Di jendela Buat proyek baru, pilih Seluler di menu drop-down Jenis proyek, pilih templat Aplikasi Seluler (Xamarin.Forms), dan klik tombol Berikutnya :

Jendela Proyek Baru

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:

Dialog Aplikasi Baru

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

Tampilan default Xamarin.Forms

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:

Dialog Tambahkan Item Baru

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 , ContentPagedan 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.TextTitle

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:

  • LayoutOptionsConverterVerticalOptions untuk properti
  • FontSizeConverterFontSize untuk properti
  • ColorTypeConverterTextColor 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.

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:

Teks Label Yang Diputar

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="&#x201C;Hello, XAML!&#x201D;" … />

Berikut tampilannya:

Teks Label Yang Diputar dengan Karakter Unicode

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:

Beberapa Kontrol pada Halaman

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

Nilai Penggerak 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.