Een gebeurtenisgestuurde gebruikersinterface vergelijken met een gegevensgebonden gebruikersinterface
Een gebeurtenisgestuurde gebruikersinterface (UI) is ontworpen rond de gebeurtenissen die een besturingselement beschikbaar maakt. Deze gebeurtenissen kunnen worden gekoppeld aan gebeurtenis-handlercode die wordt aangeroepen wanneer de gebeurtenis wordt geactiveerd. Stel dat u een knop hebt waarop een langlopende bewerking wordt uitgevoerd wanneer erop wordt geklikt. De gebeurtenis-handler die aan de Clicked
gebeurtenis is toegewezen, kan de bewerking starten en vervolgens de eigenschap false
van IsEnabled
de knop instellen om te voorkomen dat de knop opnieuw wordt geklikt terwijl de bewerking wordt uitgevoerd.
Een gegevensgebonden gebruikersinterface maakt gebruik van gegevensbinding om gegevens te presenteren en ermee te communiceren. Eigenschappen van besturingselementen zijn gebonden aan de eigenschappen van het gegevensobject en deze bindingen kunnen wijzigingen in de eigenschappen detecteren. Bekijk in het vorige voorbeeld de knop die een langdurige bewerking uitvoert. In plaats van de knop in codeachter uit te schakelen, is de IsEnabled
eigenschap gebonden aan de eigenschap van IsBusy
het gegevensobject. Wanneer het gegevensobject bezet wordt, wordt de ingeschakelde status van de knop automatisch gewijzigd in overeenstemming.
Voor- en nadelen van het gebruik van gebeurtenissen en code-behind
Het gebruik van de gebeurtenis-handler van het besturingselement met code-behind is een snelle en handige manier om de app-logica voor uw gebruikersinterface te ontwerpen. U gebruikt code om services aan te roepen om gegevens op te halen, bewerkingen op die gegevens uit te voeren en te communiceren met de besturingselementen op de pagina. De code wordt gebruikt om de gebruikersinterface en gegevens gesynchroniseerd te houden.
Bekijk het voorbeeld van een weerservice-app. Het volgende XAML-fragment bevat een eenvoudige ui-knop die de gebruiker selecteert om de meest recente gegevens op te halen en de gebruikersinterface bij te werken met de vochtigheid.
<VerticalStackLayout Margin="10">
<HorizontalStackLayout Spacing="20">
<Label Text="Postal Code:" VerticalOptions="Center" />
<Entry x:Name="PostalCode" WidthRequest="100" />
<Button x:Name="RefreshWeatherButton" Text="Refresh" WidthRequest="200" Clicked="RefreshWeatherButton_Clicked" />
</HorizontalStackLayout>
<Label x:Name="Humidity" Text="Humidity: ?" />
</VerticalStackLayout>
In dit voorbeeld zijn er drie benoemde besturingselementen:
Entry
besturingselement met de naam PostalCode.Button
besturingselement met de naam RefreshWeatherButton.Label
besturingselement met de naam Vochtigheid.
De RefreshWeatherButton
gebeurtenis-handler is gedeclareerd voor de Clicked
gebeurtenis. Wanneer op de knop wordt geklikt, vraagt de gebeurtenishandler een weerservice op voor de nieuwste weersvoorspelling, met behulp van de gegevens die zijn ingevoerd in het PostalCode
invoerbeheer en stelt de tekst van het Humidity
label in op de huidige vochtigheid.
private void RefreshWeatherButton_Clicked(object sender, EventArgs e)
{
WeatherService.Location = PostalCode.Text;
WeatherService.Refresh();
Humidity.Text = $"Humidity: {WeatherService.Humidity}";
}
In deze ene gebeurtenis-handler zijn drie besturingselementen nauw aan elkaar gekoppeld en de gegevens via de code-behind.
Dit ontwerp werkt uitstekend voor kleine UIS's, maar zodra de gebruikersinterface complex wordt, kan het onderhouden van een nauw gekoppelde code-achter lastig worden. Als u een besturingselement verwijdert of wijzigt, moet u code opschonen met deze UI-besturingselementen, waaronder de gebeurtenis-handler. Als u besluit om de gebruikersinterface opnieuw te ontwerpen, hebt u ook veel code om te herstructureren. En wanneer de back-up van de gegevensstructuur verandert, moet u in de code van elke gebruikersinterface duiken om gesynchroniseerd te blijven.
Gegevensbinding helpt
Gegevensbindingen kunnen worden geïmplementeerd in XAML of code, maar komen veel vaker voor in XAML, waar ze helpen de grootte van het bestand achter code te verkleinen. Door procedurele code in gebeurtenishandlers te vervangen door declaratieve code of markeringen, wordt de app vereenvoudigd en verduidelijkt. Omdat voor de bindingen geen codeachter is vereist, kunt u eenvoudig de gebruikersinterface maken, wijzigen of opnieuw ontwerpen om aan te passen aan de manier waarop u de gegevens wilt presenteren.
Laten we hetzelfde voorbeeld nemen als in de vorige sectie, maar deze bijwerken om gegevensbinding te gebruiken:
<VerticalStackLayout Margin="10">
<HorizontalStackLayout Spacing="20">
<Label Text="Postal Code:" VerticalOptions="Center" />
<Entry Text="{Binding Location, Mode=OneWayToSource}" WidthRequest="100" />
<Button Text="Refresh" Command="{Binding RefreshWeather}" WidthRequest="200" />
</HorizontalStackLayout>
<Label Text="{Binding Humidity}" />
</VerticalStackLayout>
U kunt de eigenschappen herkennen die afhankelijk zijn van gegevens. Ze gebruiken de syntaxis {Binding ...}
van de XAML-extensie voor de waarde van de eigenschap. Maak u nog geen zorgen over de specifieke kenmerken, die verderop in deze module worden behandeld.
Dezelfde drie besturingselementen worden gedeclareerd in de XAML, maar geen van deze besturingselementen heeft een naam, omdat een naam niet vereist is:
Entry
beheersen:De eigenschap van
Text
dit besturingselement is gebonden aan een eigenschap met de naamLocation
.Button
beheersen:De eigenschap van
Command
de knop is gebonden aan een eigenschap met de naamRefreshWeather
.Command
is een eigenschap op de knop die code aanroept wanneer de knop wordt ingedrukt. Het is een alternatief voor deClicked
gebeurtenis die wordt gebruikt in gegevensbinding.Label
beheersen:Deze
Text
eigenschap is gebonden aan een eigenschap met de naamHumidity
.
In deze eenvoudige gebruikersinterface wordt alle code-behind geëlimineerd. Het verwijderen van alle code-behind is niet het punt van gegevensbinding, ook al is het meestal mogelijk. Code-behind heeft nog steeds zijn plaats. Hoeveel gegevensbinding u implementeert, is aan u.
De gebruikersinterface is nu losjes gekoppeld aan een gegevensobject. Waarom is het losjes gekoppeld in plaats van nauw gekoppeld? Vanwege de manier waarop bindingen worden geëvalueerd. Elk besturingselement heeft een BindingContext
eigenschap. Als de context niet is ingesteld, wordt de context van het bovenliggende besturingselement gebruikt, enzovoort, totdat de hoofdmap van de XAML wordt geëvalueerd. Wanneer bindingen worden geëvalueerd, wordt het objectexemplaren van de context gecontroleerd op de vereiste eigenschappen, zoals de binding van Text
het labelbesturingselement aan de eigenschap van Humidity
de context. Als Humidity
deze niet bestaat in de context, gebeurt er niets.
Omdat de gebruikersinterface losjes is gekoppeld, kunt u de gebruikersinterface opnieuw ontwerpen zonder dat u zich zorgen hoeft te maken over het verbreken van code. U kunt de functionaliteit echter onderbreken. U kunt bijvoorbeeld de knop verwijderen en de app wordt nog steeds gecompileerd en uitgevoerd, maar u hebt geen manier om het weer te vernieuwen. Aan de andere kant kunt u de Entry
en Button
besturingselementen vervangen door één SearchBar
besturingselement. Met dit besturingselement kunt u tekst invoeren en een opdracht aanroepen.
<SearchBar Text="{Binding Location, Mode=OneWayToSource}" SearchCommand="{Binding RefreshWeather}" />
Zoals u kunt zien, kan het gebruik van gegevensbinding in uw ui-ontwerp u helpen bij het ontwikkelen en wijzigen van uw gebruikersinterface zonder veel werk. De gebruikersinterface wordt automatisch gesynchroniseerd met de gegevens en de app-logica wordt gescheiden van de gebruikersinterface.