Skip to content
Home » Basics of .NET MAUI – Part 3 – Introduction to XAML

Basics of .NET MAUI – Part 3 – Introduction to XAML

Spread the love

In part 2 of this series we were discussing the structure of the default project that is created for us when we select the .NET MAUI App template. As you saw, part of the code is written in C#, part in XAML, which is an XML-like markup language used across several technologies such as .NET MAUI, WPF, UWP or Xamarin, to mention just the most important ones.

The source code for this article is available on Github.

You could create a project without XAML, with just C# code. The question is whether you should… Before we talk about the advantages and disadvantages of XAML, though, let’s create a new page in our Slugrace project which we will be using throughout this series to test new stuff. This page is not going to be included in the project eventually, but I think it will be pretty helpful on the way. A good name for this page would be TestPage. We’ll use the page to test new stuff before we implement it in the actual project. So, open the Slugrace project, right-click the project name in the Solution Explorer (Slugrace), select Add, then New Item… and in the window that opens select .NET MAUI (A), then .NET MAUI ContentPage (XAML) (B), enter the name of the page (C) and hit Add (D).

This will create two files in the root folder of the project, TestPage.xaml and its corresponding code-behind file, TestPage.xaml.cs. The XAML file should open in the editor automatically. It has some sample code that contains a Label element inside a VerticalStackLayout element. The Text property of the label is set to “Welcome to .NET MAUI!”. Change it to something along the lines of “Test Page” so that we know which page we’re on when it’s displayed. The full code of the TestPage.xaml file should look like so:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Slugrace.TestPage"
             Title="TestPage">
    <VerticalStackLayout>
        <Label 
            Text="Test Page"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />
    </VerticalStackLayout>
</ContentPage>

We also must tell the program to display this page when it’s executed instead of the MainPage. Let’s make the changes in the AppShell.xaml file inside the ShellContent element. The title of the page should be “Test”, the content template and route have to be changed accordingly:

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

Let’s test the app on Windows, so select Windows Machine on your Play button and hit the button. You should see the TestPage with the text and title displayed correctly:

Why Use XAML? 

So, why should you use XAML if you don’t have to? A big disadvantage that probably comes to your mind when you think about it is that if it’s new to you, there’s a certain learning curve. You already know C#, so why bother to learn anything new if it’s not absolutely necessary? By the way, the good news is that .NET MAUI is not the only technology that uses this markup language and if you learn it, you will be able to use it (with slight modifications) in WPF or the other technologies listed above. And besides, it’s not so difficult if you know any other markup language like XML or HTML. There are lots of similarities.

So, is XAML worth learning or not? Well, I think it definitely is. Here are some reasons:

– it facilitates division of concerns: you use XAML for the UI and C# for the logic,

– it makes the graphical structure of the page clearly reflected in code,

– it’s much easier and faster to create the UI of your app using a declarative markup language than C# code after you master the former,

– it makes the application easier to manage as it grows,

– it enables a UI designer to work independently of a logic developer.

We’re going to see the difference between UI written with XAML and the same UI written with C# in a minute. You will definitely see how much more concise the XAML code is, although it’s even more visible in more complex examples. However, before we do that, let’s talk about the elements (like the label) that we place in a XAML page. They are called views in XAML.

Views in XAML 

In XAML most of the elements inherit from the View class. So, the layouts are views and practically all the controls that we’ll be using in our project are views. I may use the terms ‘view’ and ‘layout/control’ interchangeably in this series. One of the most commonly used views is Label. Let’s talk about it first.

The Label View 

When we created our TestPage, a Label was added for us automatically. Let’s have a look at it again:

<Label 
    Text="Test Page"
    VerticalOptions="Center" 
    HorizontalOptions="Center" />

As you can see, it has an opening angled bracket (<) and a closing one (>). In this particular case it’s a self-closing tag, with a slash character preceding the closing bracket. We can use self-closing tags if there is no content that should go between the opening and closing tag. But even with no content, we still could use an opening and a closing tag. We can rewrite the code like so:

<Label 
    Text="Test Page"
    VerticalOptions="Center" 
    HorizontalOptions="Center">
</Label>

Either way will do in this case. But if there were some content, we would have to use the latter syntax. Let’s remove the Text attribute from the opening tag and use the same string as the content of the label:

<Label 
    VerticalOptions="Center" 
    HorizontalOptions="Center">Test Page
</Label>

Now the closing angled bracket is required. Naturally, you could put everything on one line and it would work the same:

<Label VerticalOptions="Center" HorizontalOptions="Center">Test Page</Label>

The general rule is that if a view has some content, the content goes between the opening and closing tags of the view. The content may be a simple string like here, but it may also be a more or less complex hierarchy of other views. Like for example here – the Label is the content of the VerticalStackLayout and the VerticalStackLayout is the content of the ContentPage. Views nested inside other views are also referred to as their children.

