Telerik blogs

.NET MAUI reaches desktop elegantly and has features to support modern desktop app needs.

Let’s grab a definition from the books—.NET MAUI framework is designed for building modern, multi-platform, natively compiled iOS, Android, macOS and Windows apps, using C# and XAML in a single codebase. So, .NET MAUI allows developers to have a single codebase to power native mobile and desktop apps—essentially, the next generation of .NET cross-platform strategy.

However, .NET MAUI started as the evolution of Xamarin.Forms with a very mobile-first mindset. Can developers truly build modern desktop apps for Windows or macOS using .NET MAUI? While the shared codebase is nice, desktop apps often have to support heavy usage and demand very different user experiences. Can enterprises look at .NET MAUI to modernize their existing technology stack and move apps forward? While early days, .NET MAUI reaches desktop elegantly and has quite a few things to enable desktop workflows. Let’s take a look at some desktop-friendly .NET MAUI features and what lies ahead.

Reaching Desktop

Growing up from Xamarin.Forms, .NET MAUI allows reaching iOS and Android from shared .NET code—performance and tooling improvements should make developers more productive. However, .NET MAUI now also reaches desktop—Windows and macOS to start with—and desktop is a first-class citizen now with framework support and tooling.

Multiple platforms available with .NET MAUI

.NET MAUI’s desktop reach is done elegantly—thankfully not reinventing the wheel with yet another set of desktop technologies. Instead, .NET MAUI uses two of the latest and well-established ways of reaching desktop—WinUI for Windows and Mac Catalyst for macOS. WinUI is the latest UI and UX stack for Windows and Mac Catalyst is Apple’s suggested way of bringing iOS/iPad apps to the macOS desktop—both safe bets for .NET MAUI.

Platform native apps have some common traits—native UI, native platform API access and native performance. .NET MAUI checks all the boxes for native desktop apps on Windows and macOS.

Supporting Desktop

While .NET MAUI stands on the right pillars to reach desktop, there needs to be explicit work done inside the platform to enable desktop workflows. Desktop users have a unique set of demands—long-running apps, windowing support, mouse/keyboard shortcuts, complex UI and much more. Also, even though .NET MAUI reaches mobile and desktop from a single codebase, there are vast differences in form factors—developers need to cater to varying UX across devices.

There has been quite a bit of engineering work put into .NET MAUI to support desktop apps better—platform features that enable specific desktop needs. Let’s take a quick look.

Menu Bar

Menu bars are ubiquitous in many desktop apps across Windows or macOS—essentially, a container that presents a set of hierarchial navigational menus in rows at the top of a desktop app. Menu bars can be added to any ContentPage in .NET MAUI hosted in a NavigationPage or a Shell app—MenuBarItem, MenuFlyoutItem and MenuFlyoutSubItem provide hierarchy options. With bindable properties, menu bars can be dynamic and provide an easy way of content organization/navigation in .NET MAUI desktop apps.

Here’s how to quickly add a menu bar:

<ContentPage.MenuBarItems>

    <MenuBarItem Text="Locations">
        <MenuFlyoutSubItem Text="Change Location">
            <MenuFlyoutItem Text="New York, USA"
                            Command="{Binding ChangeLocationCommand}"
                            CommandParameter="NewYork" />
            <MenuFlyoutItem Text="Berlin, Germany"
                            Command="{Binding ChangeLocationCommand}"
                            CommandParameter="Berlin" />
            <MenuFlyoutItem Text="Madrid, Spain"
                            Command="{Binding ChangeLocationCommand}"
                            CommandParameter="Madrid"/>
        </MenuFlyoutSubItem>
        <MenuFlyoutItem Text="Add Location"
                        Command="{Binding AddLocationCommand}" />
    </MenuBarItem>

</ContentPage.MenuBarItems>

And the resulting menu bar displayed at the top of Windows/macOS desktop app:

Menu bar shows locations expanding to options for change location or add location. Change location is expanded to reveal New York, Berlin, and Madrid

Window Management

With greater surface area on desktops or tablets, users often demand more productivity—multiple windows and views of the same app may need to be opened at the same time. Desktop app users often expect multiple window support to be advanced—windows could be docked or running all day on a separate monitor.

.NET MAUI has baked-in support for multi-window. Let’s start our .NET MAUI tutorial for window management with a base desktop app from default template:

Default .NET MAUI app

For iOS and macOS, multiple window/view support needs to be declared as a scene delegate permission setting in info.plist, like so:

<key>UIApplicationSceneManifest</key>
<dict>
    <key>UIApplicationSupportsMultipleScenes</key>
    <true/>
    <key>UISceneConfigurations</key>
    <dict>
        <key>UIWindowSceneSessionRoleApplication</key>
        <array>
            <dict>
                <key>UISceneConfigurationName</key>
                <string>__MAUI_DEFAULT_SCENE_CONFIGURATION__</string>
                <key>UISceneDelegateClassName</key>
                <string>SceneDelegate</string>
            </dict>
        </array>
    </dict>
</dict>

Next a SceneDelegate class needs to be created and registered, like so:

