Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
164864 stories
·
33 followers

How inline C# in XAML works behind the scenes in .NET MAUI

1 Share

One of the more interesting additions to .NET MAUI 11 is the ability to write C# directly inside XAML files using the new x:Code directive.

I’ve previously written about C# expressions in XAML, which allow us to replace simple converters, calculated properties and some event handlers with inline expressions. The new x:Code directive takes this a little further, allowing us to define methods, fields and properties without needing to move into a separate code-behind file.

It’s an interesting addition to the XAML source generator, so let’s have a look at how it works, where it might be useful, and how the team has implemented it.

Getting started

First, we need to enable XAML source generation and preview features in our project file:

<PropertyGroup>
    <MauiXamlInflator>SourceGen</MauiXamlInflator>
    <EnablePreviewFeatures>true</EnablePreviewFeatures>
</PropertyGroup>

With that in place, we can use x:Code directly inside our XAML pages.

Example 1: A simple counter

Let’s start with a button that increments a counter whenever it’s clicked.

<ContentPage
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="MyApp.MainPage">

    <x:Code><![CDATA[
        private int _count;

        void OnCounterClicked(object sender, EventArgs e)
        {
            _count++;
            CounterLabel.Text = $"Clicked {_count} times";
        }
    ]]></x:Code>

    <VerticalStackLayout
        Padding="20"
        Spacing="12">

        <Label
            x:Name="CounterLabel"
            Text="Clicked 0 times" />

        <Button
            Text="Increment"
            Clicked="OnCounterClicked" />

    </VerticalStackLayout>
</ContentPage>

Nothing particularly complicated here. We’re declaring a private field and an event handler directly inside our XAML, then referencing the handler from the button.

Previously, we’d have placed these members in MainPage.xaml.cs. With x:Code, everything needed for this simple interaction lives in the same file.

Example 2: Handling CollectionView selection

For something a little more practical, let’s use x:Code to handle an item being selected from a CollectionView.

<ContentPage
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="MyApp.PropertiesPage">

    <x:Code><![CDATA[
        async void OnSelectionChanged(
            object sender,
            SelectionChangedEventArgs e)
        {
            if (e.CurrentSelection.FirstOrDefault()
                is not Property property)
                return;

            await Shell.Current.GoToAsync(
                $"property/{property.Id}");
        }
    ]]></x:Code>

    <CollectionView
        ItemsSource="{Binding Properties}"
        SelectionMode="Single"
        SelectionChanged="OnSelectionChanged">

        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="local:Property">
                <Label
                    Text="{Binding Name}"
                    Padding="12" />
            </DataTemplate>
        </CollectionView.ItemTemplate>

    </CollectionView>
</ContentPage>

This example assumes a Property model, a Properties binding and a registered Shell route. The usual namespace declaration for local is also required.

Here, the event handler belongs specifically to the page and performs a simple navigation action. Keeping it alongside the XAML makes it easier to see how the selection event is handled without switching between files.

For more complicated navigation or business logic, I’d still favour a ViewModel or separate C# implementation. The value here is having the option to keep small amounts of view-specific code close to where they’re used.

How does it work?

The implementation was introduced by Stéphane Delcroix in PR #34715, which adds a third pipeline to the XAML source generator.

Previously, the generator handled code-behind declarations and InitializeComponent generation. The new implementation adds a step between those two operations:

XAML
  |
  +-- CodeBehind generation
  |
  +-- x:Code generation
  |
  +-- InitializeComponent generation

This order is important. By generating the inline C# before InitializeComponent, the compiler can resolve methods referenced by XAML event handlers.

Looking at the source, two components are particularly relevant:

  • ComputeXCodeSource() extracts the inline code from the parsed XAML.
  • XCodeCodeWriter generates a separate C# partial class containing the extracted members.

The generator produces a file with a name following this pattern:

MainPage.xaml.xcode.cs

For our counter example, the generated code is conceptually equivalent to:

namespace MyApp
{
    partial class MainPage
    {
        private int _count;

        void OnCounterClicked(object sender, EventArgs e)
        {
            _count++;
            CounterLabel.Text = $"Clicked {_count} times";
        }
    }
}

This is a simplified representation of the generated output, rather than a verbatim extract.

Because the generated class is partial, its members are available alongside those in the usual code-behind file. We can even reference other methods and properties declared on the page.

