Kompilované vazby
Datové vazby .NET Multi-Platform App UI (.NET MAUI) mají dva hlavní problémy:
- Neexistuje žádné ověřování vazbových výrazů v době kompilace. Místo toho jsou vazby vyřešeny za běhu. Proto se žádné neplatné vazby nezjistí, dokud se nechová za běhu, pokud se aplikace nechová podle očekávání nebo se zobrazí chybové zprávy.
- Nejsou nákladově efektivní. Vazby se řeší za běhu pomocí kontroly objektů pro obecné účely (reflexe) a režijní náklady se liší od platformy po platformu.
Kompilované vazby zlepšují výkon datových vazeb v aplikacích .NET MAUI překladem výrazů vazeb v době kompilace místo modulu runtime. Kromě toho toto ověřování výrazů vazby v době kompilace umožňuje lepší prostředí pro řešení potíží vývojářů, protože neplatné vazby jsou hlášeny jako chyby sestavení.
Důležité
Kompilované vazby jsou vyžadovány místo vazeb založených na řetězcích v aplikacích NativeAOT a v aplikacích s povoleným úplným oříznutím. Další informace najdete v tématu Oříznutí aplikace .NET MAUI a nativního nasazení AOT.
Kompilované vazby v XAML
Chcete-li použít zkompilované vazby v xaml, nastavte x:DataType
atribut na VisualElement typ objektu, se kterým VisualElement bude objekt a jeho podřízené objekty svázané. Doporučuje se nastavit x:DataType
atribut na stejné úrovni v hierarchii zobrazení, jako je nastavená BindingContext . Tento atribut je však možné znovu definovat v libovolném umístění v hierarchii zobrazení.
Důležité
Kompilované vazby vyžadují použití kompilace XAML, která je ve výchozím nastavení povolená v .NET MAUI. Pokud jste zakázali kompilaci XAML, budete ji muset povolit. Další informace naleznete v tématu Kompilace XAML.
Chcete-li použít kompilované vazby v xaml, x:DataType
musí být atribut nastaven na řetězcový literál nebo typ pomocí x:Type
rozšíření značek. V době kompilace XAML se všechny neplatné vazbové výrazy oznamují jako chyby sestavení. Kompilátor XAML však bude hlásit pouze chybu sestavení prvního neplatného vazbového výrazu, na který narazí. Všechny platné vazbové výrazy definované v podřízených VisualElement objektech nebo podřízených výrazech budou zkompilovány bez ohledu na to, zda BindingContext je nastavena v xaml nebo kódu. Kompilace vazbového výrazu vygeneruje zkompilovaný kód, který získá hodnotu z vlastnosti ve zdroji, a nastaví ji na vlastnost v cíli zadaném v kódu. Kromě toho může v závislosti na vazbovém výrazu vygenerovaný kód sledovat změny v hodnotě zdrojové vlastnosti a aktualizovat cílovou vlastnost a může odesílat změny z cíle zpět do zdroje.
Důležité
Kompilované vazby jsou zakázány pro všechny výrazy vazby XAML, které definují Source
vlastnost. Důvodem je to, že Source
vlastnost je vždy nastavena pomocí x:Reference
rozšíření značek, které nelze vyřešit v době kompilace.
Kromě toho jsou kompilované vazby v XAML v současné době u více vazeb nepodporované.
Ve výchozím nastavení .NET MAUI negeneruje upozornění sestavení pro vazby XAML, které nepoužívají kompilované vazby. Upozornění kompilovaných vazeb ale můžete vyjádřit nastavením $(MauiStrictXamlCompilation)
vlastnosti sestavení do true
souboru projektu vaší aplikace (*.csproj):
<MauiStrictXamlCompilation>true</MauiStrictXamlCompilation>
Ve výchozím nastavení .NET MAUI vytváří upozornění sestavení pro vazby XAML, které nepoužívají kompilované vazby.
Další informace o upozorněních kompilovaných vazeb XAML naleznete v upozorněních kompilovaných vazeb XAML.
Použití zkompilovaných vazeb v XAML
Následující příklad ukazuje použití zkompilovaných vazeb mezi zobrazeními .NET MAUI a vlastnostmi modelu viewmodel:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataBindingDemos"
x:Class="DataBindingDemos.CompiledColorSelectorPage"
x:DataType="local:HslColorViewModel"
Title="Compiled Color Selector">
<ContentPage.BindingContext>
<local:HslColorViewModel Color="Sienna" />
</ContentPage.BindingContext>
...
<StackLayout>
<BoxView Color="{Binding Color}"
... />
<StackLayout Margin="10, 0">
<Label Text="{Binding Name}" />
<Slider Value="{Binding Hue}" />
<Label Text="{Binding Hue, StringFormat='Hue = {0:F2}'}" />
<Slider Value="{Binding Saturation}" />
<Label Text="{Binding Saturation, StringFormat='Saturation = {0:F2}'}" />
<Slider Value="{Binding Luminosity}" />
<Label Text="{Binding Luminosity, StringFormat='Luminosity = {0:F2}'}" />
</StackLayout>
</StackLayout>
</ContentPage>
Vytvoří ContentPage instanci a inicializuje HslColorViewModel
Color
vlastnost v rámci značek elementu vlastnosti pro BindingContext vlastnost. Také ContentPage definuje x:DataType
atribut jako typ modelu viewmodel, který označuje, že všechny vazbové výrazy v ContentPage hierarchii zobrazení budou zkompilovány. To lze ověřit změnou některého z vazeb výrazů na vazbu na neexistující vlastnost viewmodel, která způsobí chybu sestavení. I když tento příklad nastaví x:DataType
atribut na řetězcový literál, může být také nastaven na typ s rozšířením x:Type
značek. Další informace o x:Type
rozšíření značek naleznete v tématu x:Type Markup Extension.
Důležité
Atribut x:DataType
lze znovu definovat v libovolném bodě v hierarchii zobrazení.
Elementy BoxViewLabela Slider zobrazení dědí kontext vazby z objektu ContentPage. Tato zobrazení jsou všechny cílové vazby, které odkazují na vlastnosti zdroje v modelu viewmodel.
BoxView.Color
Pro vlastnost a Label.Text
vlastnost jsou datové vazby OneWay
– vlastnosti v zobrazení jsou nastaveny z vlastností v modelu view. Vlastnost Slider.Value
však používá TwoWay
vazbu. To umožňuje nastavit každý Slider z modelu zobrazení, a také pro model zobrazení nastavit z každého Slider.
Při prvním spuštění příkladu jsou elementy BoxViewLabel a Slider elementy nastaveny z modelu viewmodel na základě počáteční Color
vlastnosti nastavena při vytvoření instance modelu viewmodel. Při manipulaci BoxView s posuvníky se prvky odpovídajícím Label způsobem aktualizují:
Další informace o tomto selektoru barev najdete v tématu ViewModels a oznámení o změně vlastností.
Použití zkompilovaných vazeb v XAML v DataTemplate
Vazby v objektu DataTemplate jsou interpretovány v kontextu šablony objektu. Proto při použití zkompilovaných vazeb v objektu DataTemplate, DataTemplate musí deklarovat typ jeho datového objektu pomocí atributu x:DataType
. Pokud to neuděláte, může to vést k DataTemplate nesprávnému zdědění x:DataType
z nadřazeného oboru:
<ContentPage ...
x:DataType="local:AnimalsPageViewModel">
<!-- Binding to AnimalsPageViewModel.Animals -->
<CollectionView ItemsSource="{Binding Animals}">
<CollectionView.ItemTemplate>
<DataTemplate>
<!-- incorrect: compiler thinks you want to bind to AnimalsPageViewModel.Name -->
<Label Text="{Binding Name}" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
Následující příklad ukazuje správné nastavení na x:DataType
DataTemplate:
<ContentPage ...
x:DataType="local:AnimalsPageViewModel">
<!-- Binding to AnimalsPageViewModel.Animals -->
<CollectionView ItemsSource="{Binding Animals}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="local:Animal">
<!-- correct: compiler knows you want to bind to Animal.Name -->
<Label Text="{Binding Name}" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
I když tento příklad nastaví x:DataType
atribut na řetězcový literál, může být také nastaven na typ s rozšířením x:Type
značek. Další informace o x:Type
rozšíření značek naleznete v tématu x:Type Markup Extension.
Kompilace vazeb, které definují Source
vlastnost
Před rozhraním .NET MAUI 9 kompilátor XAML přeskočí kompilaci vazeb, které definují Source
vlastnost namísto BindingContext. Z .NET MAUI 9 je možné tyto vazby zkompilovat, aby využívaly lepší výkon modulu runtime. Tato optimalizace ale není ve výchozím nastavení povolená, aby nedošlo k přerušení existujícího kódu aplikace. Pokud chcete tuto optimalizaci povolit, nastavte $(MauiEnableXamlCBindingWithSourceCompilation)
vlastnost sestavení do true
souboru projektu vaší aplikace:
<MauiEnableXamlCBindingWithSourceCompilation>true</MauiEnableXamlCBindingWithSourceCompilation>
Pak se ujistěte, že všechny vazby jsou opatřeny poznámkami správnými x:DataType
a že nezdědí nesprávné datové typy ze svého nadřazeného oboru:
<HorizontalStackLayout BindingContext="{x:Reference slider}" x:DataType="Slider">
<Label Text="{Binding Value}" />
<Label Text="{Binding Text, Source={x:Reference entry}, x:DataType=Entry}" />
</HorizontalStackLayout>
Poznámka:
V případech, kdy existuje vazba s objektem Source
, ale dědí x:DataType
z nadřazeného objektu, může dojít k neshodě mezi typem x:DataType
objektu Source
. V tomto scénáři se vygeneruje upozornění a dojde k záložní vazbě založené na reflexi, která přeloží cestu vazby za běhu.
Kombinování zkompilovaných vazeb s klasickými vazbami v XAML
Vazbové výrazy jsou zkompilovány pouze pro hierarchii zobrazení, na které x:DataType
je atribut definován. Naopak všechna zobrazení v hierarchii, na které x:DataType
není atribut definován, budou používat klasické vazby. Zkombinovat kompilované vazby a klasické vazby na stránce je proto možné kombinovat. Například v předchozí části zobrazení v rámci DataTemplate zkompilovaných vazeb, zatímco BoxView tato možnost je nastavená na barvu vybranou v této části ListView .
Pečlivé strukturování x:DataType
atributů proto může vést ke stránce pomocí zkompilovaných a klasických vazeb. Případně můžete atribut znovu definovat v libovolném bodě v hierarchii zobrazení tak, x:DataType
aby null
používal x:Null
rozšíření značek. To znamená, že všechny vazbové výrazy v hierarchii zobrazení budou používat klasické vazby. Následující příklad ukazuje tento přístup:
<StackLayout x:DataType="local:HslColorViewModel">
<StackLayout.BindingContext>
<local:HslColorViewModel Color="Sienna" />
</StackLayout.BindingContext>
<BoxView Color="{Binding Color}"
VerticalOptions="FillAndExpand" />
<StackLayout x:DataType="{x:Null}"
Margin="10, 0">
<Label Text="{Binding Name}" />
<Slider Value="{Binding Hue}" />
<Label Text="{Binding Hue, StringFormat='Hue = {0:F2}'}" />
<Slider Value="{Binding Saturation}" />
<Label Text="{Binding Saturation, StringFormat='Saturation = {0:F2}'}" />
<Slider Value="{Binding Luminosity}" />
<Label Text="{Binding Luminosity, StringFormat='Luminosity = {0:F2}'}" />
</StackLayout>
</StackLayout>
Kořen StackLayout nastaví x:DataType
atribut tak, aby byl typem HslColorViewModel
, což znamená, že všechny vazbové výrazy v hierarchii kořenového StackLayout zobrazení budou zkompilovány. Vnitřní StackLayout předefinuje x:DataType
atribut null
pomocí výrazu značky x:Null
. Proto vazbové výrazy uvnitř vnitřní StackLayout používají klasické vazby. Pouze v BoxViewkořenové StackLayout hierarchii zobrazení používá zkompilované vazby.
Další informace o výrazu x:Null
značek naleznete v tématu x:Null Markup Extension.
Upozornění kompilovaných vazeb XAML
Následující tabulka uvádí upozornění kompilátoru pro kompilované vazby a způsob jejich řešení:
Kód | Zpráva | Oprava |
---|---|---|
XC0022 |
Vazby je možné zkompilovat, aby se zlepšil výkon modulu runtime, pokud x:DataType je zadán. |
Přidejte x:DataType do souboru XAML a určete typ aktuálního BindingContextsouboru . Osvědčeným postupem je přidat x:DataType všechny prvky, ve kterých se kontext vazby mění. |
XC0023 |
Vazby lze zkompilovat za účelem zlepšení výkonu modulu runtime, pokud x:DataType není explicitně null . |
Nahraďte x:DataType="{x:Null}" správným typem. |
Kód | Zpráva |
---|---|
XC0022 |
Vazby je možné zkompilovat, aby se zlepšil výkon modulu runtime, pokud x:DataType je zadán. Chcete-li toto upozornění opravit, přidejte x:DataType do xaml, abyste zadali typ aktuálního BindingContextsouboru . Osvědčeným postupem je přidat x:DataType všechny prvky, ve kterých se kontext vazby mění. |
XC0023 |
Vazby lze zkompilovat za účelem zlepšení výkonu modulu runtime, pokud x:DataType není explicitně null . Chcete-li toto upozornění opravit, nahraďte x:DataType="{x:Null}" správným typem. |
XC0024 |
Vazba může být nesprávně zkompilována, protože x:DataType poznámka pochází z vnějšího oboru. Ujistěte se, že všechny elementy XAML označíte DataTemplate správným x:DataType kódem . Chcete-li toto upozornění opravit, ujistěte se, že všechny DataTemplate prvky jsou opatřeny poznámkami správným x:DataType . |
XC0025 |
Vazba nebyla zkompilována, protože má explicitně nastavenou Source vlastnost a kompilace vazeb s Source není povolena. Zvažte povolení této optimalizace nastavením <MauiEnableXamlCBindingWithSourceCompilation>true</MauiEnableXamlCBindingWithSourceCompilation> v souboru projektu a ujistěte se, že je pro tuto vazbu zadána správná odpověď x:DataType . Chcete-li toto upozornění opravit, povolte $(MauiEnableXamlCBindingWithSourceCompilation) vlastnost sestavení v souboru projektu a označte všechny vazby odpovídajícími x:DataType . |
Pokud chcete zajistit, aby tato upozornění nebyla ignorována, zvažte změnu konkrétních upozornění na chyby sestavení pomocí $(WarningsAsErrors)
vlastnosti sestavení:
<WarningsAsErrors>$(WarningsAsErrors);XC0022;XC0023</WarningsAsErrors>
Pokud chcete tato upozornění ignorovat, použijte $(NoWarn)
vlastnost sestavení s konkrétními kódy upozornění:
<NoWarn>$(NoWarn);XC0022;XC0023</NoWarn>
Důležité
XC0022
a XC0023
upozornění budou vždy potlačeny, pokud $(MauiStrictXamlCompilation)
není vlastnost sestavení nastavena na true
.
Pokud vlastnost sestavení nastavíte $(TreatWarningsAsErrors)
v true
souboru projektu aplikace, ale chcete ignorovat určitá upozornění kompilátoru XAML, pomocí $(NoWarn)
vlastnosti sestavení tato upozornění nebo $(WarningsNotAsErrors)
vlastnost sestavení snížit závažnost některých konkrétních kódů.
Ve výchozím nastavení .NET MAUI vytváří upozornění sestavení pro vazby XAML, které nepoužívají kompilované vazby. Upozornění kompilovaných vazeb, která se považují za chyby, můžete vyjádřit nastavením $(MauiStrictXamlCompilation)
vlastností sestavení $(TreatWarningsAsErrors)
do true
souboru projektu vaší aplikace (*.csproj):
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<MauiStrictXamlCompilation>true</MauiStrictXamlCompilation>
Poznámka:
Ve výchozím nastavení je $(MauiStrictXamlCompilation)
vlastnost sestavení, false
pokud nepublikujete aplikaci pomocí úplného oříznutí nebo NativeAOT.
Kompilované vazby v kódu
Vazby napsané v kódu obvykle používají řetězce cesty, které jsou vyřešeny za běhu s reflexí.
SetBinding Metoda rozšíření má však také přetížení, které definuje vazby pomocí argumentu Func
místo cesty řetězce:
MyLabel.SetBinding(Label.TextProperty, static (Entry entry) => entry.Text);
Ne všechny metody lze použít k definování kompilované vazby. Výraz musí být jednoduchý přístupový výraz vlastnosti. Následující příklady ukazují platné a neplatné vazbové výrazy:
// Valid: Property access
static (PersonViewModel vm) => vm.Name;
static (PersonViewModel vm) => vm.Address?.Street;
// Valid: Array and indexer access
static (PersonViewModel vm) => vm.PhoneNumbers[0];
static (PersonViewModel vm) => vm.Config["Font"];
// Valid: Casts
static (Label label) => (label.BindingContext as PersonViewModel).Name;
static (Label label) => ((PersonViewModel)label.BindingContext).Name;
// Invalid: Method calls
static (PersonViewModel vm) => vm.GetAddress();
static (PersonViewModel vm) => vm.Address?.ToString();
// Invalid: Complex expressions
static (PersonViewModel vm) => vm.Address?.Street + " " + vm.Address?.City;
static (PersonViewModel vm) => $"Name: {vm.Name}";
Varování
K chybě kompilátoru CS0272 dojde, pokud je přístupový objekt sady pro vlastnost nebo indexer nepřístupný. Pokud k tomu dojde, zvyšte přístupnost přístupového objektu.
Kromě toho BindingBase.Create metoda nastaví vazbu přímo na objekt s a Func
vrátí instanci objektu vazby:
myEntry.SetBinding(Entry.TextProperty, new MultiBinding
{
Bindings = new Collection<BindingBase>
{
Binding.Create(static (Entry entry) => entry.FontFamily, source: RelativeBindingSource.Self),
Binding.Create(static (Entry entry) => entry.FontSize, source: RelativeBindingSource.Self),
Binding.Create(static (Entry entry) => entry.FontAttributes, source: RelativeBindingSource.Self),
},
Converter = new StringConcatenationConverter()
});
Tyto zkompilované přístupy k vazbám poskytují následující výhody:
- Vylepšili jsme výkon datových vazeb překladem výrazů vazeb v době kompilace místo modulu runtime.
- Lepší prostředí pro řešení potíží pro vývojáře, protože neplatné vazby jsou hlášeny jako chyby sestavení.
- IntelliSense při úpravách
Výkon
Kompilované vazby zlepšují výkon datových vazeb s různou výhodou výkonu:
- Zkompilovaná vazba, která používá oznámení o změně vlastnosti (tj.
OneWay
,OneWayToSource
neboTwoWay
vazbu), se vyřeší přibližně 8krát rychleji než klasická vazba. - Zkompilovaná vazba, která nepoužívá oznámení o změně vlastnosti (tj.
OneTime
vazby), se vyřeší přibližně 20krát rychleji než klasická vazba. -
BindingContext Nastavení kompilované vazby, která používá oznámení o změně vlastnosti (tj.
OneWay
,OneWayToSource
neboTwoWay
vazbu), je přibližně 5krát rychlejší než nastavení BindingContext u klasické vazby. -
BindingContext Nastavení kompilované vazby, která nepoužívá oznámení o změně vlastnosti (tj.
OneTime
vazby), je přibližně 7krát rychlejší než nastavení BindingContext u klasické vazby.
Tyto rozdíly v výkonu se dají zvětšit na mobilních zařízeních, závisí na používané platformě, na používané verzi operačního systému a na zařízení, na kterém je aplikace spuštěná.