Where Windows App Development Goes to Die (Premium)

Back in 2019, I started the epic Programming Windows series which, years later, turned into the equally epic book Windows Everywhere. But about halfway through writing up the history chronologically, I ran into a wall: because I had never really participated in .NET development, I had a less than authoritative handle on that era of software development. And so I took a break from the series so that I could go back in time, virtually, and learn each of the Windows-focused .NET application development frameworks in turn. In doing so, I created a Notepad clone that I later renamed to .NETpad. And then I recreated this app repeatedly, using different frameworks, languages, and .NET versions. I documented the creation of three of these projects—Visual Basic/Windows Forms, C#/Windows Presentation Foundation, and C#/Universal Windows Platform—over a several-month period, and then later updated them for the modern .NET era so I could post them to GitHub, allowing others to clone the repositories, make their own improvements, and suggest changes to the apps. Some of which I later incorporated into them.

That’s all very interesting (to me), and I did of course later go back and finish the Programming Windows series. But I still have this one idea stuck in my craw from the time I was finishing up the first half of the series, and it’s related to Visual Basic (VB), an absolutely wonderful tool that many fans still believe Microsoft completely screwed up in the transition to .NET. And that idea is that it was absolutely astonishing how much of an application one could create using this tool without writing a single line of code. This was the true strength and magic of VB, that one could construct the user interface of an app entirely using visual tools and by assigning values to properties. And then you could tie it all together with what I still think of as “glue” code.

This is why my first .NETpad project utilized VB.NET and Windows Forms: this combination was the logical successor to VB 6, the last “classic” version of VB, and it seemed like the obvious way to get into .NET. And it was. And as I had hoped and mostly expected, it was likewise possible with Windows Forms to spend much of your time making UI visually and by assigning properties. It was very much like VB in that it was impressive how much you could get done before you needed to write any code.

But as I moved forward in time through newer .NET environments like Windows Presentation Foundation (WPF) and Universal Windows Platform (UWP), I experienced 10 to 15 years later what Microsoft stack developers already knew: everything changed. Microsoft adopted a declarative UI paradigm in which application user interfaces were created with XAML, an XML-based markup language, a more sophisticated approach that would let developers and designers work together on the same project, with each sticking to their subject area. There were visual designers for XAML, at least in the beginning, but these were separate tools and not integrated into Visual Studio. And then they disappeared entirely: modern environments like the Windows App SDK and .NET MAUI use versions of XAML for which there are no visual tools. You just have to write code, which more than sort of undercuts the stated advantage of moving to XAML in the first place.

I’m not a professional developer, but I lean more in that direction than I do toward design, and there is part of me that really likes the code-based XAML approach. But I also recognize how complex it’s always been and how that complexity has only multiplied as we’ve moved forward into the current era. Back in the WPF days, the big complexity was data binding, a feature that lets UI controls connect automatically to data and update in both directions in real time. But in UWP, the Windows App SDK, and .NET MAUI, the complexities have multiplied. And now they include things we used to just get for free in classic VB or in Windows Forms.

XAML is also quite verbose: as it turns out, describing a user interface takes a lot of words. This was something I saw again and again in my XAML-based projects, whether they were the WPF or UWP versions of .NETpad or the basic WordPad-based ribbon UI I built for Programming Windows: Hello, Ribbon and Jump Lists (Premium). It’s astonishing how much code you need to write to get anything done, and modern XAML-based environments are even worse. It’s getting really tedious.

Put another way, you need to write a lot of code—C# code and XAML code—to get anything done in a modern environment like the Windows App SDK. And I can’t figure out why that’s true. All I can do is demonstrate that it is true and then explain how I’ve decided that Microsoft has completely lost the script on native Windows app development. Where VB made everything easy back in the day, perhaps too easy, these modern environments make it too hard, much too hard. And when you add that to all the other reasons why no sane developer would ever create a new Windows-only app right now, the conclusion is inescapable: Windows application development isn’t just a dead-end today, it’s dead.

Let me provide some examples of why this is so.

In the good old days when VB classic or Windows Forms was current, life was simple. We didn’t have high-resolution displays, let alone high DPI displays, and using a visual editor to create user interfaces was straightforward. Over time, of course, PCs evolved and improved, and some of the changes we saw in later frameworks like WPF and UWP were aimed at addressing the new capabilities. WPF apps scale to high DPI displays better than Windows Forms apps, for example. And because they’re mobile apps, the life cycle of UWP apps can be automatically managed by Windows in ways that aren’t possible with WPF; they can go to sleep when not in use and take up fewer system resources.

