How to Build a Live Weather Dashboard Using REST API In .NET MAUI


TL;DR: Want to build a real-time weather dashboard using a REST API? This guide walks you through integrating Open-Meteo with .NET MAUI and Syncfusion® Charts to create a responsive, cross-platform UI with live metrics, forecasts, and interactive visualizations.
Introduction
In today’s data-driven world, visualizing real-time data is crucial for making informed decisions. Weather data represents one of the most dynamic and globally relevant datasets, making it perfect for demonstrating advanced dashboard capabilities. A Live Weather Dashboard not only provides visual clarity on atmospheric conditions but also makes complex meteorological trends accessible through interactive UI components.
This blog guide will walk you through creating a sophisticated Live Weather Dashboard using Syncfusion® MAUI Chart controls, demonstrating professional REST API integration, responsive progress bar visualizations, and cross-platform compatibility. Our dashboard will feature real-time weather metrics, interactive charts with custom tooltips, and seamless client-server architecture that delivers up-to-the-minute forecasts for any location worldwide.
Table of Contents
Understanding REST APIs in Weather Dashboard Context
Why Choose Syncfusion .NET MAUI Controls?
Project Architecture & MVVM Pattern
Loading Country Data from CSV Resources
Layout Structure Overview
Advanced Theme Support: Light & Dark Mode
Implementing Title and Country Selection with Syncfusion SfComboBox
Implementing REST API Client Architecture
Building Interactive Charts with Syncfusion
Weather Metrics with Circular Progress Bars
Understanding REST APIs in weather dashboard context
REST API (Representational State Transfer) serves as the foundational architecture for modern client-server communication, particularly crucial for data-driven applications like our Live Weather Dashboard. In the context of weather applications, REST APIs act as the critical bridge between your MAUI client application and external weather data providers, enabling real-time atmospheric data retrieval through standardized HTTP protocols.
Key benefits of REST API integration:
Stateless Each request is independent and self-contained.
Standard methods: Uses HTTP GET for easy data retrieval.
JSON format: Lightweight and easy to bind to UI.
Scalable: Handles multiple requests efficiently.
Real-time: Always fetches the latest data.
Why choose Syncfusion® .NET MAUI controls?
Syncfusion® MAUI Toolkit controls provide open-source components specifically designed for cross-platform applications:
Technical advantages:
High-performance rendering: Optimized for large datasets with smooth animations
Rich interactive features: Built-in tooltips, zooming, panning, and selection
Theme-aware components: Automatic adaptation to light/dark themes
MVVM-ready architecture: Seamless data binding and command support
Cross-platform consistency: Identical behavior across iOS, Android, Windows, and macOS
Extensive customization: Granular control over appearance and behavior
Project architecture & MVVM pattern
Our Live Weather Dashboard implements a robust MVVM (Model-View-ViewModel) architecture that separates concerns and enables efficient data binding.
Models (Data Structure):
Model classes are used to structure and manage weather data received from an REST API. These classes represent:
Location data (country name, latitude, longitude)
Daily weather metrics (temperature, precipitation, wind speed)
Hourly weather data (temperature and time)
Formatted data for easy chart binding
The JsonPropertyName attribute maps JSON keys from the API response to C# property names. This ensures accurate deserialization, even when the JSON field names don’t match your class property names.
public class Model
{
public string CountryName { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public Model(string countryName, double latitude, double longitude)
{
CountryName = countryName;
Latitude = latitude;
Longitude = longitude;
}
}
internal class WeatherData
{
[JsonPropertyName("daily")]
public Daily? DailyTemp { get; set; }
[JsonPropertyName("hourly")]
public Hourly? HourlyTemp { get; set; }
}
internal class Daily
{
[JsonPropertyName("temperature_2m_mean")]
public List<double>? TemperatureMean { get; set; }
[JsonPropertyName("precipitation_probability_mean")]
public List<double>? PrecipitationMean { get; set; }
[JsonPropertyName("wind_speed_10m_mean")]
public List<double>? WindSpeedMean { get; set; }
}
internal class Hourly
{
public List<string>? Time { get; set; }
[JsonPropertyName("temperature_2m")]
public List<double>? Temperature { get; set; }
}
public class HourlyTemperatureData
{
public DateTime? Time { get; set; }
public double Temperature { get; set; }
}
ViewModel (Business Logic)
public class WeatherViewModel: INotifyPropertyChanged
{
#region Private Fields
private Model selectedCountry;
private double dailyTemperature;
private double dailyWindSpeed;
private double dailyPrecipitation;
#endregion
#region Public Properties
public ObservableCollection<Model> CountriesDetail { get; set; }
public Model SelectedCountry
{
get => selectedCountry;
set
{
if (selectedCountry != value)
{
selectedCountry = value;
OnPropertyChanged();
}
}
}
public double DailyTemperature
{
get => dailyTemperature;
set { dailyTemperature = value; OnPropertyChanged(); }
}
public double DailyWindSpeed
{
get => dailyWindSpeed;
set { dailyWindSpeed = value; OnPropertyChanged(); }
}
public double DailyPrecipitation
{
get => dailyPrecipitation;
set { dailyPrecipitation = value; OnPropertyChanged(); }
}
public ObservableCollection<HourlyTemperatureData> HourlyTemperatures { get; set; } = new();
public ObservableCollection<HourlyTemperatureData> CurrentTemperatures { get; set; } = new();
public ObservableCollection<HourlyTemperatureData> ForecastTemperatures { get; set; } = new();
#endregion
public WeatherViewModel()
{
CountriesDetail = new ObservableCollection<Model>();
}
}
Loading country data from CSV resources
We begin by loading a list of countries along with their geographic coordinates’ latitude and longitude, from a CSV file. This data is essential for fetching accurate weather information using REST APIs. We use a publicly available dataset from Google’s canonical country list, which includes country names and their respective coordinates. Place it in our project’s resource folder (for example, Resources/Data/countriesdetail.csv), also mark its Build Action as Embedded Resource.
Reading the CSV file in .NET MAUI:
In the WeatherViewModel class, the CSV file is read, and country details are loaded into the CountriesDetail observable collection. The following functions assist in this process:
GetManifestResourceStream(): Retrieves the embedded CSV resource from the assembly.
Any: Supports parsing various number formats from the CSV.
InvariantCulture: Ensures consistent number parsing across different locales.
TryParse(): Safely converts string values to numeric types with built-in error handling.
public class WeatherViewModel : INotifyPropertyChanged
{
public WeatherViewModel()
{
CountriesDetail = new ObservableCollection<Model>();
LoadCountriesFromCSVFile();
}
private void LoadCountriesFromCSVFile()
{
try
{
Assembly executingAssembly = typeof(WeatherViewModel).GetTypeInfo().Assembly;
var resourceName = "WeatherDashBoardDemo.Resources.Data.countriesdetail.csv";
using Stream? inputStream = executingAssembly?.GetManifestResourceStream(resourceName);
if (inputStream == null)
{
Debug.WriteLine("Could not find countries CSV resource.");
return;
}
using StreamReader reader = new(inputStream);
// Remove header
string? header = reader.ReadLine();
while (!reader.EndOfStream)
{
string? line = reader.ReadLine();
var data = line.Split(',');
// Format: Country,Lattitude,Longitude
if (data.Length >= 3 &&
double.TryParse(data[1], NumberStyles.Any, CultureInfo.InvariantCulture, out double lat) &&
double.TryParse(data[2], NumberStyles.Any, CultureInfo.InvariantCulture, out double lon))
{
CountriesDetail.Add(new Model(data[0], lat, lon));
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"Error loading CSV: {ex.Message}");
}
}
}
Layout structure overview
Our weather dashboard is organized into several main sections:
Header and description: Title and description that clearly state the dashboard’s purpose.
Country selection panel: Syncfusion® ComboBox to select a country, bound to your loaded CSV list.
Main content:
Temperature Line Chart: Shows a 7-day hourly forecast using Syncfusion® SfCartesianChart.
Metric cards (Progress Rings): Circular progress bars visualize temperature, wind speed, and precipitation highlights for today.
<Border Padding="18" Background="{AppThemeBinding Light='#FFF', Dark='#22242D'}" ...>
<Grid RowDefinitions="Auto,*" RowSpacing="18">
<!-- Header and Controls -->
<Grid ColumnDefinitions="*,Auto,Auto" ...>...</Grid>
<!-- Chart and Cards Section -->
<Grid Grid.Row="1">
<!-- Chart Section -->
<chart:SfCartesianChart ... />
<!-- Metrics Section -->
<VerticalStackLayout Spacing="14">
<progressBar:SfCircularProgressBar ... />
<progressBar:SfCircularProgressBar ... />
<progressBar:SfCircularProgressBar ... />
</VerticalStackLayout>
</Grid>
</Grid>
</Border>
Advanced theme support: Light & dark mode
Modern applications require seamless adaptation between light and dark themes to provide an optimal user experience across different environments and user preferences. Our Live Weather Dashboard implements comprehensive theme support, which enables dynamic styling of Syncfusion® controls.
The dashboard features an intuitive theme toggle button that allows users to manually switch between light and dark modes. This implementation leverages AppTheme and ThemeKeys for Syncfusion® control theming and AppThemeBinding for native MAUI controls.
<Button Text="Change Theme"
TextColor="{AppThemeBinding Light='White', Dark='Black'}"
FontSize="13"
Padding="12,6"
WidthRequest="130"
HeightRequest="40"
Background="#00C9A7"
BorderColor="{AppThemeBinding Light='#00C9A7', Dark='#3C3F4F'}"
BorderWidth="1"
CornerRadius="10"
Clicked="Button_Clicked"/>
private void Button_Clicked(object sender, EventArgs e)
{
if (App.Current != null)
{
if (App.Current.RequestedTheme == AppTheme.Light)
{
App.Current.UserAppTheme = AppTheme.Dark;
}
else
{
App.Current.UserAppTheme = AppTheme.Light;
}
}
}
Implementing title and country selection with Syncfusion® SfComboBox
Use the Label control to display a prominent title and descriptive text that clearly conveys the purpose of the dashboard. For country selection, integrate Syncfusion’s SfComboBox, which provides a highly customizable and theme-aware dropdown experience in .NET MAUI.
The ComboBox is bind to the CountriesDetailcollection, which is populated from a CSV file containing country names and their geographic coordinates.
<!-- Header Section -->
<Grid ColumnDefinitions="*,Auto,Auto" RowDefinitions="Auto,Auto" Padding="0,0,0,8">
<Label Text="Live Weather Dashboard"
FontSize="28"
FontAttributes="Bold"/>
<Label Text="Explore detailed real-time weather statistics, engaging charts, and stay ahead with a 7-day forecast tailored for chosen country."
Grid.Row="1"
Grid.Column="0"
FontSize="14"/>
<!--Country Selection section-->
<comboBox:SfComboBox WidthRequest="145"
HeightRequest="38"
Background="{AppThemeBinding Light='White', Dark='#2A2D3E'}"
TextColor="{AppThemeBinding Light='#1F2937', Dark='White'}"
ItemsSource="{Binding CountriesDetail}"
IsClearButtonVisible="False"
DropDownBackground="{AppThemeBinding Light='White', Dark='#302D38'}"
DisplayMemberPath="CountryName"
DropDownItemTextColor="{AppThemeBinding Light='#1F2937', Dark='White'}"
DropDownIconColor="{AppThemeBinding Light='Black',Dark='White'}"
SelectedItem="{Binding SelectedCountry}"
SelectedIndex="0"
ShowBorder="False"/>
</ Grid>
Implementing REST API client architecture
The REST API client architecture forms the backbone of our Live Weather Dashboard, enabling seamless communication between the client application and external weather services. Our implementation follows enterprise-grade patterns for reliability, performance, and maintainability
Country selection
The weather data retrieval process begins with country selection. A reactive property setter automatically triggers the API call when the user changes their selection:
public Model SelectedCountry
{
get => selectedCountry;
set
{
if (selectedCountry != value)
{
selectedCountry = value;
OnPropertyChanged();
FetchWeatherData(selectedCountry);
}
}
}
REST API client implementation
We use the Open-Meteo REST API to fetch weather data. The FetchWeatherData method implements robust HTTP client architecture with comprehensive error handling and efficient JSON deserialization. This method serves as the primary interface between our application and the Open-Meteo weather service.
API endpoint construction:
The method constructs a sophisticated REST API endpoint with multiple query parameters:
Latitude/Longitude: Precise geographic coordinates from the selected country
Daily Metrics: temperature_2m_mean, precipitation_probability_mean, wind_speed_10m_mean
Hourly Data: temperature_2m for detailed forecast visualization
Timezone Handling: auto ensures localized time representation
Forecast Duration: forecast_days=7 provides a full week of weather data
private async void FetchWeatherData(Model country)
{
if (country == null)
return;
string url = "https://api.open-meteo.com/v1/forecast" +
$"?latitude={country.Latitude.ToString(CultureInfo.InvariantCulture)}" +
$"&longitude={country.Longitude.ToString(CultureInfo.InvariantCulture)}" +
"&DailyTemp=Temperature_2m_mean,Precipitation_probability_mean,Wind_speed_10m_mean" +
"&HourlyTemp=Temperature_2m" +
"&timezone=auto" +
"&forecast_days=7";
}
HTTP client management and JSON deserialization:
Efficient HTTP client management and robust JSON deserialization are building reliable and scalable REST API integrations. In our Live Weather Dashboard, we use the HttpClient class to perform a GET request to the Open-Meteo API, retrieving structured weather data in JSON format.
private async void FetchWeatherData(Model country)
{
try
{
using HttpClient client = new HttpClient();
var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var data = JsonSerializer.Deserialize<WeatherData>(json, options);
if (data != null && data.DailyTemp != null && data.HourlyTemp != null)
{
// Current Weather Metrics
DailyTemperature = data.DailyTemp.Temperature_2m_mean?.Count > 0
? data.DailyTemp.Temperature_2m_mean[0]
: 0;
DailyWindSpeed = data.DailyTemp.Wind_speed_10m_mean?.Count > 0
? data.DailyTemp.Wind_speed_10m_mean[0]
: 0;
DailyPrecipitation = data.DailyTemp.Precipitation_probability_mean?.Count > 0
? data.DailyTemp.Precipitation_probability_mean[0]
: 0;
// Temperature Forecast
HourlyTemperatures.Clear();
if (data.HourlyTemp?.Temperature_2m != null && data.HourlyTemp?.Time != null)
{
DateTime now = DateTime.Now;
int max = Math.Min(168, data.HourlyTemp.Temperature_2m.Count);
for (int i = 0; i < max; i++)
{
if (DateTime.TryParse(data.HourlyTemp.Time[i], out DateTime hTime))
{
HourlyTemperatures.Add(new HourlyTemperatureData
{
Time = hTime,
Temperature = data.HourlyTemp.Temperature_2m[i]
});
}
}
OnPropertyChanged(nameof(HourlyTemperatures));
}
SplitHourlyDataForTodayAndForecast();
OnPropertyChanged(nameof(CurrentTemperatures));
OnPropertyChanged(nameof(ForecastTemperatures));
}
}
else
{
Debug.WriteLine($"API call failed with status {response.StatusCode}");
}
}
catch (Exception ex)
{
Debug.WriteLine($"Error fetching weather data: {ex.Message}");
}
}
Data processing: Current vs. Forecast separation
The method SplitHourlyDataForTodayAndForecast() is invoked immediately after successful API response handling in FetchWeatherData(). It organizes hourly temperature data into two distinct collections:
CurrentTemperatures: Contains data for today, including midnight of the next day.
ForecastTemperatures: Contains data starting from midnight of the next day onward.
private async void FetchWeatherData(Model country)
{
// ... API data retrieval and processing logic
// Execute data separation after successful API processing
SplitHourlyDataForTodayAndForecast();
}
private void SplitHourlyDataForTodayAndForecast()
{
CurrentTemperatures.Clear();
ForecastTemperatures.Clear();
var now = DateTime.Now;
var today = now.Date;
var tomorrow = today.AddDays(1);
// Track if we've already included the 12AM of the next day
bool addedMidnightForecast = false;
foreach (var item in HourlyTemperatures)
{
// Today's bucket
if (item.Time < tomorrow)
{
CurrentTemperatures.Add(item);
}
// Special: include exactly midnight of "tomorrow" in today's series
else if (item.Time == tomorrow)
{
CurrentTemperatures.Add(item);
ForecastTemperatures.Add(item);
addedMidnightForecast = true;
}
// Forecast bucket
else if (item.Time > tomorrow || (item.Time == tomorrow && !addedMidnightForecast))
{
ForecastTemperatures.Add(item);
}
}
}
Building interactive Charts with Syncfusion
To visualize weather trends clearly and interactively, the dashboard uses Syncfusion® MAUI Toolkit SfCartesianChart, a powerful charting control that supports animation, tooltips, and theme-aware customization.
It supports:
Custom axis configuration for time and temperature.
Tooltip and Series support enhanced interactivity.
Theme customization using AppThemeBinding.
<chart:SfCartesianChart>
<chart:SfCartesianChart.Title>
<Label Text="Temperature Forecast"
FontSize="20"
TextColor="{AppThemeBinding Light='#1E293B', Dark='White'}"
FontAttributes="Bold"
HorizontalOptions="Center"/>
</chart:SfCartesianChart.Title>
<chart:SfCartesianChart.XAxes>
<chart:DateTimeAxis IntervalType="Days" Interval="1" ShowMajorGridLines="False">
<chart:DateTimeAxis.LabelStyle>
<chart:ChartAxisLabelStyle LabelFormat="dd-MMM"
TextColor="{AppThemeBinding Light='#222', Dark='#C1CCDE'}"/>
</chart:DateTimeAxis.LabelStyle>
</chart:DateTimeAxis>
</chart:SfCartesianChart.XAxes>
<chart:SfCartesianChart.YAxes>
<chart:NumericalAxis Interval="5" ShowMajorGridLines="False">
<chart:NumericalAxis.Title>
<chart:ChartAxisTitle Text="Temperature (°C)"
TextColor="{AppThemeBinding Light='#252525', Dark='#AEB4BF'}"/>
</chart:NumericalAxis.Title>
<chart:NumericalAxis.LabelStyle>
<chart:ChartAxisLabelStyle TextColor="{AppThemeBinding Light='#252525', Dark='#AEB4BF'}"/>
</chart:NumericalAxis.LabelStyle>
</chart:NumericalAxis>
</chart:SfCartesianChart.YAxes>
<chart:SfCartesianChart.ZoomPanBehavior>
<chart:ChartZoomPanBehavior EnablePanning="True"/>
</chart:SfCartesianChart.ZoomPanBehavior>
</chart:SfCartesianChart>
Dynamically updating Charts with REST API Data
The dashboard displays both current and forecasted temperature data using two LineSeries in the chart, bound to REST API-driven ObservableCollection properties: CurrentTemperatures and ForecastTemperatures in the ViewModel.
When a new REST API response arrives, these collections are updated, and the chart’s ItemsSource property ensures the UI automatically and instantly reflects the latest current and forecasted data—no manual refresh logic required. This approach delivers fast, real-time, and reactive data-visualization for our live weather dashboard.
<chart:SfCartesianChart>
<chart:LineSeries
ItemsSource="{Binding CurrentTemperatures}"
XBindingPath="Time"
YBindingPath="Temperature"
EnableAnimation="True"
EnableTooltip="True" />
<chart:LineSeries
ItemsSource="{Binding ForecastTemperatures}"
XBindingPath="Time"
YBindingPath="Temperature"
EnableTooltip="True"
EnableAnimation="True"
Fill="{AppThemeBinding Light='#7B8B9D', Dark='#68C1F2'}" />
</chart:SfCartesianChart>
Customizing tooltips in Syncfusion Charts
To enhance data readability and user interaction, the dashboard includes custom tooltips for the temperature chart. These tooltips display both the timestamp and temperature value in a clean, theme-aware format.
Using the TooltipTemplate property available in the chart series, we bind a custom DataTemplate that dynamically formats the tooltip content based on the bound data.
<chart:SfCartesianChart BackgroundColor="{AppThemeBinding Light='#FFFBFE', Dark='#302D38'}">
<chart:SfCartesianChart.Resources>
<DataTemplate x:Key="tooltipTemplate">
<StackLayout Orientation="Vertical" Padding="5">
<Label Text="{Binding Item.Time, StringFormat='{0:dd MMM hh:mm tt}'}"
TextColor="{AppThemeBinding Light='White',Dark='Black'}"
FontAttributes="Bold"
FontSize="12"
HorizontalOptions="Center"/>
<Label Text="{Binding Item.Temperature, StringFormat='Temp: {0}°C'}"
TextColor="{AppThemeBinding Light='White',Dark='Black'}"
FontAttributes="Bold"
FontSize="12"
HorizontalOptions="Center"/>
</StackLayout>
</DataTemplate>
</chart:SfCartesianChart.Resources>
<chart:LineSeries TooltipTemplate="{StaticResource tooltipTemplate}"/>
<chart:LineSeries TooltipTemplate="{StaticResource tooltipTemplate}"/>
</chart:SfCartesianChart>
Weather metrics with Circular Progress Bars
The Syncfusion SfCircularProgressBar control provides an elegant way to display current weather conditions such as temperature, wind speed, and precipitation in a circular format, with animated, theme-aware progress indicators that effectively communicate data intensity and context.
<VerticalStackLayout Spacing="14" Padding="0">
<Label Text="Current Weather Metrics"
TextColor="{AppThemeBinding Light='#1E293B', Dark='White'}"
FontSize="18"
FontAttributes="Bold"
HorizontalOptions="Center"/>
<!-- Temperature -->
<progressBar:SfCircularProgressBar WidthRequest="135" HeightRequest="135"
Progress="{Binding DailyTemperature}"
Maximum="50"
TrackFill="{AppThemeBinding Light='#C0F1EC', Dark='#495662'}"
ProgressFill="{AppThemeBinding Light='#00C9A7', Dark='#00C9A7'}"
TrackThickness="0.2"
ProgressThickness="0.2"
ThicknessUnit="Factor"
AnimationEasing="{x:Static Easing.CubicInOut}">
<progressBar:SfCircularProgressBar.Content>
<VerticalStackLayout>
<Label Text="Temperature"
TextColor="{AppThemeBinding Light='#5C6E87', Dark='#BFC9CA'}"
FontSize="13"/>
<Label Text="{Binding DailyTemperature, StringFormat='{0}°C'}"
TextColor="{AppThemeBinding Light='#262626', Dark='#D0D0D0'}"
FontAttributes="Bold"
FontSize="16"
HorizontalOptions="Center"/>
</VerticalStackLayout>
</progressBar:SfCircularProgressBar.Content>
</progressBar:SfCircularProgressBar>
<!-- Wind Speed -->
<progressBar:SfCircularProgressBar WidthRequest="135"
HeightRequest="135"
Progress="{Binding DailyWindSpeed}"
Maximum="50"
TrackFill="{AppThemeBinding Light='#C0F1EC', Dark='#495662'}"
ProgressFill="{AppThemeBinding Light='#00C9A7', Dark='#00C9A7'}"
TrackThickness="0.2"
ProgressThickness="0.2"
ThicknessUnit="Factor"
AnimationEasing="{x:Static Easing.CubicInOut}">
<progressBar:SfCircularProgressBar.Content>
<VerticalStackLayout>
<Label Text="WindSpeed"
TextColor="{AppThemeBinding Light='#5C6E87', Dark='#BFC9CA'}"
FontSize="13"/>
<Label Text="{Binding DailyWindSpeed, StringFormat='{0}km/h'}"
TextColor="{AppThemeBinding Light='#262626', Dark='#D0D0D0'}"
FontAttributes="Bold"
FontSize="14"
HorizontalOptions="Center"/>
</VerticalStackLayout>
</progressBar:SfCircularProgressBar.Content>
</progressBar:SfCircularProgressBar>
<!-- Precipitation -->
<progressBar:SfCircularProgressBar WidthRequest="135" HeightRequest="135"
Progress="{Binding DailyPrecipitation}"
Maximum="100"
TrackFill="{AppThemeBinding Light='#C0F1EC', Dark='#495662'}"
ProgressFill="{AppThemeBinding Light='#00C9A7', Dark='#00C9A7'}"
BackgroundColor="Transparent"
TrackThickness="0.2"
ProgressThickness="0.2"
ThicknessUnit="Factor"
AnimationEasing="{x:Static Easing.CubicInOut}">
<progressBar:SfCircularProgressBar.Content>
<VerticalStackLayout>
<Label Text="Precipitation"
TextColor="{AppThemeBinding Light='#5C6E87', Dark='#BFC9CA'}"
FontSize="13"/>
<Label Text="{Binding DailyPrecipitation, StringFormat='{0}%'}"
TextColor="{AppThemeBinding Light='#262626', Dark='#D0D0D0'}"
FontAttributes="Bold"
FontSize="16"
HorizontalOptions="Center"/>
</VerticalStackLayout>
</progressBar:SfCircularProgressBar.Content>
</progressBar:SfCircularProgressBar>
</VerticalStackLayout>
Weather Dashboard in .NET MAUI with REST API
FAQs
Q1: Can I use this dashboard with any weather API? Yes, while this example uses Open-Meteo, the architecture supports any RESTful weather API that returns JSON data.
Q2: How does the dashboard handle themes switching? The dashboard handles theme switching dynamically using AppTheme. It checks the current theme using Current.RequestedTheme, and toggles between light and dark modes by setting App.Current.UserAppTheme accordingly.
Q3: Is this dashboard compatible with Android and iOS? Absolutely! Syncfusion MAUI controls are designed for cross-platform development, including Android, iOS, Windows, and macOS.
Q4: How are the weather metrics visualized? Temperature, wind speed, and precipitation are displayed using animated SfCircularProgressBar controls for a clean and intuitive UI.
Q5: Can I customize the chart tooltips and appearance? Yes, Syncfusion charts support custom tooltip templates, axis styling, and series customization to match your design needs.
GitHub reference
For more details, refer to the runnable sample on GitHub demo.
Conclusion
Thank you for reading! In this blog, we explored how to build a real-time Live Weather Dashboard using Syncfusion® .NET MAUI Toolkit controls and REST API integration. From loading country data via CSV, fetching live weather updates using Open- Meteo API, and visualizing metrics with interactive charts and circular progress bars, we demonstrated how to create a responsive, theme-aware, and cross-platform weather dashboard.
The existing customers can download the new version of Essential Studio on the license and downloads page. If you are not a Syncfusion® customer, try our 30-day free trial to check out our incredible features.
You can also contact us through our support forum, support portal, or feedback portal. We are always happy to assist you!
Related Blogs
Subscribe to my newsletter
Read articles from syncfusion directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

syncfusion
syncfusion
Syncfusion provides third-party UI components for React, Vue, Angular, JavaScript, Blazor, .NET MAUI, ASP.NET MVC, Core, WinForms, WPF, UWP and Xamarin.