Telerik blogs

Following these five UX tips as a .NET MAUI developer can help keep your app user-friendly and polished.

Creating a pleasant app experience doesn’t always depend on having the most complex designs, the most harmonious colors, or the best user experience (UX). Obviously, all of this carries a lot of weight, but many times that whole system can be overshadowed by the lack of small details that can make a big difference between an average app and one that feels fast and familiar for your user.

As developers, we make UI decisions every day while writing code, and this can happen without us fully realizing it.

The day-to-day work of a developer involves making important decisions to build great applications. In this article, we’ll focus a bit on the UI side. While we usually have design teams that decide what the app’s colors will be, where and how buttons will be placed, developers also have the responsibility of making the right technical decisions so that the required design is implemented following best practices.

The best practics span from making decisions like which screen layout to use, whether to use an icon or an image, how to display certain information on screen, to complying with accessibility rules. UI decisions are not made only for aesthetics; they are made based on the reason behind each element we use, since they can directly impact performance and the overall experience, not just the visual aspect.

Even going a bit further, it’s also valid for developers to add design suggestions that design teams might not think about, such as using a Lottie instead of a heavier file (besides impacting visuals, it also impacts performance), supporting dark mode, among others.

In this article, I’ll share five design-impacting recommendations for .NET MAUI development that can help your users love using your apps.

1. Avoid Nested Layouts As Much As Possible

It’s important to understand the potential of each layout before you start building a UI. This is because, in most cases, you can achieve exactly the same visual result using different types of layouts.

For example, the same design can be built using combinations of HorizontalStackLayout and VerticalStackLayout as by using a single grid. Visually the result may be the same, but the impact on performance is probably quite different.

Each additional layout involves more measurement and layout calculations on screen, and that, accumulated over time, ends up impacting the overall fluidity of the application.

To make this easier to understand, let’s look at it this way: if you need to go to a place that is 10 km away, you have three options:

  • Go by private vehicle
  • Go by public transportation
  • Go on foot

All three options will allow you to reach the same destination, but not in the same way. If you walk, it will take much longer and you will arrive tired. If you use public transportation, you will spend extra time waiting and moving between stops. While if you go by private vehicle, you will arrive faster and more efficiently.

The same thing happens with layouts in an application. You can achieve the same visual result using different layout combinations, but not all of them are equally efficient. Using nested unnecessarily layouts generates more layout calculations, directly affecting performance.

One recommendation I always give is to review Grid. This layout allows you to create complex designs using a single layout, reducing the number of layouts and, therefore, the processing load.

There are also scenarios where StackLayout is completely valid. In those cases, make sure to use the one that matches your orientation—VerticalStackLayout or HorizontalStackLayout—and avoid nesting them without a clear reason.

For example, if we want to achieve a three-column, three-row layout, an example of doing it with StackLayout would be as follows:

<VerticalStackLayout Padding="16" Spacing="8"> 
    <HorizontalStackLayout Spacing="8"> 
	    <BoxView Color="Red" HeightRequest="40" WidthRequest="40" /> 
	    <BoxView Color="Green" HeightRequest="40" WidthRequest="40" /> 
	    <BoxView Color="Blue" HeightRequest="40" WidthRequest="40" /> 
    </HorizontalStackLayout>
     
    <HorizontalStackLayout Spacing="8"> 
	    <BoxView Color="Orange" HeightRequest="40" WidthRequest="40" /> 
	    <BoxView Color="Purple" HeightRequest="40" WidthRequest="40" /> 
	    <BoxView Color="Pink" HeightRequest="40" WidthRequest="40" /> 
    </HorizontalStackLayout>
      
    <HorizontalStackLayout Spacing="8"> 
	    <BoxView Color="Gray" HeightRequest="40" WidthRequest="40" /> 
	    <BoxView Color="Brown" HeightRequest="40" WidthRequest="40" /> 
	    <BoxView Color="Black" HeightRequest="40" WidthRequest="40" /> 
    </HorizontalStackLayout> 
</VerticalStackLayout>

But if we use a Grid, it would look like this:

<Grid 
    RowDefinitions="Auto,Auto,Auto" 
    ColumnDefinitions="*,*,*" 
    Padding="16" 
    RowSpacing="8" 
    ColumnSpacing="8">
 
    <!-- Row 1 --> 
    <BoxView Grid.Row="0" Grid.Column="0" Color="Red" HeightRequest="40" /> 
    <BoxView Grid.Row="0" Grid.Column="1" Color="Green" HeightRequest="40" /> 
    <BoxView Grid.Row="0" Grid.Column="2" Color="Blue" HeightRequest="40" />
    
    <!-- Row 2 --> 
    <BoxView Grid.Row="1" Grid.Column="0" Color="Orange" HeightRequest="40" /> 
    <BoxView Grid.Row="1" Grid.Column="1" Color="Purple" HeightRequest="40" /> 
    <BoxView Grid.Row="1" Grid.Column="2" Color="Pink" HeightRequest="40" />
    
    <!-- Row 3 --> 
    <BoxView Grid.Row="2" Grid.Column="0" Color="Gray" HeightRequest="40" /> 
    <BoxView Grid.Row="2" Grid.Column="1" Color="Brown" HeightRequest="40" /> 
    <BoxView Grid.Row="2" Grid.Column="2" Color="Black" HeightRequest="40" />

