Skip to content
Home » Basics of .NET MAUI – Part 15 – Namespaces in XAML

Basics of .NET MAUI – Part 15 – Namespaces in XAML

Spread the love

In the previous part of the series we implemented the light and dark themes in our app. Before that, we styled the app. The next step is to start working with real data, because at this moment all the labels display hardcoded data. But before we dive into data and data binding, let’s briefly discuss another topic, namespaces in XAML. It’s a pretty straightforward topic, but let’s systematize our knowledge of namespaces before we move on.

The source code for this article is available on Github.

Default and Non-default Namespaces

You must have noticed that each page and each content view in XAML, and generally each root element, starts like this:

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

or this:

<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"...

The App.xaml file starts like this:

<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"...

And the Styles.xaml file in the Resources folder also starts in a similar way:

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">

Whatever the root element is, it always contains these two lines of code. At least these two, but there may be more. So, what are these lines of code actually for?

Well, these are namespace declarations. The first line defines the default namespace. All elements in the XAML file that are used without any prefix are instances of .NET MAUI classes. Here belong ContentPage, Label, Button, Slider, Grid, and many, many more. This namespace declaration enables us to use the elements in code like so:

<Grid>
<Label>
<ContentView>

and so on, so without any prefix. Any other namespaces are non-default namespaces and they do require a prefix. We use the prefix both in the namespace declaration and then inside the code. In the second line of each code fragment above you can see the x prefix. This particular namespace contains classes intrinsic to XAML, and specifically, to the 2009 XAML specification.

To reference items from this namespace in code, we must always use the x prefix. We’ve already used such objects and attributes in our app. Here are some examples:

<Color x:Key="mainButtonColor">#520000</Color>
<VisualState x:Name="Normal" />
<OnPlatform x:TypeArguments="Thickness">
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:Slugrace.Controls"
             x:Class="Slugrace.Views.RacePage" 
             Padding="5">

In the last example you can see that the argument is defined on the root element. This attribute specifies the namespace and class name for a class defined in XAML. In this particular case it tells us that the class’s name is RacePage and that it’s defined in the Views folder, which is inside the root Slugrace folder:

If you open the code-behind file you will see that the class name of the class defined there matches the one defined in XAML:

namespace Slugrace.Views;

public partial class RacePage : ContentPage
{
    ...
}

You can also see this exact same namespace defined in C#.

There also markup extensions that are used with the x prefix, like x:Static, x:Array or x:Type that we talked about before.

Namespaces for Types

To reference types in XAML you have to declare their namespaces with a prefix. The declaration must specify the Common Language Runtime (CLR) namespace name using the clr-namespace (or using) keyword inside the namespace declaration. If the types are in a different assembly, the assembly name must be delivered, too.

You can use any prefixes you like, but there are some conventions, like, for example, the local prefix. We don’t have it in our app, but we would declare it like so:

xmlns:local="clr-namespace:Slugrace"

By convention we use the local prefix to reference types local to the app, so types added directly to the root. When we created the .NET MAUI project, the MainPage.xaml file was added to the root. We could use the prefix to reference the MainPage like so:

local:MainPage

Another convention is that we often use the names of the folders as prefixes. This is not mandatory, but it’s pretty common. Let’s have a look at the AppShell.xaml file:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="Slugrace.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:views="clr-namespace:Slugrace.Views"
    Shell.FlyoutBehavior="Disabled">
    ...

We’re interested in the following line of code:

xmlns:views="clr-namespace:Slugrace.Views"

Here we use the views prefix to declare the namespace. It corresponds to the name of the folder it references.  Then, below, in the same file, we use the prefix to reference a type that we defined there, SettingsPage:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    ...
    ...
    <ShellContent
        Title=""
        ContentTemplate="{DataTemplate views:SettingsPage}"
        Route="SettingsPage" />
</Shell>

We also used another prefix, controls, to reference types defined in the Controls folder, like for example in the SettingsPage:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage ...
             xmlns:controls="clr-namespace:Slugrace.Controls"
             x:Class="Slugrace.Views.SettingsPage"> 
    ...
                    <VerticalStackLayout>
                        <controls:PlayerSettings />
                        <controls:PlayerSettings />
                        <controls:PlayerSettings />
                        <controls:PlayerSettings />
                    </VerticalStackLayout>
                </VerticalStackLayout>

We’re not using types from a different assembly in our app, but if we were, we would have to declare the namespace like this:

<ContentPage ... 
             xmlns:controls="clr-namespace:Controls;assembly=ExternalLibraryName" ...>

That’s all you need to know about namespaces in XAML, at least for now. We can finally make our app do something, not only look somehow. In order for an app to do something, it must consume data that we deliver to it. So, in the next part of the series we’ll be talking about data and data binding.


Spread the love

Leave a Reply