using Foundation;
namespace MauiDesktop;

[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}

[Register("SceneDelegate")]
public class SceneDelegate : MauiUISceneDelegate
{
}

Once configurations are in place, we can spin up a new window rather easily, like on the click of our counter button in default template:

private void OnCounterClicked(object sender, EventArgs e)
{
    count++;

    if (count == 1)
        CounterBtn.Text = $"Clicked {count} time";
    else
        CounterBtn.Text = $"Clicked {count} times";

    var secondWindow = new Window {Page = new MainPage{}};

    secondWindow.MinimumHeight = 800;
    secondWindow.MinimumWidth = 600;

    Application.Current.OpenWindow(secondWindow);
} 

Here’s a look at multiple windows with the same sample view in a .NET MAUI app running on macOS:

Mulitple windows of a .NET MAUI desktop app

Multi-window support in .NET MAUI has additional bells and whistles to provide developers with more control—latest API includes new properties and events:

  • X/Y position
  • Width/Height
  • Minimum Width/Height
  • Maximum Width/Height
  • SizeChanged

Navigation

Developers building busy desktop apps often need a way to organize and tuck away lots of content, and provide easy navigation to users. Flyouts and Tabs to the rescue here in .NET MAUI, and they are fully customizable. With or without the default Shell, Flyout menus are easy to render—here’s how:

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

    <Shell.ItemTemplate>
        <DataTemplate>
            <Grid ColumnDefinitions="0.2*,0.8*">
                <Image Source="{Binding FlyoutIcon}"
                    Margin="5"
                    HeightRequest="45" />
                <Label Grid.Column="1"
                    Text="{Binding Title}"
                    FontAttributes="Italic"
                    VerticalTextAlignment="Center" />
            </Grid>
        </DataTemplate>
    </Shell.ItemTemplate>

    <FlyoutItem Title="English" Icon="language.png">
        <ShellContent Title="Home"
                            ContentTemplate="{DataTemplate local:MainPage}"
                            Route="MainPage" />
    </FlyoutItem>
    <FlyoutItem Title="German" Icon="language.png"> 
        <ShellContent Title="Heim"
                            ContentTemplate="{DataTemplate local:MainPage}"
                            Route="MainPage" />
    </FlyoutItem>
    <FlyoutItem Title="Spanish" Icon="language.png">
        <ShellContent Title="Hogar"
                            ContentTemplate="{DataTemplate local:MainPage}"
                            Route="MainPage" />
    </FlyoutItem>

</Shell>

Here’s the Flyout menu showing up with classic burger UI on macOS desktop:

Menu in upper left shows English, German, Spanish

Users of big tablets running iOS/Android might have different UX expectations. Developers can recognize platforms and cater accordingly—here’s the same menu, now through a TabBar:

<TabBar>
    <Tab Title="English" Icon="language.png">
        <ShellContent Title="Home"
                            ContentTemplate="{DataTemplate local:MainPage}"
                            Route="MainPage" />
    </Tab>
    <Tab Title="German" Icon="language.png"> 
        <ShellContent Title="Heim"
                            ContentTemplate="{DataTemplate local:MainPage}"
                            Route="MainPage" />

    </Tab>
    <Tab Title="Spanish" Icon="language.png">
        <ShellContent Title="Hogar"
                            ContentTemplate="{DataTemplate local:MainPage}"
                            Route="MainPage" />

    </Tab>
</TabBar>

And running the app on iOS means the UX is more friendly to someone on a mobile OS, like so:

English, German, Spanish options are now across teh bottom

Tooltips

Desktop users are mostly interacting with apps through mouse/keyboard. While app UI can get busy, users expect a feature to take the guesswork out—hover over an item and see some informational tooltips. Tooltips are now easy with the latest .NET MAUI—developers can attach properties to just about any visual tree element, like so:

<Image
    Source="dotnet_bot.png"
    ToolTipProperties.Text="A11Y demands Alt Text you know .."
    SemanticProperties.Description="Cute dot net bot waving hi to you!"
    HeightRequest="200"
    HorizontalOptions="Center">
</Image> 

Users can hover and see whatever extra information makes the UX friendlier:

Tooltip by dotnet bot reads A11Y demands Alt Text you know ..

Context Menus

What’s a popular user action with a mouse? Yup, right-click—and desktop app users expect additional goodies as context menus. .NET MAUI has this covered with the ContextFlyout—attachable to any visual item, like so:

<Image
    Source="dotnet_bot.png"
    SemanticProperties.Description="Cute dot net bot waving hi to you!"
    HeightRequest="200"
    HorizontalOptions="Center">
        <FlyoutBase.ContextFlyout>
            <MenuFlyout>
                <MenuFlyoutItem Text="What do you want?"/>
                <MenuFlyoutItem Text="Really .. Right Clicking on Image?" />
                <MenuFlyoutSubItem Text="Seriously ..">
                    <MenuFlyoutItem Text="Can't download image .. already local"/>   
                </MenuFlyoutSubItem>
            </MenuFlyout>
        </FlyoutBase.ContextFlyout>
</Image> 