Before we proceed, let’s restore the original shape of the label with the Text attribute set inside the opening tag. As you can see, Text is not the only attribute here. Let’s have a look at the others.

Property Attributes 

Just as the elements (like Label or Button) represent class instances (we call it Object Element Syntax), so the attributes inside the opening tags of the elements are used to set the values of the properties of those instances. This is why we call them property attributes. It’ll become even clearer when you see the corresponding C# code. Let’s stay in the XAML file for while, though. There are three attributes on the Label instance right now. Let’s add some more. The order of the attributes doesn’t matter. Here’s the modified code:

<?xml version="1.0" encoding="utf-8" ?>
...
    <VerticalStackLayout>
        <Label 
            Text="Test Page"
            VerticalOptions="Center" 
            HorizontalOptions="Center" 
            TextColor="Red"
            FontSize="36"
            FontAttributes="Bold, Italic" 
            Rotation="45"
            CharacterSpacing="5"
            TranslationY="100" />
    </VerticalStackLayout>
...

The names of the attributes are self-explanatory. Now run the app again to see the result:

One interesting thing is the FontAttributes attribute. There are two values assigned to it. If you want to assign more than one value to an attribute (provided it’s at all possible), you separate them with a comma.

And there are more attributes that you can use with a Label (as well as with any other view). Use Intellisense to experiment if you like.

Now, before we proceed to the C# counterpart of the above XAML code, I’d like to draw your attention to a very useful feature available in Visual Studio that will make your life a whole lot easier.

Hot Reload 

The feature I’m talking about is Hot Reload. When you run the code, it should be activated, but if it isn’t, you can activate it manually. You will find it here:

With this feature activated and your app still running, try to make some changes in the code. Let’s change the values of some of the properties. Whenever you change a value, the change is immediately reflected in the running app. Here’s what I tried:

<?xml version="1.0" encoding="utf-8" ?>
...
    <VerticalStackLayout>
        <Label 
            Text="Test Page"
            VerticalOptions="Center" 
            HorizontalOptions="Center" 
            TextColor="Blue"
            FontSize="60"
            FontAttributes="Bold, Italic" 
            Rotation="180"
            CharacterSpacing="20"
            TranslationY="100" />
    </VerticalStackLayout>
...

And here’s the result after my last modification:

So, with Hot Reload on, you can view your changes live in the running app without having to stop and restart it every time.

XAML vs C# 

And now let’s finally see, what our code would look like if we decided to go with pure C#, no XAML at all. Here’s the XAML code that we’re going to rewrite in C#:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Slugrace.TestPage"
             Title="TestPage">
    <VerticalStackLayout>
        <Label 
            Text="Test Page"
            VerticalOptions="Center" 
            HorizontalOptions="Center" 
            TextColor="Blue"
            FontSize="60"
            FontAttributes="Bold, Italic" 
            Rotation="180"
            CharacterSpacing="20"
            TranslationY="100" />
    </VerticalStackLayout>
</ContentPage>

Let’s delete the TestPage completely. Right-click the XAML file, select Delete and confirm. This will delete both the XAML file and the code-behind. Then add a new TestPage like we did before, but this time select the .NET MAUI ContentPage (C#) template.

The file will open in the editor with some initial code already in it. Let’s modify the code to make it the C# counterpart of the XAML code that we had before:

namespace Slugrace;

public class TestPage : ContentPage
{
    public TestPage()
    {
	Content = new VerticalStackLayout
	{
	    Children = {
			 new Label 
				{
                          	    Text = "Test Page",
                    		    VerticalOptions = LayoutOptions.Center,
                    		    HorizontalOptions = LayoutOptions.Center,
                    		    TextColor = Colors.Blue,
                    		    FontSize = 60,
                    		    FontAttributes = FontAttributes.Bold | FontAttributes.Italic,
                    		    Rotation = 180,
                    		    CharacterSpacing = 20,
                    		    TranslationY = 100
                		}
            		}
	    };
    }
}

This code is more verbose than its XAML counterpart, although at this level of complexity the difference isn’t that obvious. But when our UI gets more complex, the XAML code will be much easier to read.

Look at how we set the values of the properties. We need to check their types in documentation. For example FontSize is a property of type double, so we don’t use quotation marks in C#. If we need to set multiple values, like with the FontAttributes enum, we use the pipe symbol (|) to separate them.

Anyway, if you now run the app, it’ll work as before.

After you’re done testing, remove the C# file and recreate the XAML version of the TestPage with its corresponding code-behind, just like we did in the first place (without the later modifications in the Label object except the Text attribute, which should be set to “Test Page”). Make sure everything works as expected. We’ll be using XAML in this series, but we’ll also compare the XAML code to its corresponding C# code quite frequently.

In this part of the series we focused on just one view, the Label. But there are more, as we’re going to see in the next part.


Spread the love

Leave a Reply