Använda databindningar i XAML
Databindningar kan deklareras i antingen kod eller I XAML med hjälp av markeringstillägg. I den här lektionen beskrivs det senare eftersom det är det vanligaste sättet att skapa bindningar. Det finns ett par skäl att föredra XAML. För det första anser de flesta att bindningar är en del av användargränssnittskoden eftersom bindningarna hämtar data som användargränssnittet ska visa. För det andra finns det ett tillägg med namnet Binding
som gör det enkelt att göra det.
Vad är databindningar?
En bindning kopplar ihop två egenskaper. En egenskap finns i användargränssnittet och den andra finns i datamodellobjektet. Om värdet för någon av egenskaperna ändras kan bindningsobjektet uppdatera det andra. Med andra ord är bindningar mellanliggande objekt som synkroniserar användargränssnittet och data. Vi använder termerna källa och mål för att identifiera de två objekt som ingår:
Källa: En källa kan vara ett objekt av vilken typ som helst. I praktiken använder du vanligtvis ett dataobjekt som källa. Du måste identifiera egenskapen för källobjektet för att delta i bindningen. Du identifierar egenskapen genom att
Path
ange egenskapen i bindningen.Mål: Målet är en egenskap som implementeras med hjälp av en särskild egenskap som kallas för .
BindableProperty
Objektet medBindableProperty
måste härledas frånBindableObject
. Alla kontroller som tillhandahålls i .NET MAUI härleds frånBindableObject
och de flesta av deras egenskaper ärBindableProperties
.
Följande diagram visar hur en bindning är ett mellanliggande objekt mellan två egenskaper:
Så här skapar du en databindning i XAML
Nu ska vi titta på en enkel bindning som skapats i XAML med hjälp av markeringstillägget {Binding}
. Den binder WeatherService.Humidity
källans egenskap till Text
egenskapen för användargränssnittskontrollen.
<VerticalStackLayout Margin="10">
<VerticalStackLayout.Resources>
<ResourceDictionary>
<services:WeatherService x:Key="myWeatherService" />
</ResourceDictionary>
</VerticalStackLayout.Resources>
<Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
</VerticalStackLayout>
Bindningskällan är:
En objektinstans av
WeatherService
typen. Instansen{StaticResource ...}
refereras via XAML-tillägget, som pekar på ett objekt i stacklayoutens resursordlista.Pekar
Path
på en egenskap med namnetHumidity
påWeatherService
typen.Path
är den första namnlösa parametern i syntaxen{Binding}
och syntaxenPath=
kan utelämnas. Dessa två bindningar är likvärdiga:<Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" /> <Label Text="{Binding Humidity, Source={StaticResource myWeatherService}}" />
Bindningsmålet är:
- Kontrollen
Label
. - Kontrollens
Text
egenskap.
När användargränssnittet visas {Binding}
skapar XAML-tillägget en bindning mellan WeatherService
och Label
. Bindningen läser in WeatherService.Humidity
egenskapens värde i egenskapen Label.Text
.
Använda en annan kontroll som bindningskälla
En användbar funktion i bindningen är att kunna binda till andra kontroller. Följande XAML är en enkel demonstration:
<VerticalStackLayout HorizontalOptions="Center" VerticalOptions="Center">
<Label x:Name="TargetLabel" Text="TEXT TO ROTATE" BackgroundColor="Yellow" />
<Slider WidthRequest="100" Maximum="360"
Value="{Binding Rotation, Mode=OneWayToSource, Source={x:Reference TargetLabel}}" />
</VerticalStackLayout>
Egenskapen Slider.Value
är bunden till Label.Rotation
egenskapen, men på ett annat sätt än tidigare förklarat. Den här egenskapen använder bindningsläget OneWayToSource
, som vänder den typiska bindningsmekanismen. I stället för att källan uppdaterar måletOneWayToSource
uppdaterar källan när målet ändras. I det här exemplet när skjutreglaget flyttas uppdateras rotationen av etiketten baserat på skjutreglagets värde, enligt följande animering:
Det vanliga scenariot för bindning av kontroller till varandra är när en kontroll, vanligtvis en samlingskontroll som en ListView
eller CarouselView
, har ett markerat objekt som du vill använda som datakälla. I exemplet med en sida som visar väderprognosen kan du ha en ListView
aktuell femdagarsprognos. När användaren väljer en dag i listan visas informationen om väderprognosen i andra kontroller. Om användaren väljer en annan dag uppdateras de andra kontrollerna igen med den valda dagens information.
Använd samma källa för flera bindningar
I föregående exempel visades användning av en statisk resurs som källa för en enda bindning. Den källan kan användas i flera bindningar. Här är ett exempel på hur du deklarerar en bindning mellan tre olika kontroller, alla bindningar till samma objekt och egenskap Path
, även om vissa utelämnar Path
egenskapen:
<VerticalStackLayout Margin="10">
<VerticalStackLayout.Resources>
<vm:SimpleWeatherServiceObject x:Key="myWeatherService" />
</VerticalStackLayout.Resources>
<Entry Text="{Binding Humidity, Source={StaticResource myWeatherService}}" />
<Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
</VerticalStackLayout>
Du behöver inte använda samma Path
när du använder samma Source
:
<VerticalStackLayout Margin="10">
<VerticalStackLayout.Resources>
<vm:SimpleWeatherServiceObject x:Key="myWeatherService" />
</VerticalStackLayout.Resources>
<Entry Text="{Binding Temperature, Source={StaticResource myWeatherService}}" />
<Label Text="{Binding Path=Humidity, Source={StaticResource myWeatherService}}" />
</VerticalStackLayout>
Sällan presenterar du en enda datamängd från en källa, även om det kan hända. Vanligtvis har du flera kontroller som använder olika datadelar från samma källa. Den här situationen är så vanlig att BindableObject
klassen har en egenskap med namnet BindingContext
som fungerar som källa för databindning. Kom ihåg att .NET MAUI-kontroller ärver från BindableObject
klassen, så .NET MAUI-kontrollerna har BindingContext
egenskapen .
Source
Det är valfritt att ange bindningen. En bindning som inte har Source
angetts söker automatiskt i det visuella XAML-trädet efter en BindingContext
, som anges i XAML eller tilldelas till ett överordnat element efter kod. Bindningar utvärderas enligt det här mönstret:
Om bindningen definierar en
Source
används den källan och sökningen stoppas. BindningarnaPath
tillämpas påSource
för att hämta ett värde. OmSource
inte har angetts börjar sökningen efter en bindningskälla.Sökningen börjar med själva målobjektet. Om målobjektets inte är null stoppas
BindingContext
sökningen och bindningarnaPath
tillämpas på för attBindingContext
hämta ett värde. Om ärBindingContext
null fortsätter sökningen.Den här processen fortsätter tills den når XAML-roten. Sökningen avslutas genom att kontrollera
BindingContext
rotens värde för ett värde som inte är null. Om inget giltigtBindingContext
hittades har bindningen inget att binda mot och gör ingenting.
Det är vanligt att ange BindingContext
på rotobjektets nivå för att tillämpa på hela XAML.
Det finns en sista praktisk funktion som är värd att nämna. Bindningar söker efter ändringar i objektreferensen för källan. Detta fungerar även för bindningar som använder BindingContext
som källa. Source
Om eller BindingContext
omtilldelas till ett annat objekt hämtar bindningarna data från den nya källan och uppdaterar målet.