There’s another nice implementation detail here. The generator automatically moves using directives out of the inline block and places them at the top of the generated C# file, removing duplicates along the way.

That means the following is also valid:

<x:Code><![CDATA[
    using System.Diagnostics;

    private int _clickCount;

    void OnButtonClicked(object sender, EventArgs e)
    {
        _clickCount++;
        Debug.WriteLine($"Clicked {_clickCount} times");
    }
]]></x:Code>

The source generator takes care of arranging the code into a valid C# file, while the normal C# compiler remains responsible for checking the method bodies.

What about the visual tree?

One detail I particularly like is that x:Code doesn’t become part of the visual tree.

The implementation explicitly excludes these elements from the visitors responsible for generating controls, setting properties and registering names. The directive exists purely for code generation, so there’s no additional runtime control or corresponding visual element.

There are a few restrictions. The directive must be a direct child of the root XAML element, and the root must declare x:Class.

The team has also introduced diagnostics for incorrect usage, including MAUIX2015 when the directive isn’t a direct child of the root and MAUIX2016 when x:Class is missing.

Should we use it?

I can see this being useful for small, view-specific event handlers and helper methods. Keeping a few lines of presentation logic alongside the XAML they belong to could make a page easier to understand, particularly when prototyping or building relatively simple views.

That doesn’t mean we should start moving large amounts of code-behind into XAML. For anything more complicated, a separate C# file is probably still easier to read, maintain and test.

For me, the more interesting story is what’s happening underneath. The team continues to expand what the XAML source generator can do, moving more work into the build process while giving developers additional ways to structure their applications.

It’s worth experimenting with, particularly alongside the new C# expressions feature. Just remember that both are still preview features in .NET 11.

References and further reading

Read the whole story
alvinashcraft
6 hours ago
reply
Pennsylvania, USA
Share this story
Delete

Testing your MAUI code on real devices comes to .NET 11

1 Share

Testing .NET MAUI applications has always presented a few challenges, particularly when the code you’re testing depends on platform-specific functionality. Traditional unit tests are great for testing business logic, but what happens when you need to test something that interacts directly with Android or iOS?

With .NET 11, the team has introduced native device test projects, bringing the familiar dotnet test workflow to Android, iOS, macOS, Mac Catalyst and tvOS.

This is a useful addition for MAUI developers, allowing tests to run inside a native application process on a physical device or emulator, rather than relying entirely on mocks or desktop-based tests.

Let’s take a closer look.

Getting started

.NET 11 RC1 introduces five new project templates, each configured to use MSTest and Microsoft.Testing.Platform.

Template Platform
androidtest Android
iostest iOS
tvostest tvOS
macostest macOS
maccatalysttest Mac Catalyst

Creating an Android test project is straightforward. With the .NET 11 SDK and Android workload installed, run:

dotnet new androidtest -n MyAndroidTests
cd MyAndroidTests
dotnet test

With an Android emulator running or a compatible physical device connected, the tooling builds and installs the test application before executing the tests on the device.

You can write tests using the familiar MSTest attributes, just as you would in a conventional .NET test project.

For example, let’s check whether Android’s connectivity service is available:

using Android.App;
using Android.Content;
using Android.Net;
using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class ConnectivityTests
{
    [TestMethod]
    public void ConnectivityService_IsAvailable()
    {
        var context = Application.Context;

        var connectivity = context.GetSystemService(
            Context.ConnectivityService);

        Assert.IsInstanceOfType<ConnectivityManager>(
            connectivity);
    }
}

Unlike a conventional unit test running on your development machine, this test executes inside an Android application process and interacts directly with the platform’s APIs.

It’s a simple example, but the same approach can be used to test platform integrations that are difficult to exercise in an ordinary .NET test project.

A look behind the scenes

One of the interesting parts of this feature is how the team has integrated device testing into the existing .NET tooling.

If we look at dotnet/android PR #11130, we can see the introduction of AndroidTestAdapter, which connects Android’s instrumentation system with Microsoft.Testing.Platform.

Android already provides a mechanism for executing tests through its instrumentation framework. For example, the following command executes instrumentation on a connected device:

adb shell am instrument -w <package>/<runner>

The new adapter builds on this existing functionality. When you run dotnet test, the tooling launches Android instrumentation, retrieves the generated TRX results file and reports the results through Microsoft.Testing.Platform.

