WinUIpad: Fonts, Dynamic Document Title Display, More ⭐

WinUIpad: Fonts, Dynamic Document Title Display, More

Last week, I discussed my new rewrite of .NETpad as WinUIpad, using the Windows App SDK and WinUI 3. Since then, I’ve made two major additions to the code, which you can now find in the WinUIpad 2026 repository on GitHub: Font configuration now works properly, and I somehow managed to solve a months-long issue with a custom converter, so now the document filename displays properly too.

Fonts

The original version of the app I posted didn’t include working font code, so the font name (family), size, italicization, and weight (bold) features were stuck at the default values (Consolas, 18 point, no italics or bold).

Explaining how I fixed this is a bit difficult, but there’s enough font-related code that needs to run when the app starts that I create a Font_Configuration() method to segregate that from the rest of the code in LoadAppSettings(). Most of that was working fine already, but the correct font name (family) wasn’t displaying at all, so I fixed that.

And then I finally just created Selection_Changed event handlers for the Font family, Font style, and Font size combo-boxes in the settings interface and added code so that any changes the user made to each would impact the font used by the main app’s Textbox and then save the change to app settings. So that all seems to work properly now and font changes of whatever kind persist between app runs.

Dynamic document name display

This one I’m really excited about, as it had been a months-long source of frustration. As I wrote in .NETpad 2025: Running Up That Hill (Premium) back in August, I have been struggling to use data binding wherever possible in this project and finally discovered that one of the issues I’ve experienced is tied to an (at least) four-year-old bug in the Windows App SDK/WinUI 3 that Microsoft knows about and has never fixed.

Without getting into the weeds on this one, there are two ways you can implement data-binding in XAML with the Windows App SDK/WinUI 3: The x:Bind markup extension, which is the newer and more efficient way, and the Binding markup extension, which is the old-fashioned and less efficient way. Obviously, I assumed I’d be using x:Bind everywhere possible, and it usually does work fine. Except in this one case.

This app has a custom title bar, and the TextBlock control I’m using to display the document title at the top of the app window can be data-bound to the FileName property in my Document class so that it displays dynamically as the user opens new documents, saves an existing document, or creates a new, empty document. The problem is that it will display the entire file name, including its path and file extension by default. Like so:

To fix this, I create a custom converter that strips away the path and file extension. This is found in FileNameConverter.cs (in a new Converters folder, as I will be using a few other custom converters soon, too). There’s a lot that goes into this, but basically you just add the converter code to the XAML that handles the binding. So, instead of this code:

<TextBlock Text=”{x:Bind doc.FileName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}” />

You might use something like this:

<TextBlock Text=”{x:Bind doc.FileName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Converter={StaticResource FileNameConverter}}” />

More accurately, you might try to use something like that because it doesn’t work. And the problem, I found over much wasted time, isn’t the code I wrote, it’s that bug in the Windows App SDK that Microsoft never fixed.

I keep reworking all the code like a pit bull trying to get through a chain link fence, but I never did make it work. Microsoft’s advice—which I did try, to disastrous results—is to remove all the UI code in MainWindow.xaml (which is basically all the code in that file) and put it in a user control. But others claim you can get this working by using the old Binding markup extension instead of x:Bind. So I’ve tried that multiple times, too. But with the same results: No bueno.

Sunday, inexplicably, I made it work. I don’t want to unwind anything just in case, but I believe what put it over the top was assigning the data context of the TextBlock’s parent container (a grid called TitlebarGrid) to the instance of the Document object that I use while the app is running (imaginatively named doc), in the main window’s constructor. Like this:

// Set up document
TitlebarGrid.DataContext = doc;
doc.ResetDocument();

And then the pertinent bit in XAML looks like so:

<TextBlock Text=”{Binding FileName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Converter={StaticResource FileNameConverter}}” />

And freaking-A. It works.

Other changes

I made a few other small changes to WinUIpad over the past week:

  • I wrote the XAML code to display the Page Setup and Print menu items under the File menu, with the correct keyboard accelerators. But I haven’t (re)added the C# code for those features yet.
  • I wrote the XAML code to display the Zoom menu items under the View menu (Zoom > Zoom in, Zoom out, Restore default zoom), with the correct keyboard accelerators. But I haven’t (re)added the C# code to zoom the text yet.

More to do…

This means I still have the following to-do items left for the initial single document version of the app:

App exit. The File > Exit menu item isn’t implemented, and the code that runs when the app window closes is just the basics. There’s more to do here.

Go to. The Go to feature doesn’t work at all. I’m not sure if I had tried to make this work in WinUIpad yet, but it worked fine in .NETpad so I will figure that out.

Zoom. The code-behind zoom capabilities haven’t been added yet.

Status bar updates. The Position, Character/Word count, and Zoom level displays in the status bar haven’t been implemented yet, so they’re just static text for now.

Printing. The Page Setup and Print C# code is missing.

Status bar and Word wrap toggles. These work,  but there’s a lot of code redundancy that I will fix.

Spell check, Autocorrect. Neither of these settings is implemented yet.

You can download the latest version of the WinUIpad source code on GitHub.

More soon.

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