Esercizio - Sostituire il codice con binding di .NET MAUI
In questo esercizio si convertirà un'app che usa eventi e code-behind in un'app che usa principalmente il data binding. L'app di esempio è un'app di previsioni meteo che visualizza il meteo per la giornata.
Aprire la soluzione iniziale
Clonare o scaricare il repository dell'esercizio da GitHub.
Nota
È consigliabile clonare o scaricare il contenuto dell'esercizio in un percorso di cartella breve, ad esempio C:\dev, per evitare che i file generati dalla compilazione superino la lunghezza massima del percorso.
Aprire la soluzione WeatherClient.sln dalla cartella avviare usando Visual Studio o questa cartella in Visual Studio Code.
Compilare ed eseguire il progetto per assicurarsi che funzioni. Nella schermata visualizzata verranno mostrati alcuni dettagli meteo vuoti. Premere il pulsante Refresh per visualizzare l'aggiornamento dei dettagli meteo.
Di seguito è riportato, per riferimento, un riepilogo delle classi e dei file che verranno usati in questo esercizio.
File Descrizione MainPage.xaml Definisce l'interfaccia utente e la logica per la pagina iniziale. Il file XAML definisce l'interfaccia utente tramite markup. MainPage.xaml.cs Definisce l'interfaccia utente e la logica per la pagina iniziale. File code-behind associato che contiene il codice correlato all'interfaccia utente definita da MainPage.xaml. Services\WeatherService.cs Questa classe simula un servizio di segnalazione meteo. Contiene un singolo metodo denominato GetWeather
che restituisce un tipoWeatherData
.Models\WeatherData.cs Contiene i dati meteo. Si tratta di un semplice tipo di record che fornisce la temperatura, le precipitazioni, l'umidità, il vento e la condizione della giornata. Models\WeatherType.cs Enumerazione della condizione meteorologica, soleggiata o nuvolosa.
Impostare il contesto di binding
È necessario modificare il code-behind per il gestore eventi click del pulsante Refresh. Il codice ottiene attualmente i dati meteo e aggiorna direttamente i controlli. Ottenere invece i dati meteo e impostarli come contesto di binding per la pagina.
Aprire il file di codice MainPage.xaml.cs.
Esaminare il metodo
btnRefresh_Clicked
. Questo metodo esegue i passaggi seguenti:- Disabilita il pulsante e abilita la rotellina "occupato".
- Ottiene le previsioni meteo dal servizio meteo.
- Aggiorna i controlli nella pagina con le informazioni meteo.
- Abilita il pulsante e disabilita la rotellina "occupato".
Rimuovere il codice che aggiorna i controlli con i dati. Il codice dell'evento dovrebbe essere simile al frammento di codice seguente:
private async void btnRefresh_Clicked(object sender, EventArgs e) { btnRefresh.IsEnabled = false; actIsBusy.IsRunning = true; Models.WeatherData weatherData = await Services.WeatherServer.GetWeather(txtPostalCode.Text); btnRefresh.IsEnabled = true; actIsBusy.IsRunning = false; }
Anziché assegnare il risultato del metodo
GetWeather
del servizio a una variabile, assegnarlo aBindingContext
della pagina:private async void btnRefresh_Clicked(object sender, EventArgs e) { btnRefresh.IsEnabled = false; actIsBusy.IsRunning = true; BindingContext = await Services.WeatherServer.GetWeather(txtPostalCode.Text); btnRefresh.IsEnabled = true; actIsBusy.IsRunning = false; }
Eseguire il progetto. Si noti che quando si preme il pulsante Refresh e il servizio meteo restituisce i dati, nessuno dei controlli viene aggiornato con le previsioni meteo. Questo bug verrà risolto nella sezione successiva.
Creare binding in XAML
Ora che il code-behind imposta il contesto di binding per la pagina, è possibile aggiungere i binding ai controlli per usare i dati nel contesto.
Aprire il file MainPage.xaml.
Trovare
Grid
interno che contiene tutti i controlliLabel
.<Grid Grid.Row="2" RowDefinitions="Auto, Auto, Auto, Auto, Auto" ColumnDefinitions="Auto, Auto" Margin="0,5,0,0"> <Label Grid.Row="0" Grid.Column="0" Text="Condition" VerticalOptions="Center" /> <Image x:Name="imgCondition" Grid.Row="0" Grid.Column="1" HeightRequest="25" WidthRequest="25" Source="question.png" HorizontalOptions="Start" /> <Label Grid.Row="1" Grid.Column="0" Text="Temperature" Margin="0,0,20,0" /> <Label x:Name="lblTemperature" Grid.Row="1" Grid.Column="1" Text="0" /> <Label Grid.Row="2" Grid.Column="0" Text="Humidity" Margin="0,0,20,0" /> <Label x:Name="lblHumidity" Grid.Row="2" Grid.Column="1" Text="0" /> <Label Grid.Row="3" Grid.Column="0" Text="Precipitation" Margin="0,0,20,0" /> <Label x:Name="lblPrecipitation" Grid.Row="3" Grid.Column="1" Text="0" /> <Label Grid.Row="4" Grid.Column="0" Text="Wind" Margin="0,0,20,0" /> <Label x:Name="lblWind" Grid.Row="4" Grid.Column="1" Text="0" /> </Grid>
Aggiungere binding a ognuno dei controlli
Label
denominati. Ne sono presenti quattro.Il valore della proprietà
Label.Text
deve essere modificato nella sintassi{Binding PROPERTY_NAME}
in cuiPROPERTY_NAME
è una proprietà del tipoModels.WeatherData
definito in Models\WeatherData.cs. Tenere presente che questo tipo è il tipo di dati restituito dal servizio meteo.Ad esempio,
Label
denominatolblWind
(l'ultima etichetta nella griglia) deve avere una proprietàText
simile al codice seguente:<Label x:Name="lblWind" Grid.Row="4" Grid.Column="1" Text="{Binding Wind}" />
All'interno di
<Grid>
dei controlli in cui sono elencati tutti i dettagli meteo, rimuovere tutti gli attributix:Name="..."
.I nomi non sono necessari ora che nel code-behind non si fa riferimento ai controlli.
Verificare che i binding XAML corrispondano al frammento di codice seguente:
<Grid Grid.Row="2" RowDefinitions="Auto, Auto, Auto, Auto, Auto" ColumnDefinitions="Auto, Auto" Margin="0,5,0,0"> <Label Grid.Row="0" Grid.Column="0" Text="Condition" VerticalOptions="Center" /> <Image Grid.Row="0" Grid.Column="1" HeightRequest="25" WidthRequest="25" Source="question.png" HorizontalOptions="Start" /> <Label Grid.Row="1" Grid.Column="0" Text="Temperature" Margin="0,0,20,0" /> <Label Grid.Row="1" Grid.Column="1" Text="{Binding Temperature}" /> <Label Grid.Row="2" Grid.Column="0" Text="Humidity" Margin="0,0,20,0" /> <Label Grid.Row="2" Grid.Column="1" Text="{Binding Humidity}" /> <Label Grid.Row="3" Grid.Column="0" Text="Precipitation" Margin="0,0,20,0" /> <Label Grid.Row="3" Grid.Column="1" Text="{Binding Precipitation}" /> <Label Grid.Row="4" Grid.Column="0" Text="Wind" Margin="0,0,20,0" /> <Label Grid.Row="4" Grid.Column="1" Text="{Binding Wind}" /> </Grid>
Eseguire l'app e premere il pulsante Refresh. L'app funziona quasi come l'originale.
Si noti che l'icona che rappresenta Condition non viene aggiornata dal punto interrogativo a un'icona del sole o della nuvola. Perché l'icona non cambia? Poiché l'icona è una risorsa immagine scelta nel codice in base al valore dell'enumerazione WeatherData.Condition
. Il valore dell'enumerazione non può essere modificato in una risorsa immagine senza un impegno aggiuntivo. Questo problema viene risolto nell'esercizio successivo dopo aver appreso altre informazioni sui binding.