This means developers can use the same dotnet test command they’re already familiar with, without needing to manually manage the Android instrumentation process.

The implementation also integrates with the .NET SDK’s device discovery capabilities. If multiple devices are available, you can select a particular device using the --device option, or list available devices with --list-devices.

Where does this fit with MAUI testing?

It’s worth distinguishing native device tests from UI automation.

Tools such as Appium and the MAUI testing ecosystem remain important for testing complete user journeys, including navigation, button interactions and validating what’s displayed on screen.

Native device test projects solve a different problem. They allow developers to run tests against platform functionality inside a real Android or Apple application process, without requiring a complete UI automation framework.

For MAUI applications that use native APIs, this opens up some useful possibilities. Platform-specific services, permissions, device capabilities and native integrations are all potential candidates, provided the tests account for the device configuration and permissions they require.

It also means there’s a clearer path towards including these tests in automated build pipelines, although your build environment will still need access to suitable devices or emulators.

Final thoughts

This is another of those .NET 11 improvements that could easily be overlooked among the more visible MAUI features.

Bringing native device testing into dotnet test removes some of the additional tooling and configuration previously required to execute tests on mobile platforms. More importantly, it makes testing platform-specific functionality feel like a natural extension of the existing .NET development workflow.

I’m particularly interested in how this could help test native integrations in larger MAUI applications, where relying entirely on mocks doesn’t always give you confidence that the platform implementation behaves as expected.

References and further reading

Read the whole story
alvinashcraft
6 hours ago
reply
Pennsylvania, USA
Share this story
Delete

Success for Scrum Masters Is the Team's Life After You Leave | Rajveer Prasad

1 Share

Rajveer Prasad: Success for Scrum Masters Is the Team's Life After You Leave

Read the full Show Notes and search through the world's largest audio library on Agile and Scrum directly on the Scrum Master Toolbox Podcast website: http://bit.ly/SMTP_ShowNotes.

 

"If you have not helped your team move from point A to point B positively, you are just doing part of the job." - Rajveer Prasad

 

Rajveer defines success for Scrum Masters through the change they leave behind in the lives of the people they serve. Delivery outcomes matter, and he names lead time as a useful end-to-end metric, but he warns that numbers alone miss the deeper work. For Rajveer, success shows up in relationship signals: whether people want to have lunch with you, whether they trust you enough to help in a rare crunch without being forced, and whether they still call you after you leave the organization. Those signals matter because Scrum Masters often come from outside the technical team and must earn a place in the system. The job is to help people move from point A to point B, not only in output, but also in work-life balance, skills, confidence, and the quality of collaboration across the whole team, including the Product Owner.

 

Self-reflection Question: If you left your team next month, what evidence would show that their day-to-day life improved because you were there?

Featured Retrospective Format for the Week: Sailboat Retrospective

Rajveer's preferred retrospective is the Sailboat format because it helps teams move beyond sprint details and talk about the system they operate in. He uses it to explore what is pushing the team forward, what is anchoring them, where the risks are, and how the team feels. For Rajveer, the format works because it "conditions you for a conversation" and creates space to discuss patterns, behaviors, and ways of working instead of only reviewing tasks.

 

[The Scrum Master Toolbox Podcast Recommends]

🔥In the ruthless world of fintech, success isn't just about innovation—it's about coaching!🔥

Angela thought she was just there to coach a team. But now, she's caught in the middle of a corporate espionage drama that could make or break the future of digital banking. Can she help the team regain their mojo and outwit their rivals, or will the competition crush their ambitions? As alliances shift and the pressure builds, one thing becomes clear: this isn't just about the product—it's about the people.

 

🚨 Will Angela's coaching be enough? Find out in Shift: From Product to People—the gripping story of high-stakes innovation and corporate intrigue.

 

Buy Now on Amazon

 

[The Scrum Master Toolbox Podcast Recommends]

 

About Rajveer Prasad

 

Our guest today is Rajveer Prasad, founder of OAKKTREEUNII. He's spent years helping aspiring and working project managers and Scrum Masters break into IT delivery — and grow once they're there — through real projects, real interview prep, and real accountability. He's mentored hundreds through career changes most people call impossible. Welcome, Rajveer

 

You can link with Rajveer Prasad on LinkedIn.





