Datová vazba s neshodovanými typy
Někdy se data, která používáte, neshodují s datovým typem vlastnosti ovládacího prvku zobrazující data. Můžete mít například peněžní hodnotu uloženou decimal
v typu, který chcete zobrazit na ovládacím Label
prvku, který je formátovaný jako měna. Složitějším příkladem by byla aplikace počasí uvedená v tomto modulu. Obrázek se má zobrazit na základě hodnoty předpovědi Sunny
počasí nebo Cloudy
výčtu, ale nemůžete svázat hodnotu výčtu zdroje s vlastností image cíle. V této lekci se podíváme na způsoby, jak můžete převést data.
Formátování řetězců
Běžnou neshodou typů je vnitřní typ, který chcete zobrazit jako formátovaný řetězec. Podobně jako když chcete zobrazit části DateTime
hodnoty nebo chcete typ naformátovat decimal
jako měnu.
Předpokládejme, že chcete zobrazit částku splatnosti na faktuře a máte tuto vlastnost u datového objektu:
public decimal BillAmount { get; set; }
Dlužná částka končí na 22,0304. K zobrazení textu a částky dolaru můžete použít dva ovládací prvky popisku, jak je znázorněno v následujícím fragmentu kódu:
<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>
Tento výstup vypíše řetězec do uživatelského rozhraní, který vypadá nějak You owe 22.0304 to the bank
takto, ale chybí symbol měny a v závislosti na místní měně může být příliš mnoho nebo příliš málo desetinných míst. Za normálních okolností byste hodnotu zpracováli jako řetězec se specifikátorem formátu "C" (nebo měna) v kódu, například takto:
string formattedBillAmount = string.Format("{0:C}", BillAmount);
Pokud ale chcete použít formátování v datové vazbě, musíte mít buď datový objekt, který vám poskytne formátovaný řetězec jako jinou vlastnost, nebo ho nějak zachytíte a naformátujete ho sami. Vazby .NET MAUI naštěstí poskytují způsob formátování řetězců pomocí vlastnosti vazby StringFormat
. Formátovací řetězec se řídí stejnými pravidly jako String.Format
metoda. Uzavřete formátovací řetězec do jednoduchých uvozovek, aby se analyzátor XAML nezaměňoval za složené závorky. Parametr 0
formátu řetězce je hodnota vlastnosti zpracovávaná vazbou.
<Label Text="{Binding BillAmount, StringFormat='You owe {0:C} to the bank'}" />
Představte si následující XAML, který ukazuje zobrazení BillAmount
obou způsobů:
<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>
Následující obrázek znázorňuje, co výstup XAML vytvoří na obrazovce:
XAML používající vlastnost vazby StringFormat
je jednodušší než ostatní XAML a máte přístup k souboru . Net je výkonný systém formátování řetězců.
Převod vlastního typu
Vlastnost StringFormat
vazby je vhodná při zobrazení hodnoty jako řetězce, ale ne, pokud chcete převést něco jako Color
nebo Image
z jiného typu. V těchto případech potřebujete napsat vlastní kód převodu.
Předpokládejme, že se uživateli zobrazí výzva k výběru hesla a chcete použít barvu v uživatelském rozhraní k označení síly hesla. Existují tři úrovně síly: slabá, dobrá, silná. Síla je založená na tom, kolik znaků je v hesle. Pokud chcete uživateli poskytnout okamžitou zpětnou vazbu o síle hesla, chcete, aby se pozadí ovládacího prvku obsahujícího Entry
heslo změnilo na základě síly. Následující obrázek ukazuje tyto tři úrovně síly: slabá, dobrá a silná.
Ze tří ovládacích prvků pro zadání na snímku obrazovky má první čtyři znaky a obsahuje červené pozadí. Druhý má zadaná devět znaků a obsahuje žluté pozadí. Poslední ovládací prvek pro zadávání má 15 znaků a má modré pozadí.
K výčtu Strength
se přiřazují tyto úrovně:
private enum Strength
{
Weak,
Good,
Strong
}
Datový objekt je přiřazen jako stránka BindingContext
, která obsahuje sílu hesla s PasswordStrength
vlastností. Vzhledem k tomu, že uživatel zadá heslo, PasswordStrength
vlastnost se změní podle délky hesla. Vzhledem k tomu, že datový objekt obsahuje PasswordStrength
vlastnost, vytvoříte vazbu této vlastnosti na BackgroundColor
ovládací prvek Entry
:
<Entry BackgroundColor="{Binding PasswordStrength} ... />
Je tu ale problém. Jedná PasswordStrength
se o typStrength
, zatímco BackgroundColor
je .Color
Tyto typy nejsou vzájemně kompatibilní. .NET MAUI poskytuje způsob, jak tyto problémy s neshodou typů vyřešit, vlastnost vazby Converter
.
Převaděč vazeb dělá přesně to, co říká jeho název, převádí mezi zdroj vazby a cílem. Převaděče jsou implementovány prostřednictvím IValueConverter
rozhraní.
Implementace IValueConverter
Logiku převodu vytvoříte do třídy, která implementuje IValueConverter
rozhraní. Názvy těchto tříd obvykle končí názvem Converter
, aby byl jeho účel jasný.
Rozhraní IValueConverter
definuje dvě metody:
Convert
— Převede vlastnost zdroje vazby na vlastnost uživatelského rozhraní cílové vazby.ConvertBack
– Převede vlastnost uživatelského rozhraní cílové vazby zpět na vlastnost zdroje vazby.Tato metoda se používá zřídka a v tomto scénáři se nepoužívá. Většina převaděčů vyvolá
NotSupportedException
upozornění, že tento převod není podporován.
Tady je kontrakt rozhraní:
public interface IValueConverter
{
object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture);
object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture);
}
Vzpomeňte si, že scénář, se kterým pracujeme, je vazba Entry.BackgroundColor
vlastnosti na vlastnost datového PasswordStrength
objektu, což je Strength
výčet.
<Entry BackgroundColor="{Binding PasswordStrength} ... />
Výčet Strength
je třeba převést na .Color
Převaděč proto musí vyhodnotit, která Strength
hodnota je k dispozici, a vrátit jinou Color
hodnotu . Tento převod ukazuje následující kód:
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();
}
Pojďme tento kód rozčlenět:
- Metoda
Convert
má čtyři parametry. Pokud nemáte konkrétní důvod k jejich použití, můžete obecně zahodit poslední dva parametry. - Parametr
value
obsahuje příchozí hodnotu. V tomto příkladu se jedná o hodnotu výčtuStrength
. - Parametr
targetType
je ignorován. Tento parametr však můžete použít k ověření, že typ vlastnosti, se kterou se převaděč používá, je .Color
Toto je v tomto příkladu vynecháno kvůli jednoduchosti. - Výraz přepínače se používá k vrácení jiné barvy na
Strength
základě hodnoty.
Použití převaděče v XAML
S vytvořenou třídou převaděče musíte vytvořit instanci a odkazovat na ni v vazbě. Standardní způsob vytvoření instance převaděče je ve slovníku prostředků kořenového prvku.
Nejprve namapujte obor názvů XML na obor názvů .NET, který obsahuje převaděč. V následujícím příkladu kódu se cvt
obor názvů XML mapuje na MyProject.Converters
obor názvů .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"
...
Dále vytvořte instanci v :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>
Teď je instance převaděče ve slovníku prostředků s klíčem StrengthToColorConverter
, který se stane se stejným názvem jako typ. Jedná se o typický způsob pojmenování převaděčů, protože obecně máte jen jeden převaděč, který opakovaně používáte v rámci XAML. Pokud byste z nějakého důvodu vyžadovali více instancí převaděče, klíče by se mezi nimi musely lišit.
Nakonec na vazbu odkazujte na převaděč. Vzhledem k tomu, že převaděč je ve slovníku prostředků, použijete {StaticResource}
k odkazování rozšíření značek. Převaděč je přiřazen k vlastnosti vazby Converter
:
<Entry BackgroundColor="{Binding PasswordStrength, Converter={StaticResource StrengthToColorConverter}}" ... />