But we also lost things. As you may recall from the WPF version of .NETpad, for example, WPF didn’t support the standard Font and Color dialogs that were oh-so-easy to use with Windows Forms, so I had to create own from scratch. UWP couldn’t initially display secondary windows, a basic feature of an operating system that is named after that very capability. And so on.

Flash forward to Windows 11 and we have modern UI concepts to deal with, and modern UI controls to implement. For example, Windows 11 supports the notion of materials, which are visual effects that can resemble real-life materials and be applied to application surfaces. There are two base materials: Mica, an opaque effect that is most often used on the base layer of an application window, and Acrylic, a frosted glass-like translucent material that is best used on flyouts and context menus that will appear over an opaque base layer.

OK, great. But applying a Mica or Acrylic material to a window or control should be as simple as assigning a value to a set of properties, and that’s true even when you account for the fact that Windows 11 supports light and dark app and system modes, accent colors, and other modern UI constructs. If I am creating a Windows App SDK-based app, using a material should be simple.

But it’s not.

This one is so astonishing you’re going to think I’m making it up. We should be able to write XAML code like the following to apply a material to a window:

<Window Material="Mica" />

And then perhaps some optional code around which color(s) to use in different conditions like Light and Dark mode, when the window is focused or not focused, and so on. This is how VB would have handled it.

But with the Windows App SDK, you need to write over 100 lines of C# code to do nothing more than apply the Mica material to the background of a window (it can be found under the heading “Example: Use Mica in a Windows AppSDK/WinUI 3 app”). And what you get, after all that work, is a plain window with an opaque fricking background. Are you kidding me?

Naturally, I’ve examined what it would look like to create a Windows App SDK version of .NETpad. Here, Microsoft has raised the bar by modernizing Notepad for Windows 11, first by giving it a modern Windows 11 look and feel—what I think of as a “WinUI” user interface—and then later by adding tabs. Leaving the complexity of tabs aside for the moment, what would it take to create that modern UI in the Windows App SDK?

Well, the first step involves customizing the title bar. Here, you have two choices: you can perform a simple customization in which you apply a non-standard color to the title bar, or you can opt for a full customization in which you hide the app’s title bar and then create your own custom title bar area in which you must draw and maintain any UI that you want there. This includes a system icon, the title text, and whatever other controls you need (like a search box), obviously, but you also have to specify one or more areas that can be grabbed and dragged via the mouse; otherwise, the user will have a very hard time moving that window.

Surely, a simple title bar customization in which you just specify a new color for the title bar is a single line of code, right? Something like:

titleBar.BackgroundColor = Colors.Green;

Almost. First, you actually have to write code that uses WinRT interop to get your application’s window handle, a concept from C-based Windows SDK programming. That looks a bit like so:

private readonly AppWindow myAppWindow;
myAppWindow = GetAppWindow();

private AppWindow GetAppWindow()
{
    IntPtr hWnd = WindowNative.GetWindowHandle(this);
    WindowId wndId = Win32Interop.GetWindowIdFromWindow(hWnd);
    return AppWindow.GetFromWindowId(wndId);
}

And then you have to write code that accounts for all of the title bar and window button states like so:

It’s a lot of code to just, I don’t know, make the title bar green. Something we could do in VB without writing any code.

But it gets worse when you want full customization, which is what I’d want for .NETpad. Now, we need to write lots and lots of XAML code to define that custom title bar. (And that’s before we think about using a material. I’m just faking it here with a hard-coded color.)

And what that gives us is … this. Not much.

And that’s just for a blank top area and three empty menus. As I build out that UI, the XAML code expands almost exponentially. Again, it’s quite verbose. And then there’s the C# code, because we still need to accommodate all the same title bar nonsense that we did above in the simple customization version. This is all before the app even does anything.

And then, of course, we need to put it all together. That is, we don’t just need a fully customized title bar. We also want to apply the Mica material to the app and have that bleed through into the title bar and menu, right? It just never ends.

And once we figure all that out, once we’ve written literally hundreds of lines of code all in the name of presenting what is, in the end, a fairly basic if modern-looking app that literally does nothing, well then, we need to actually write the app. Because all this stuff is just boilerplate so we can throw up something that looks reasonable here in 2023.

It is, in other words, what VB gave us for free.

Put another way, where I marveled at how little code one needed to write in VB, today I marvel instead at how much code one needs to write just to have a decent-looking app that does absolutely nothing. Windows App SDK is, in this way, the opposite of VB.

And from where I’m sitting, this is not progress. It’s a graveyard. The graveyard in which Microsoft buried modern Windows app development.

Gain unlimited access to Premium articles.

With technology shaping our everyday lives, how could we not dig deeper?

Thurrott Premium delivers an honest and thorough perspective about the technologies we use and rely on everyday. Discover deeper content as a Premium member.

Tagged with

Share post

Thurrott