Context menus look exactly as you expect—a rather handy way to provide extra functionality for .NET MAUI desktop apps.

Context menu from right-clicking dotnet bot image has options what do you want, really right clicking on image, and Seriously, which is opened to can't download image.. already local

Maps

Desktop apps often use maps—geolocation-based apps power a plethora of enterprise workflows. Mapping solutions are now doable—.NET MAUI ships with a new full-featured Map control that integrates with native platform Maps on mobile/desktop.

Once developers bring in the Microsoft.Maui.Controls.Maps NuGet package, all kinds of functionalities can be lit up with Maps—dropping pins, drawing shapes, overlaying traffic, geocoding and more. Developers have to remember to use the extra extension method as the .NET MAUI app starts up, like so:

public static MauiApp CreateMauiApp()
{
    var builder = MauiApp.CreateBuilder();
    builder
        .UseMauiApp<App>()
        .UseMauiMaps()
        .ConfigureFonts(fonts =>
        {
            fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
        });
    return builder.Build();
}

Once ready, throwing Maps on screen is easy as pie—as is dropping pins or other custom functionality, like in this example:

// XAML View
<Grid>
    <Map x:Name="map"/>
</Grid>

// Code-Behind
protected override void OnNavigatedTo(NavigatedToEventArgs args)
{
    base.OnNavigatedTo(args);

    var hanaLoc = new Location(20.7557, -155.9880);

    MapSpan mapSpan = MapSpan.FromCenterAndRadius(hanaLoc, Distance.FromKilometers(50));
    map.MoveToRegion(mapSpan);
    map.Pins.Add(new Pin
    {
        Label = "Welcome to .NET MAUI!",
        Location = hanaLoc,
    });
}

The result is platform-driven pixel-perfect maps—let the geolocation solutions commence.

Map of Maui with a pin showing welcome to .NET MAUI!

App Modernization

.NET MAUI is being positioned as the next generation .NET cross-platform strategy—a single shared codebase powers native apps on mobile and desktop. There are built-in platform features to enable particular user experience when .NET MAUI apps run on Windows or macOS. And when running on desktop, .NET MAUI apps are also not sand-boxed—developers can step outside of the app process and build deep integrations with the host OS.

In fact, combined with the latest .NET runtimes in .NET 6 and .NET 7, .NET MAUI is part of the story for app migration and modernization. Enterprises with older desktop apps with technologies like WinForms or WPF are looking at .NET MAUI to move things forward—target desktop first, and then perhaps cater to mobile UX.

As technology stacks evolve, it is quite remarkable to see WinForms/WPF apps run seamlessly on modern .NET runtimes, as long as dependencies come along. If there are investments in web technologies, they’re also welcome on desktop now—thanks to Blazor Hybrid apps and a modern WebView component in .NET MAUI. A well-architected app is always easier to modernize—perhaps moving apps forward is best done in bite-sized pieces keeping ROI in mind.

.NET MAUI UI for Desktop

Let’s talk about the elephant in the room—enterprise-grade desktop apps need complex UI components. Any development platform can have all the robust building blocks for desktop apps, but rubber hits the road when developers start building complex busy yet performant UI that is expected of desktop apps. Telerik UI for .NET MAUI controls can help—a set of polished UI components for cross-platform mobile and desktop apps.

Desktop apps invariably need full-featured Grids—users expect loads of functionality like sorting, filtering, grouping, customizations, aggregate functions, localization and more. MAUI DataGrids take a lot of solid engineering to build right and developers should be able to drop one in with functionality built-in—the .NET MAUI DataGrid will do that.

Telerik UI for .NET MAUI Data Grid examples

Enterprise desktop apps often have dashboard-like features presenting data with rich visualizations. Need various types of Charts, Graphs or Gauges, with feature-richness and easily bindable to any data source? Telerik UI for .NET MAUI has got you covered.

Telerik UI for .NET MAUI chart examples

With .NET MAUI and Telerik UI for .NET MAUI, developers for the first time have Telerik UI that works seamlessly across mobile and desktop—this is not a light statement to make. The same UI components cater to different experiences on mobile and desktop form factors with solid engineering and pixel-perfect rendering—developers do not have to worry about platform differences.

Wrap Up

Congratulations—you made it to the end of long article making the case for desktop apps with .NET MAUI. Oh wait—did you just TL;DR and scrolled down here? Either way, here is the bottom line—.NET MAUI can power lots of desktop experience on Windows and macOS.

Is it early days and could tooling be better? Absolutely. But the promise is there for wonderful code sharing across mobile, desktop and web platforms. Modern .NET desktop apps are also mobile apps with varying UX—.NET MAUI is here to enable developers to take their apps places. Cheers.


SamBasu
About the Author

Sam Basu

Sam Basu is a technologist, author, speaker, Microsoft MVP, gadget-lover and Progress Developer Advocate for Telerik products. With a long developer background, he now spends much of his time advocating modern web/mobile/cloud development platforms on Microsoft/Telerik technology stacks. His spare times call for travel, fast cars, cricket and culinary adventures with the family. You can find him on the internet.

Related Posts

Comments

Comments are disabled in preview mode.