100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Your First MAUI App

A hands-on walkthrough of scaffolding, running, and modifying your first .NET MAUI app, including event wiring, navigation, and Hot Reload debugging.

FoundationsBeginner8 min readJul 10, 2026
Analogies

Your First MAUI App

The fastest way to build a first MAUI app is dotnet new maui -n HelloMaui, which scaffolds the default 'click counter' template: a MainPage.xaml with a Label and a Button, and MainPage.xaml.cs with an OnCounterClicked handler that increments a private field and updates the Label's Text. Running it with dotnet build -t:Run -f net8.0-android (or pressing F5 in Visual Studio with an Android emulator or Windows Machine selected as the debug target) deploys and launches the app, giving you a working baseline to modify before writing anything custom.

🏏

Cricket analogy: Scaffolding with dotnet new maui is like a net session where the coach sets up stumps and a bowling machine before you've even picked up a bat, giving you a working baseline (the click-counter template) to start practicing from immediately.

Wiring Up Events and Modifying the UI

The default template's OnCounterClicked event handler shows the fundamental pattern used throughout MAUI: a XAML control's Clicked (or Tapped, TextChanged, etc.) attribute references a method in the code-behind by name, and that method runs on the UI thread where it can safely mutate control properties directly (CounterBtn.Text = $"Clicked {count} times"). Extending this into something more useful — say, adding an Entry for user input and a second Button that navigates to a details page — means adding controls to the XAML, wiring their events or bindings, and, once the app grows beyond a page or two, registering additional routes in AppShell.xaml so Shell.Current.GoToAsync("details") can navigate between pages.

🏏

Cricket analogy: Wiring Clicked="OnCounterClicked" to a method is like a fielding call ('mine!') triggering a specific pre-drilled response from a fielder, where the XAML attribute names exactly which code-behind method fires when the button is pressed.

csharp
// MainPage.xaml.cs
public partial class MainPage : ContentPage
{
    int count = 0;

    public MainPage()
    {
        InitializeComponent();
    }

    private void OnCounterClicked(object sender, EventArgs e)
    {
        count++;
        CounterBtn.Text = count == 1
            ? "Clicked 1 time"
            : $"Clicked {count} times";

        SemanticScreenReader.Announce(CounterBtn.Text);
    }

    private async void OnGoToDetailsClicked(object sender, EventArgs e)
    {
        await Shell.Current.GoToAsync($"details?count={count}");
    }
}

Debugging and Hot Reload

MAUI supports XAML Hot Reload, which pushes XAML markup changes to a running app instance without a full rebuild — useful for adjusting layout, spacing, or colors while the app stays running on the emulator or device — though changes to code-behind C# logic still require a rebuild since Hot Reload only applies to XAML. Setting breakpoints in code-behind or ViewModel code works exactly like any .NET debugging session (step-over, watch windows, the Immediate window), and the Output/Debug window's platform-specific logs (logcat filtering for Android, the Xcode-equivalent device log for iOS) are essential when a native crash occurs outside managed code that the .NET debugger alone can't explain.

🏏

Cricket analogy: XAML Hot Reload updating layout live is like adjusting a fielding position mid-over without stopping play, while a code-behind change needing a rebuild is like a bowling action change that requires leaving the field to be re-certified first.

Press Ctrl+Shift+Alt+Enter (Windows) or Cmd+Alt+Enter (Mac) in Visual Studio while debugging to force an immediate XAML Hot Reload apply if a change doesn't trigger automatically.

Hot Reload cannot apply structural changes like adding a brand-new named control that code-behind references (x:Name="NewButton" used in a new event handler) — those require a full rebuild, since the generated .g.cs partial class fields are only regenerated at build time.

  • dotnet new maui -n <ProjectName> scaffolds a runnable click-counter starter app with a Label and Button.
  • dotnet build -t:Run -f net8.0-android (or F5 in Visual Studio) builds, deploys, and launches the app on an emulator or device.
  • XAML's Clicked attribute wires a control's event directly to a named method in the paired code-behind class.
  • Growing beyond one page means adding routes in AppShell.xaml and using Shell.Current.GoToAsync to navigate.
  • XAML Hot Reload applies markup changes to a running app instantly but does not apply C# code-behind logic changes.
  • Adding a new named control that code-behind references requires a full rebuild, not just Hot Reload.
  • Platform-specific device logs (Android logcat, iOS device console) are essential for diagnosing native crashes the .NET debugger can't explain.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#NETMAUIStudyNotes#YourFirstMAUIApp#MAUI#App#Wiring#Events#StudyNotes#SkillVeris#ExamPrep