Sdílet prostřednictvím


Kompilované vazby

Projděte si ukázku. Procházení ukázky

Datové vazby .NET Multi-Platform App UI (.NET MAUI) mají dva hlavní problémy:

  1. 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.
  2. 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 HslColorViewModelColor 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í:

Kompilovaný selektor barev.

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

<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:DataTypekó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 Funcvrá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, OneWayToSourcenebo TwoWay 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, OneWayToSourcenebo TwoWay 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á.