What you will learn
- Combine skills from the previous lessons into a full example
- Retrieve current conditions via Open-Meteo without a paid API key
- Remember the selected city using Preferences
MauiWeather with .NET 10. Use the complete file listings below, and leave other template-generated files unchanged unless the lesson explicitly says otherwise. Run the Android target on Windows.1. Plan the weather dashboard
Create a .NET MAUI App named MauiWeather. The dashboard lets a user choose Kuala Lumpur, Singapore, Tokyo or London; then it retrieves current temperature, relative humidity and wind speed from the Open-Meteo forecast API over HTTPS. Fixed city coordinates avoid location permissions and make the example reproducible.
2. Design the XAML
The interface contains a Picker for the city, a Refresh button, a status label, and three result cards. A ScrollView keeps the page usable on smaller devices. This is a stand-alone example—no assets or paid subscriptions are required.
3. Implement the data retrieval
The code builds the URL using InvariantCulture to guarantee that decimal coordinates use periods. The Open-Meteo JSON response contains a current object. Read its temperature_2m, relative_humidity_2m and wind_speed_10m properties, then show the values in the UI.
The example catches networking, JSON parsing and timeout errors, prevents overlapping requests by disabling the Refresh button, and stores the selected city index with Preferences.Default.
4. Test the finished app
- Run the app on an Android emulator or connected Android phone.
- Choose Kuala Lumpur and tap Load weather.
- Change to another city and refresh.
- Restart the app to confirm the city selection is remembered.
- Disconnect the network and verify that the status label shows a useful error instead of crashing.
5. Next improvements
Add weather codes and icons, local caching, a timestamp of the last successful response and a list of favorite cities. An advanced version could use device location, but it would need platform permissions, explicit user consent and on-device validation.
Complete sample code
Use the exact file names and folder locations shown below. Copy each listing into your MAUI project. The separate source files can also be downloaded individually.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiWeather.MainPage"
Title="City Weather">
<ScrollView>
<VerticalStackLayout Padding="24" Spacing="14">
<Label Text="City Weather Dashboard"
FontSize="26" FontAttributes="Bold" />
<Label Text="Choose a city" />
<Picker x:Name="CityPicker" Title="Select a city" />
<Button x:Name="RefreshButton" Text="Load weather"
Clicked="OnRefreshClicked" />
<Label x:Name="StatusLabel" Text="Tap Load weather."
FontSize="14" />
<Border Padding="18" BackgroundColor="#E6F4FF"
StrokeShape="RoundRectangle 16">
<VerticalStackLayout Spacing="6">
<Label Text="Temperature" TextColor="#34566E" />
<Label x:Name="TemperatureLabel" Text="—"
FontSize="32" FontAttributes="Bold" />
</VerticalStackLayout>
</Border>
<Border Padding="18" BackgroundColor="#ECFDF5"
StrokeShape="RoundRectangle 16">
<VerticalStackLayout Spacing="6">
<Label Text="Relative humidity" TextColor="#34566E" />
<Label x:Name="HumidityLabel" Text="—"
FontSize="24" />
</VerticalStackLayout>
</Border>
<Border Padding="18" BackgroundColor="#F2F2FF"
StrokeShape="RoundRectangle 16">
<VerticalStackLayout Spacing="6">
<Label Text="Wind speed" TextColor="#34566E" />
<Label x:Name="WindLabel" Text="—"
FontSize="24" />
</VerticalStackLayout>
</Border>
</VerticalStackLayout>
</ScrollView>
</ContentPage>using Microsoft.Maui.Storage;
using System.Globalization;
using System.Text.Json;
namespace MauiWeather;
public partial class MainPage : ContentPage
{
private static readonly HttpClient Client = new()
{
Timeout = TimeSpan.FromSeconds(15)
};
private readonly (string Name, double Lat, double Lon)[] cities =
[
("Kuala Lumpur", 3.1390, 101.6869),
("Singapore", 1.3521, 103.8198),
("Tokyo", 35.6762, 139.6503),
("London", 51.5072, -0.1276)
];
public MainPage()
{
InitializeComponent();
CityPicker.ItemsSource = cities.Select(c => c.Name).ToList();
int saved = Preferences.Default.Get("cityIndex", 0);
CityPicker.SelectedIndex = Math.Clamp(saved, 0, cities.Length - 1);
}
private async void OnRefreshClicked(object sender, EventArgs e)
{
int index = CityPicker.SelectedIndex;
if (index < 0) return;
Preferences.Default.Set("cityIndex", index);
var city = cities[index];
string lat = city.Lat.ToString(CultureInfo.InvariantCulture);
string lon = city.Lon.ToString(CultureInfo.InvariantCulture);
string url = "https://api.open-meteo.com/v1/forecast" +
$"?latitude={lat}&longitude={lon}" +
"¤t=temperature_2m,relative_humidity_2m,wind_speed_10m";
RefreshButton.IsEnabled = false;
StatusLabel.Text = $"Loading {city.Name}...";
try
{
using var response = await Client.GetAsync(url);
response.EnsureSuccessStatusCode();
string jsonText = await response.Content.ReadAsStringAsync();
using var doc = JsonDocument.Parse(jsonText);
var current = doc.RootElement.GetProperty("current");
double temp = current.GetProperty("temperature_2m").GetDouble();
double humidity = current.GetProperty("relative_humidity_2m").GetDouble();
double wind = current.GetProperty("wind_speed_10m").GetDouble();
TemperatureLabel.Text = $"{temp:0.#} °C";
HumidityLabel.Text = $"{humidity:0}%";
WindLabel.Text = $"{wind:0.#} km/h";
StatusLabel.Text = $"Current conditions for {city.Name}.";
}
catch (Exception ex) when (ex is HttpRequestException
or TaskCanceledException
or JsonException
or KeyNotFoundException)
{
StatusLabel.Text = "Weather unavailable. Check the connection and try again.";
}
finally
{
RefreshButton.IsEnabled = true;
}
}
}<!-- Add inside the existing <manifest> element only if absent. -->
<uses-permission android:name="android.permission.INTERNET" />Common problems and solutions
- No data loads: Check Internet permission, connectivity and whether the Open-Meteo API is reachable.
- Temperature stays blank: The app only fetches after you tap Load weather.
- The weather values look different from another app: Weather providers use different models, refresh times and locations.
Practice exercise
Add a fifth city and a last-updated timestamp based on the response. Clearly label the timezone of the timestamp.