---
title: "Build a Weather Dashboard with .NET MAUI Tab View"
published_at: "2026-05-19T11:48:12+00:00"
modified_at: "2026-05-25T02:35:37+00:00"
url: "https://www.syncfusion.com/blogs/post/real-time-weather-dashboard-maui-tab-view"
excerpt: "Build a fast, responsive weather dashboard in .NET MAUI using Tab View, fetch real-time forecasts, handle async data, and deliver a smooth cross-platform UX."
taxonomy_category:
  - ".NET MAUI"
  - "Cross-platform"
  - "Desktop"
  - "Mobile"
  - "Tab View"
  - "UI"
taxonomy_post_tag:
  - ".NET MAUI"
  - "Cross-Platform"
  - "desktop"
  - "development"
  - "Mobile"
  - "Tab View"
---

# Build a Weather Dashboard with .NET MAUI Tab View

[Sneha Kumar](https://www.syncfusion.com/blogs/author/sneha-kumar)

![Easily Build a Real-Time Weather Dashboard with .NET MAUI Tab View](https://www.syncfusion.com/blogs/wp-content/uploads/2026/05/Easily-Build-a-Real-Time-Weather-Dashboard-with-.NET-MAUI-Tab-View.jpg)


**TL;DR:** With .NET MAUI Tab View, you can create a sleek, responsive dashboard where switching between cities feels instant, real-time data from Open‑Meteo loads smoothly in the background, and multi-day forecasts are presented in a clean, visually intuitive layout that’s easy to explore and rely on.

A weather app should do more than just show numbers; it should feel smooth and effortless to use. Imagine tapping once to switch cities, seeing updates instantly, and checking a clean, easy-to-follow forecast for the week ahead.

That’s exactly what you can build with Syncfusion® [.NET MAUI Tab View](https://www.syncfusion.com/maui-controls/maui-tab-view)
.

In this guide, we’ll create a responsive weather dashboard that fetches live data from a remote API and presents it in a clean, modern way. By combining Tab View with smart asynchronous loading, we’ll build an app that feels fast, polished, and easy to use.

## What you will learn

Here, we’ll learn to:

- Implement the [.NET MAUI Tab View](https://help.syncfusion.com/maui/tabview/getting-started) for effortless navigation through cities.
- Fetch and parse real-time weather data from a reliable API.
- Display current conditions and multi-day forecasts with a clean design.
- Keep the UI smooth and responsive, even when switching tabs.

## Designing a weather dashboard with .NET MAUI Tab View

Let’s follow these steps to build a weather dashboard with the .NET MAUI Tab View:

**Note:** Before proceeding, refer to our [.NET MAUI Tab View getting started documentation](https://help.syncfusion.com/maui/tabview/getting-started)
.

### Step 1: Adding city tabs

Start by making the dashboard interactive with [SfTabView.](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.TabView.SfTabView.html?tabs=tabid-1)
 Each tab represents a city, and the header automatically shows the city name. This lets users switch between locations with a single tap, making navigation simple and intuitive.

MainPage.xaml

```
<tabview:SfTabView x:Name="LocationTabView" ItemsSource="{Binding Cities}" IndicatorBackground="White">

  <!-- Header: city title -->
  <tabview:SfTabView.HeaderItemTemplate>
     <DataTemplate>
        <Label Text="{Binding Name}" TextColor="White"/>
     </DataTemplate>
  </tabview:SfTabView.HeaderItemTemplate>

</tabview:SfTabView>
```

### Step 2: Customizing background views to improve the look and feel

Give your dashboard a modern touch by adding a radial gradient background to the page. This simple design choice instantly elevates the look, making the interface sleek, vibrant, and visually appealing.

MainPage.xaml

```
<ContentPage.Background>
    <RadialGradientBrush Center="0.5,0.35" Radius="0.9">
       <GradientStop Color="#3A91F7" Offset="0.0" />
       <GradientStop Color="#0D2C4D" Offset="0.55" />
       <GradientStop Color="#071421" Offset="1.0" />
    </RadialGradientBrush>
</ContentPage.Background>
```

Refer to the following images.


Customizing the background view in the weather dashboard

### Step 3: Define data models for weather API response

To keep things structured, create data models that mirror the API response. This makes parsing JSON simple and keeps your app maintainable.

C#

```
public class WeatherApiResponse
{
    [JsonPropertyName("hourly")]
    public HourlyData? Hourly { get; set; }

    [JsonPropertyName("daily")]
    public DailyData? Daily { get; set; }
}

public class HourlyData
{
    [JsonPropertyName("temperature_2m")]
    public List<double>? TemperatureData { get; set; }

    [JsonPropertyName("weathercode")]
    public List<int>? Weather { get; set; }
}

public class DailyData
{
    [JsonPropertyName("time")]
    public List<string>? Time { get; set; }

    [JsonPropertyName("temperature_2m_max")]
    public List<double>? TemperatureMax { get; set; }

    [JsonPropertyName("temperature_2m_min")]
    public List<double>? TemperatureMin { get; set; }

    [JsonPropertyName("weathercode")]
    public List<int>? WeatherData { get; set; }
}
```

Now, let’s turn raw weather data into a friendly forecast model. This simple model wraps each day’s details into a neat package, ready to display in your app with clarity and style.

C#

```
public class DailyForecastItem
{
public string DayText { get; set; } = ""; // e.g., "Tue • Jan 30" 
public string HighText { get; set; } = ""; // e.g., "High : 25°" 
public string LowText { get; set; } = ""; // e.g., "Low : 12°" 
public string Icon { get; set; } = "cloudy.png"; // Icon
}
```

### Step 4: Initialize the dashboard and load weather data instantly

When the app launches, it binds the dashboard to the `ViewModel`. Then, it automatically selects the first city and starts loading its weather data. Meanwhile, other cities are prepared in the background, so that switching tabs feels instant and smooth, keeping the experience fast and responsive.

MainPage.cs

```
private readonly WeatherMainViewModel viewmodel = new();

public MainPage()
{
    InitializeComponent();

    BindingContext = viewmodel;

    LocationTabView.SelectionChanged += (_, e) =>
    {
        int index = (int)e.NewIndex;

        if (index >= 0 && index < viewmodel.Cities.Count)
        {
            _ = viewmodel.Cities[index].EnsureLoadedAsync();
        }
    };
}

protected override async void OnAppearing()
{
    base.OnAppearing();

    if (viewmodel.Cities.Count > 0)
    {
        LocationTabView.SelectedIndex = 0;
        await viewmodel.WarmUpAsync();
    }
}
```

### Step 5: Display the key weather details clearly

Below the Tab View, let’s add a scrollable layout to display:

- Current date,
- Weather icon,
- Condition and temperature, and
- Horizontal scroll view for multi-day

This layout keeps the dashboard clean, organized, and easy to navigate, while giving users all the information they need at a glance.

MainPage.xaml

```
<tabview:SfTabView.ContentItemTemplate>
    <DataTemplate>
        <ScrollView>
            <VerticalStackLayout>

                <!-- current date -->
                <Label
                    Text="{Binding DateText}"
                    TextColor="White"
                    HorizontalOptions="Center" />

                <!-- current weather icon -->
                <Image
                    Source="{Binding Icon}"
                    HorizontalOptions="Center" />

                <!-- current weather condition -->
                <Label
                    Text="{Binding ConditionText}"
                    HorizontalOptions="Center"
                    TextColor="White" />

                <!-- current temperature -->
                <Label
                    Text="{Binding TempText}"
                    TextColor="White"
                    HorizontalOptions="Center" />

                <!-- Daily Forecast -->
                <ScrollView Orientation="Horizontal">
                    <CollectionView
                        ItemsSource="{Binding NextDays}"
                        ItemsLayout="HorizontalList"
                        HorizontalOptions="Center"
                        SelectionMode="None">

                        <CollectionView.ItemTemplate>
                            <!-- Scrollable view for daily weather forecast -->
                        </CollectionView.ItemTemplate>

                    </CollectionView>
                </ScrollView>

            </VerticalStackLayout>
        </ScrollView>
    </DataTemplate>
</tabview:SfTabView.ContentItemTemplate>
```

### Step 6: Set up city coordinates and prefetch weather data

The **ViewModel** takes care of retrieving city coordinates, loading the first city immediately, and prefetching the others in the background. Outdated requests are canceled automatically, while intuitive weather icons keep updates clear and reliable. This ensures the dashboard stays fast, error‑free, and seamless every time you switch tabs.

**Note:** For complete implementation details, refer to the [GitHub](https://github.com/SyncfusionExamples/Creating-Dynamic-Tabs-in-.NET-MAUI-Tab-View-Using-Remote-Data)
 demo.

WeatherMainViewModel.cs

```
private readonly Dictionary<string, (double Lat, double Lon)> CityCoordinates = new()
{
    { "Phoenix",        (33.45, -112.07) },
    { "Seattle",        (47.61, -122.33) },
    { "San Francisco",  (37.77, -122.42) },
    { "Miami",          (25.76, -80.19) },
    { "Denver",         (39.74, -104.99) },
    { "Chicago",        (41.88, -87.63) },
    { "New York",       (40.71, -74.01) },
};

public WeatherMainViewModel()
{
    foreach (var coordinates in CityCoordinates)
    {
        Cities.Add(new CityWeatherViewModel(
            coordinates.Key,
            coordinates.Value.Lat,
            coordinates.Value.Lon
        ));
    }
}

// Load the first city, then prefetch the rest
public async Task WarmUpAsync()
{
    if (Cities.Count == 0)
        return;

    await Cities[0].EnsureLoadedAsync();

    _ = Task.WhenAll(
        Cities
            .Skip(1)
            .Select(c => c.EnsureLoadedAsync())
    );
}
```

### Step 7: Mapping weather codes into meaningful insights

This step involves converting raw numeric weather codes into user-friendly visuals. This mapping ensures each [Open-Meteo code](https://open-meteo.com/)
 is translated into an intuitive label (e.g., “**Clear**,” “** Rain**”) with a corresponding icon, making forecasts easy to understand at a glance.

WeatherMapping.cs

```
public static (string Icon, string Label) Map(int weatherValue) =>
    weatherValue switch
    {
        0           => ("sunny.png", "Clear"),
        1 or 2      => ("partly_cloudy.png", "Partly cloudy"),
        3           => ("cloudy.png", "Cloudy"),

        // weather codes to icons and labels
        _           => ("unknown.png", "Unknown")
    };
```

### Step 8: Building an interactive weather forecast

Behind the scenes, the app keeps your forecast up to date. It cancels outdated requests, grabs the latest data from **Open-Meteo**, and instantly updates today’s temperature and conditions. Then, it builds a smooth weekly view, so you can scroll and plan with ease.

CityWeatherViewModel.cs

```
public Task EnsureLoadedAsync()
{
    if (isLoaded)
        return Task.CompletedTask;

    return loadTask ??= LoadCoreAsync();
}

private async Task LoadCoreAsync()
{
    // Cancel any in-flight request and create a fresh token

    try
    {
        string apiUrl =
            "https://api.open-meteo.com/v1/forecast" +
            $"?latitude={Latitude.ToString(CultureInfo.InvariantCulture)}" +
            $"&longitude={Longitude.ToString(CultureInfo.InvariantCulture)}" +
            "&hourly=temperature_2m,weathercode" + // Request hourly data
            "&daily=temperature_2m_max,temperature_2m_min,weathercode" +
            "&timezone=auto";

        // Deserialize the response

        // Compute today's temperature and weather code
        // Map to label and icon

        await MainThread.InvokeOnMainThreadAsync(() =>
        {
            // Update today's date, temperature, condition, and icon in the UI

            // Prepare and populate a scrollable weekly view
            // (dates, highs, lows, icons)
        });

        isLoaded = true;
    }
    catch (OperationCanceledException)
    {
        // Ignore cancellation
    }
    finally
    {
        // Reset load task if not completed
        if (!isLoaded)
            loadTask = null;
    }
}
```

### Step 9: Finding the right forecast day

Accuracy matters when showing future weather. Let’s implement the logic that scans a list of date strings, safely parses each one, and returns the index of the first date that is later than today. If no future date is found, it falls back to a default index. In this method, the invalid dates are skipped to avoid causing errors.

CityWeatherViewModel.cs

```
private static int GetFirstFutureDayIndex(System.Collections.Generic.List<string> dates)
{
    if (dates == null || dates.Count == 0)
        return 0;

    var today = DateTime.Now.Date;

    for (int i = 0; i < dates.Count; i++)
    {
        if (DateTime.TryParse(dates[i], out var d) && d.Date > today)
        {
            return i;
        }
    }

    return dates.Count > 1 ? 1 : 0;
}
```

After executing the above code example, our output will look like the following image


Designing a weather dashboard with .NET MAUI Tab View

## GitHub references

Also, find a complete code example to build a weather dashboard with .NET MAUI Tab View on [GitHub](https://github.com/SyncfusionExamples/Creating-Dynamic-Tabs-in-.NET-MAUI-Tab-View-Using-Remote-Data)
 repository.

## Frequently Asked Questions

How do I bind the cities collection to SfTabView and template headers/content per city?You can bind the Cities collection to the **`ItemsSource`** property of ** SfTabView**. Then, define the `HeaderItemTemplate` to display each city’s header, such as the city name or an icon, and `ContentItemTemplate` to define the UI shown for each city’s content. You can refer to the [MainPage.xaml](https://github.com/SyncfusionExamples/Creating-Dynamic-Tabs-in-.NET-MAUI-Tab-View-Using-Remote-Data/blob/master/DynamicTabs/DynamicTabs/MainPage.xaml)
 file for a complete implementation example.

How do I load or refresh weather data when the selected tab changes (lazy load, prefetch, cancellation)?To refresh weather data when the selected tab changes, bind SelectedIndex using `SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}`“. Then, handle the `SelectionChanged`event to call each city’s `EnsureLoadedAsync()` method. You can also prefetch adjacent cities by running background tasks using `Task.WhenAll(...)`. For robustness, make sure to cancel outdated or overlapping fetch requests with a per-city `CancellationTokenSource`. Refer to the [WeatherMainViewModel.cs](https://github.com/SyncfusionExamples/Creating-Dynamic-Tabs-in-.NET-MAUI-Tab-View-Using-Remote-Data/blob/master/DynamicTabs/DynamicTabs/ViewModel/WeatherMainViewModel.cs)
 file for the complete implementation.

Do I need an API key for the weather provider, and can I swap providers easily?**Open-Meteo** requires no API key. To swap providers, change the request URL, and adjust models. Keep the API logic in the ** ViewModel** or service layer so views remain unchanged.

How should I model and parse the API response and map weather codes to readable labels/icons?Mirror JSON with `WeatherApiResponse` to `HourlyData` and `DailyData`, parse via `System.Text.Json`, and map weather codes to labels or icons with a static dictionary.

How do I handle units and time zones (°C/°F, mph/kph, local dates and day names)?You can control units directly through Open Meteo query parameters by setting `temperature_unit` to **celsius** or ** fahrenheit** and `windspeed_unit` to ** kmh** or ** mph**, and by using `timezone=auto` to automatically return timestamps in the device or user’s local zone. In your app, format all numbers and dates using `CultureInfo.CurrentCulture`, and convert timestamps using `DateTimeOffset` so that day names such as ** Mon**, ** Tue**, or ** Thu** and local dates display correctly for the user’s locale.

How can tab headers be customized across platforms (state-based styles, icons, spacing, and alignment)?Use `HeaderItemTemplate` along with styles to control text appearance, icons, and spacing. Apply state-based visual changes such as selected and unselected states, and adjust header padding and margins to align content consistently across platforms.

How to customize the tab indicator in a .NET MAUI Tab View?You can customize the tab indicator in .NET MAUI Tab View using built-in properties by changing its placement such as **Top**, ** Bottom**, or ** Fill** using [IndicatorPlacement](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.TabView.SfTabView.html#Syncfusion_Maui_TabView_SfTabView_IndicatorPlacement)
, adjusting its color or gradient via [IndicatorBackground](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.TabView.SfTabView.html#Syncfusion_Maui_TabView_SfTabView_IndicatorBackground)
, controlling its width with [IndicatorWidthMode](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.TabView.SfTabView.html?tabs=tabid-1#Syncfusion_Maui_TabView_SfTabView_IndicatorWidthMode)
 using Fit or Stretch, and modifying its corner radius and thickness using [IndicatorCornerRadius](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.TabView.SfTabView.html#Syncfusion_Maui_TabView_SfTabView_IndicatorCornerRadius)
 and [IndicatorStrokeThickness](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.TabView.SfTabView.html#Syncfusion_Maui_TabView_SfTabView_IndicatorStrokeThickness)
.

How do I ensure responsive layouts on Android, iOS, Windows, and macOS?Use adaptive layouts such as **Grid**, ** FlexLayout**, or ** CollectionView** with virtualization, avoid fixed sizes, use scalable or vector assets, test window resizing and orientation, and verify touch target sizes and font scaling across devices.


## Build your own weather dashboard app

Thanks for reading! With Syncfusion [.NET MAUI Tab View](https://www.syncfusion.com/maui-controls/maui-tab-view)
, building a responsive weather dashboard becomes effortless. From initializing the interface and managing tab-based updates to fetching real-time forecasts and transforming raw data into a stunning, scrollable design, you now have everything you need to create an app that feels modern and alive.

This approach not only delivers accurate weather insights but also elevates the overall experience with smooth navigation and visually rich components.

Give it a try, download [Essential Studio for .NET MAUI](https://www.syncfusion.com/downloads/maui)
, and see how quickly you can turn this into a real app.

If you have any questions, you can also contact us through our [support forum](https://www.syncfusion.com/forums)
, [support portal](https://support.syncfusion.com/)
, or [feedback portal](https://www.syncfusion.com/feedback/)
. We are always happy to help you!

## Related Blogs



[Build an AI-Powered Rich Text Editor in .NET MAUI with AI AssistView](https://www.syncfusion.com/blogs/post/ai-assisted-rich-text-editor-dotnet-maui)



[Integrating Native Device Features in .NET MAUI with Built‑In APIs](https://www.syncfusion.com/blogs/post/use-native-device-features-dotnet-maui)



[.NET MAUI State Management: From ViewModels to App Stores](https://www.syncfusion.com/blogs/post/managing-state-in-dotnet-maui)



[Private: .NET MAUI ListView vs CollectionView: How Syncfusion ListView Performs Better](https://www.syncfusion.com/blogs/?p=235640)
