Pengikatan data dengan jenis yang tidak cocok

Selesai

Terkadang data yang Anda gunakan tidak cocok dengan jenis data properti kontrol yang menampilkan data. Misalnya, Anda mungkin memiliki nilai moneter yang decimal disimpan dalam jenis yang ingin Anda tampilkan pada kontrol, yang diformat Label sebagai mata uang. Contoh yang lebih rumit adalah dengan aplikasi cuaca yang disajikan dalam modul. Gambar seharusnya ditampilkan berdasarkan nilai prakiraan Sunny cuaca atau Cloudy enumerasi, tetapi Anda tidak dapat mengikat nilai enumerasi sumber ke properti gambar target. Unit ini melihat cara Anda dapat mengonversi data.

Pemformatan string

Tipe umum tidak cocok adalah jenis intrinsik yang ingin Anda tampilkan sebagai string yang diformat. Seperti saat Anda ingin menampilkan bagian dari DateTime nilai, atau Anda ingin memformat decimal jenis sebagai mata uang.

Misalkan Anda ingin menampilkan jumlah yang jatuh tempo pada tagihan dan Anda memiliki properti ini pada objek data Anda:

public decimal BillAmount { get; set; }

Jumlah yang terutang akhirnya menjadi 22.0304. Anda mungkin menggunakan dua kontrol label untuk menampilkan beberapa teks dan jumlah dolar seperti yang ditunjukkan dalam cuplikan berikut:

<HorizontalStackLayout>
    <Label Text="You owe" Margin="0,0,5,0" />
    <Label Text="{Binding BillAmount}" />
    <Label Text="to the bank" Margin="5,0,0,0" />
</HorizontalStackLayout>

Ini menghasilkan string ke UI yang terlihat seperti You owe 22.0304 to the bank, tetapi kehilangan simbol mata uang dan mungkin ada terlalu banyak atau terlalu sedikit tempat desimal berdasarkan mata uang lokal. Biasanya Anda akan memproses nilai sebagai string dengan penentu format "C" (atau mata uang) dalam kode, seperti:

string formattedBillAmount = string.Format("{0:C}", BillAmount);

Tetapi untuk menggunakan pemformatan dalam pengikatan data, Anda harus memiliki objek data yang memberi Anda string yang diformat sebagai properti yang berbeda, atau mencegatnya dan memformatnya sendiri. Untungnya, pengikatan .NET MAUI menyediakan cara untuk memformat string dengan StringFormat properti pengikatan. String format mengikuti aturan yang sama dengan String.Format metode . Sertakan string format dalam tanda kutip tunggal sehingga pengurai XAML tidak bingung oleh kurung kurawal. Parameter 0 format string adalah nilai properti yang diproses oleh pengikatan.

<Label Text="{Binding BillAmount, StringFormat='You owe {0:C} to the bank'}" />

Pertimbangkan XAML berikut, yang menunjukkan menampilkan BillAmount penggunaan kedua cara:

<VerticalStackLayout Padding="10">
    <HorizontalStackLayout>
        <Label Text="You owe" Margin="0,0,5,0" />
        <Label Text="{Binding BillAmount}" />
        <Label Text="to the bank" Margin="5,0,0,0" />
    </HorizontalStackLayout>
    <HorizontalStackLayout>
        <Label Text="{Binding BillAmount, StringFormat='You owe {0:C} to the bank'}" />
    </HorizontalStackLayout>
</VerticalStackLayout>

Gambar berikut menggambarkan apa yang dihasilkan output XAML di layar:

Screenshot of a .NET MAUI Android app displaying two different label controls with text related to owing a bill. One label's text is formatted with USD currency.

XAML yang menggunakan StringFormat properti pengikatan lebih sederhana daripada XAML lainnya, dan Anda memiliki akses ke . Sistem pemformatan string net yang kuat.

Konversi jenis kustom

Properti StringFormat pengikatan nyaman saat menampilkan nilai sebagai string, tetapi tidak ketika Anda ingin mengonversi sesuatu seperti Color atau Image dari jenis lain. Dalam kasus ini, Anda perlu menulis kode konversi kustom.

Misalkan Anda meminta pengguna untuk memilih kata sandi, dan Anda ingin menggunakan warna di UI untuk menunjukkan kekuatan kata sandi. Ada tiga tingkat kekuatan: lemah, baik, kuat. Kekuatan didasarkan pada berapa banyak karakter dalam kata sandi. Untuk memberikan umpan balik langsung kepada pengguna tentang kekuatan kata sandi mereka, Anda ingin latar belakang Entry kontrol yang berisi kata sandi berubah berdasarkan kekuatan. Gambar berikut menunjukkan ketiga tingkat kekuatan tersebut: lemah, baik, dan kuat.

Screenshot of a .NET MAUI Android app with three entry controls, each with a different colored background.

Dari tiga kontrol entri dalam cuplikan layar, yang pertama memiliki empat karakter yang dimasukkan dan menampilkan latar belakang merah. Yang kedua memiliki sembilan karakter yang dimasukkan dan menampilkan latar belakang kuning. Kontrol entri terakhir memiliki 15 karakter dan memiliki latar belakang biru.

Tingkat-tingkat ini ditetapkan ke Strength enumerasi:

private enum Strength
{
    Weak,
    Good,
    Strong
}

Objek data ditetapkan sebagai halaman BindingContext, yang berisi kekuatan kata sandi dengan PasswordStrength properti . Saat pengguna mengetikkan kata sandi, PasswordStrength properti diubah sesuai dengan panjang kata sandi. Karena objek data berisi PasswordStrength properti , Anda mengikat properti tersebut ke BackgroundColor Entry kontrol:

<Entry BackgroundColor="{Binding PasswordStrength} ... />

Ada masalah di sini. PasswordStrength jenis Strength sementara BackgroundColor adalah Color. Jenis ini tidak kompatibel satu sama lain. .NET MAUI menyediakan cara untuk memperbaiki masalah ketidakcocokan jenis ini, properti pengikatan Converter .

Pengonversi pengikatan melakukan apa yang dikatakan namanya, mengonversi antara sumber pengikatan dan target. Konverter diimplementasikan melalui IValueConverter antarmuka.

Menerapkan IValueConverter

Anda membuat logika konversi ke dalam kelas yang mengimplementasikan IValueConverter antarmuka. Biasanya, nama-nama kelas ini berakhir dengan nama Converter untuk memperjelas tujuannya.

Antarmuka IValueConverter mendefinisikan dua metode:

  • Convert—Mengonversi dari properti sumber pengikatan ke properti UI target pengikatan.

  • ConvertBack—Mengonversi dari properti UI target pengikatan kembali ke properti sumber pengikatan.

    Metode ini jarang digunakan dan tidak digunakan dalam skenario ini. Sebagian besar konverter melemparkan NotSupportedException untuk menunjukkan bahwa konversi ini tidak didukung.

Berikut adalah kontrak antarmuka:

public interface IValueConverter
{
    object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture);
    object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture);
}

Ingat bahwa skenario yang sedang kami kerjakan mengikat Entry.BackgroundColor properti ke properti objek PasswordStrength data, yang merupakan Strength enumerasi.

<Entry BackgroundColor="{Binding PasswordStrength} ... />

Enumerasi Strength perlu dikonversi ke Color. Jadi pengonversi perlu mengevaluasi nilai mana yang Strength disediakan, dan mengembalikan yang berbeda Color. Kode berikut menunjukkan konversi ini:

namespace MyProject.Converters;

class StrengthToColorConverter : IValueConverter
{
    public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        return (Strength)value! switch
        {
            Strength.Weak => Colors.OrangeRed,
            Strength.Good => Colors.Yellow,
            Strength.Strong => Colors.LightBlue,
            _ => Colors.LightBlue
        };
    }

    public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
        throw new NotImplementedException();
}

Mari kita uraikan kode ini:

  • Metode ini Convert memiliki empat parameter. Anda umumnya dapat membuang dua parameter terakhir kecuali Anda memiliki alasan khusus untuk menggunakannya.
  • Parameter value berisi nilai masuk. Dalam contoh ini, ini adalah Strength nilai enumerasi.
  • Parameter targetType diabaikan. Tetapi Anda dapat menggunakan parameter ini untuk memvalidasi bahwa jenis properti yang digunakan pengonversi adalah Color. Ini dihilangkan dalam contoh ini untuk kesederhanaan.
  • Ekspresi pengalih digunakan untuk mengembalikan warna yang berbeda berdasarkan Strength nilai .

Menggunakan pengonversi di XAML

Dengan kelas konverter yang dibuat, Anda perlu membuat instansnya dan mereferensikannya dalam pengikatan. Cara standar untuk membuat instans pengonversi ada di kamus sumber daya elemen akar.

Pertama, petakan namespace XML ke namespace .NET yang berisi pengonversi. Dalam contoh kode berikut, cvt namespace XML memetakan ke MyProject.Converters namespace .NET:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:cvt="clr-namespace:MyProject.Converters"
             ...

Selanjutnya, buat instans di ContentPage.Resources:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:cvt="clr-namespace:MyProject.Converters"
             x:Class="MyProject.PasswordExample">
    <ContentPage.Resources>
        <cvt:StrengthToColorConverter x:Key="StrengthToColorConverter" />
    </ContentPage.Resources>

Sekarang instans pengonversi berada dalam kamus sumber daya dengan kunci StrengthToColorConverter, yang kebetulan bernama sama dengan jenisnya. Ini adalah cara umum penamaan pengonversi, karena Anda umumnya hanya memiliki satu pengonversi yang Anda gunakan kembali di seluruh XAML. Jika Anda, karena alasan tertentu, memerlukan beberapa instans konverter, kunci harus berbeda di antaranya.

Terakhir, referensikan pengonversi pada pengikatan. Karena konverter berada dalam kamus sumber daya, Anda menggunakan {StaticResource} ekstensi markup untuk mereferensikannya. Pengonversi ditetapkan ke Converter properti pengikatan:

<Entry BackgroundColor="{Binding PasswordStrength, Converter={StaticResource StrengthToColorConverter}}" ... />

Uji pengetahuan Anda

1.

Untuk menampilkan dan memformat nilai sebagai string dalam pengikatan data, mana pendekatan terbaik?

2.

Jenis mana yang digunakan dalam konversi pengikatan data?