</Grid>

2. Add Accessibility to Your Apps

Sometimes we forget about what we don’t notice, but just because we don’t notice it doesn’t mean it isn’t important. Accessibility in apps allows us to adapt our applications for people with various impairments.

One quick win is to use SemanticProperties, which basically allow you to define text to be spoken out loud when a screen reader is employed. This way, if a person visually can’t read the text, they can listen to it and stay aware of what is happening in the app.

You can add SemanticProperties to all the visual elements you’re working with, as I show in the following example.

<Entry x:Name="lastName" SemanticProperties.Description="Last name"/>

For more information, I recommend reading the article “Creating Accessible Apps with Semantic Properties in .NET MAUI.”

3. Use Native Gradients Instead of Gradient Images

Gradients sample
Images obtained from the official documentation.

I’ve noticed that many times images are added just to simulate gradients. However, with .NET MAUI we can create our own gradients using Brushes, which allows us to avoid adding unnecessary resources that can be heavier than a definition in C# or XAML.

Using native gradients allows us to play more with colors and achieve the desired design, but they also offer great benefits such as:

  • Reducing the size of the application by avoiding additional images
  • Getting a more flexible UI
  • Gradients adapt better to different screen sizes; whereas images can look different on some devices, which forces us to maintain multiple versions of the same image
  • More flexibility when handling dark mode or light mode

Additionally, Brushes in .NET MAUI allow us to define linear, radial or solid gradients in a simple way, reuse them through resources and maintain greater visual consistency across the application, all with a lower performance impact compared to images.

Example in code:

<Border HeightRequest="120"> 
    <Border.Background> 
	    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> 
		    <GradientStop Color="#4FACFE" Offset="0.0" /> 
		    <GradientStop Color="#00F2FE" Offset="1.0" /> 
	    </LinearGradientBrush> 
    </Border.Background> 
</Border>

To dive deeper into this topic, I recommend reading the article “Getting Started With Brushes in .NET MAUI.”

4. Use Preferences Correctly

Basically, Preferences are used to store simple information on the device, allowing faster access. A very common example of using Preferences is when we select the “remember my email” option when logging into an app.

What happens is that, in some cases, Preferences may be used incorrectly. Let’s look at some common scenarios:

  • Storing information that should be in the database.
    My advice is to only store simple information in Preferences—data that you need at the moment and that helps you save time by avoiding unnecessary calls to an API or the database.

  • Storing sensitive information without protection.
    In some cases, we need to store data that could be sensitive; if this is your case, always remember to encrypt the information. This way, if someone manages to access the Preferences, they won’t be able to read the user’s data in plain text.

⚠️ Keep in mind that you should only store this type of information if it is absolutely necessary. Otherwise, it’s better not to do so.

Using Preferences is very simple. You just need the following:

A Set to store the information:

Preferences.Default.Set("user_name", "Leo");

A Get to retrieve it:

string userName = Preferences.Default.Get("user_name", "Unknown");

To dive deeper into this topic, I recommend reading the article “Exploring Preferences in .NET MAUI.”

5. Use FontImageSource Instead of Icons

Devs are always thinking about better performance, so here’s a tip. Instead of using .png icons, consider using icon fonts through FontImageSource. This allows you to continue displaying icons in your UI while keeping your app lighter, since these icons behave like text rather than images.

This brings many benefits to your application, including:

  • Font-based icons are much easier to customize. You can change their color, size and adapt them to light or dark mode without the need to create multiple versions of the same icon.
  • It allows you to have fewer resources in the app, reducing its size and making UI maintenance easier.

To use FontImageSource, you only need the icon code you want to work with, and you can implement it as follows:

<ImageButton> 
    <ImageButton.Source> 
	    <FontImageSource 
	    FontFamily="MaterialIcons" 
	    Glyph="&#xE87C;" 
	    Color="Black" 
	    Size="24" /> 
    </ImageButton.Source> 
</ImageButton>

The Glyph represents the icon that will be rendered. There are several portals where you can explore icons; as an example, you can use FontAwesome.

For example, you can go to https://fontawesome.com/search, select an icon and in the top-right corner you’ll see the Unicode that you can copy and paste directly into your project.

Conclusion

And that’s it! 🎉 In this article, we explored how UI decisions in .NET MAUI can make a big difference in performance and maintainability. Here are some key takeaways:

  • From choosing the right layout and avoiding unnecessary nesting, to using gradients, icon fonts, accessibility features and storing data correctly, each decision adds up.
  • Building a good UI is not only about how it looks, but also about how it’s implemented. Clean, thoughtful choices help your app feel faster, lighter and more polished—without adding unnecessary complexity.
  • Remember: users may not notice these decisions, but they definitely feel them. 💚

See you in the next article! 🙋‍♀️✨


LeomarisReyes
About the Author

Leomaris Reyes

Leomaris Reyes is a software engineer from the Dominican Republic specializing in mobile development. She is a 7-time Microsoft MVP and actively builds mobile applications while sharing practical knowledge through technical articles and developer-focused content.

Through her work, she explains programming concepts, developer tools and real-world development practices to help developers grow in their careers.

You can follow her on Instagram and TikTok at @leomarisreyes.dev, read her articles on AskXammy, and connect with her on LinkedIn, where she shares tutorials, insights and resources for developers.

Comments

Comments are disabled in preview mode.