Modernizing .NETpad: First Steps (Premium)

.NETpad WPF is modernized

I’ve taken the first steps in modernizing the WPF version of my .NETpad app, and I’m excited to say I’ve made some progress. That said, there’s lot more work to do. And it’s not clear how far I can go with this existing codebase before I run into issues I’m unable to resolve.

Indeed, I’ve been trying to reconcile what’s happening with WPF (Windows Foundation Presentation) since Microsoft’s announced its return to the spotlight at Build 2024 last month. Long story short, there are now two “native” Windows app platforms, WPF and the Windows App SDK. And while neither is literally native, they are both closer to the metal, so to speak than other Windows app frameworks like React Native, which is web-based, or .NET MAUI, which is a cross-platform mobile app platform.

But WPF and the Windows App SDK target different audiences, and they aren’t entirely equals in terms of functionality. Worse, each is in a weird place right now and documentation for new features and functionality is either non-existent or hard to find.

WPF is by far the older of the two, and Microsoft’s formal (re)embrace of it is an acknowledgement that WPF never went away despite multiple attempts (the Windows Runtime (WinRT), the Universal Windows Platform (UWP), etc.) to replace it. The audience here is developers of existing WPF apps, many of which have been out in the world, just chugging along for years and year, but looking more and more dated: Thanks to a community-driven effort, it’s become possible to modernize these existing apps so that they look more normal alongside other apps in Windows 11, in particular.

Windows App SDK is the logical endgame for Microsoft’s doomed WinRT and UWP platforms. It’s a desktop version of what used to be a set of mobile app platforms. Unlike its predecessors, it’s not tied to any specific Windows version: Windows App SDK apps will run and look normally on any supported version of Windows (10 or 11). Technically, WinAppSDK targets two audiences: Developers of existing WinRT/UWP mobile apps who wish to modernize those apps, and developers who wish to create new “native” Windows apps. That the second of those two audiences is so small that it’s essentially non-existent is, of course, obvious. But it’s there if you want that option.

And so too is WPF, of course. And that’s kind of an interesting problem. God help you if you wanted to create a new native Windows app for some reason, but you now have these two choices. Neither is perfect, though either would make a lot more sense than, say, using C++ and Win32 SDK like it was the 1990s again.

I may eventually look into creating a new Windows App SDK app, have indeed gone down this path in the past more than a few times. But the return of WPF into the spotlight means that I will first look at modernizing the WPF version of my .NETpad app, a Notepad clone that, today, is increasingly out-of-date because Microsoft has actually been busy updating Notepad in recent years for some reason. But that’s perfect: My app, like basically all WPF apps, is now nicely out-of-date and in need of modernization.

As you may recall, I moved my .NETpad projects to GitHub and 2020, and you can find the WPF version here. To get started on the modernization project, I installed the Visual Studio 2022 Preview and configured it with the .NET Desktop development workload required for WPF. I also installed the latest pre-release version of .NET 9 SDK (version 4 at the time of this writing).

With that completed, I signed in to Visual Studio and chose the “Clone a repository” option on the Visual Studio 2022 Get Started page and pasted the web URL of my .NETpad project into Visual Studio as prompted.

Once the project was fully loaded in Visual Studio, I opened its properties (by right-clicking the “NotepadWPF” project name in Solution Explorer and choosing “Properties”) to make a few changes.

As you can see, the target (.NET) framework is .NET 6.0, which was modern at the time but now out-of-date. And the target and supported OS versions are likewise out of date. So I changed “Target framework” to .NET 9.0, which is available because I had installed the pre-release version. And I changed the target and supported OS properties to “10.0.22621.0,” which is Windows 11 22H2, the most recent version available. (This will change later, but I’m working exclusively in Windows 11 and with pre-release code, so it’s not a concern for now.)

I saved that and started that app. And there it was, in all its legacy goodness, but running on .NET 9 Preview 4.

With a bit of testing, it seemed that everything was working correctly. So it was time for some basic modernization. This is where Microsoft’s lack of documentation hurts, but thanks to two Build 2022 session videos, Navigating Win32 App Development with WinUI and WPF and How to create superior experiences with WinUI and WPF, I found what I needed:

That code, which needs to be added to App.xaml, basically enables the modern, WinUI 3-based user interfaces in your WPF app. It looks like so:

And when I started the app with that addition, voila, .NETpad now looks like a modern Windows 11-style app with rounded corners everywhere. An app that correctly supports Windows 11’s dark and light system themes.

Even the menus are updated, which is nice.

If only it were this simple.

As it turns out, there are problems. Many problems. The status bar is too thick, though that seemed like something I could fix easily enough. The custom themes I had created because the app didn’t support system themes are all hosed now. There are custom dialog boxes that need to be updated and more.

But job one is the textbox at the heart of this application. It’s all messed up now, with rounded corners, a selection highlight color that no one wants, and a weird “Close” (“x”) button over on the right when you add text to it. Much work was needed here.

To isolate the issue, I started fresh with a more basic version of the app that eliminated most of the code.

And after failing to resolve the issues, I finally did what I always do and turned to the expert: Rafael, who quickly got things up to speed.

The status bar thickness issue was caused by a change to the default padding of this control in Windows 11 to 12 points. So I fixed that by setting that explicitly to 2.

<StatusBar Grid.Row=”2″ Name=”StatusBar1″ Padding=”2″>

The textbox issues were a bit more complex, but Rafael looked at the base style and provided me the following code to remove the rounded corners:

And that was a nice step forward.

That said, the selection accent remained, but was now the entire border. Which seemed like a familiar problem. So I brought in more of my XAML code from the original app to see if that would resolve that issue. So, the textbox XAML code now looked like so:

And sure enough, that did it.

That was a nice start. I made those same changes to the actual app, and it looks good: The app has that modern WinUI 3/Windows 11 look and feel, and the main text box and status bar look correct.

But again, there is still so much more to do. I have to fix the custom themes support now that it supports system themes. All the dialog boxes need to be reconsidered and modernized somehow. For example:

My custom Fonts dialog, which I was so proud of originally, looks particularly bad.

And then I would like to further emulate the modern Notepad, starting with that Settings gear in the tab bar and the new Settings sheet. If possible.

So I will start working on all that. With the understanding that much of this won’t be possible anytime soon, if ever. And that the documentation I need, not to mention the updates, will likewise come on whatever schedule or not at all.

We’ll see. For now, an interesting first step.

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