Download audio: https://traffic.libsyn.com/secure/scrummastertoolbox/20261112_Rajveer_Prasad_Thu.mp3?dest-id=246429
Read the whole story
alvinashcraft
6 hours ago
reply
Pennsylvania, USA
Share this story
Delete

Announcing Dart 3.14

1 Share
Bringing the Dart workflow full circle with automated SDK migrations, faster WebAssembly, and a re-engineered DartPad.
Read the whole story
alvinashcraft
6 hours ago
reply
Pennsylvania, USA
Share this story
Delete

Sunken SS United States Set To Become World's Largest Artificial Reef

1 Share
An anonymous reader quotes a report from PBS: The historic ocean liner SS United States will be intentionally sunk Wednesday off the coast of the Florida panhandle. Live coverage of the sinking of the SS United States is expected to start at 1 p.m. EST, with the sinking expected at 2 p.m. EST. Watch live in the video player above. In its heyday, the SS United States crushed the trans-Atlantic speed record, which it still holds. The luxury ocean liner took only three days to cross from New York to Europe on its maiden voyage in 1952. Carrying presidents and Hollywood stars, the nearly 1,000-foot vessel was a technical marvel of its time. However, the rise of air travel and high operating costs sunk its economic viability, and the ship was pulled from service in 1969. The ocean liner sat at Philadelphia's Pier 82 for nearly 30 years. After a contentious back and forth with a pier landlord over rent and docking fees, Okaloosa County in Florida eventually stepped in to purchase the ship and bring it to the Gulf of Mexico to become the world's largest artificial reef. The multi-million dollar project is also aimed at creating an economic development opportunity as a major diving attraction. "It was our goal to make sure that she wasn't lost forever," said David Lawrence, a member of the board for the SS United States Conservancy, the group that sold the vessel to the Florida county. Like the ship's unconventional life, it will also have an unconventional sinking. Federal environmental and explosives rules prevent the county from using explosives. Instead, tanks inside the ship have been removed and large holes were cut into the decks. Once the valves are opened, water will flood the hull, sinking the ship. Resting at 180 feet below the surface of the water, the SS United States will join more than 500 artificial reefs in Okaloosa County, which the county relies on to support the underwater ecosystem.

Read more of this story at Slashdot.

Read the whole story
alvinashcraft
6 hours ago
reply
Pennsylvania, USA
Share this story
Delete

Why English loves animals, from the bee’s knees to herding cats, with Jeremy Butterfield

1 Share

1237. This week, we talk to Jeremy Butterfield, former editor in chief at Collins Dictionaries and author of “The Metaphor Zoo,” about why English loves animals. We look at how conceptual metaphors like “human is animal” shape what we say, why “the bee’s knees” had so many ridiculous cousins in the 1920s, and how “herding cats” is much newer than you’d expect. Then we look at the Order of the Pug, how Hush Puppies got their name, and the animal eggcorns that sneak into idioms.


Find Jeremy at jeremybutterfield.com.


A hearty thank you to the Keepers of the Commas one mysterious Immortal on Patreon. We appreciate your support!

  • Larry Rosenblum
  • Mahala Russell
  • George Wilson
  • Laurel Paul
  • Linda Cox
  • Birna Anna BjörnsdĂłttir
  • Kate Wade


đź”— Share your familect recording in Speakpipe or by leaving a voicemail at 833-214-GIRL (833-214-4475)

đź”— Watch my LinkedIn Learning writing courses.

đź”— Subscribe to the newsletter.

đź”— Find an edited transcript.

đź”— Get Grammar Girl books.


| HOST: Mignon Fogarty

| Grammar Girl is part of the Quick and Dirty Tips podcast network.

  • Audio Engineer: Dan Feierabend
  • Director of Podcast: Holly Hutchings
  • Advertising Operations Specialist: Morgan Christianson
  • Marketing and Video: Nat Hoopes, Rebekah Sebastian
  • Podcast Associate: Maram Elnagheeb

| Theme music by Catherine Rannus.

| Grammar Girl Social Media: YouTube. TikTok. Facebook. Threads. Instagram. LinkedIn. Mastodon. Bluesky.


Hosted on Acast. See acast.com/privacy for more information.





Download audio: https://sphinx.acast.com/p/open/s/69c1476c007cdcf83fc0964b/e/6aece46b5e56bd617c82b779/media.mp3
Read the whole story
alvinashcraft
6 hours ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories