Modernizing .NETpad: Settings, UI Changes, Spell Check, and More (Premium)

.NETpad 2024

It’s been a whirlwind week of rapid improvements to .NETpad. The Settings page is in place, and everything that can work is working properly. I added a “Reset settings” button, similar to what I did for the UWP version of the app. I fixed the Auto save functionality (which was broken somehow). I added spell checking. And I updated the main menu layout to match what Microsoft did with Notepad in Windows 11 as closely as possible.

There’s so much more to do, but as I noted last time, this project is progressing quicker than I expected, and I’m able to get more done with WPF than I expected. There are some control differences—Microsoft is clearly using custom styling for the checkmarks in menu items for options that can be toggled on/off, for example, and WPF doesn’t (yet?) support the Windows 10/11 ToggleSwitch control—and of course the biggest missing feature, tabs, remains missing. I’ve removed the Font and About box dialogs, but I still need to address the other windows that pop-up, like some message boxes, Find, Find/Replace, and Go to line. It’s getting there.

I am perhaps inordinately proud of this work, given that I’m not a developer: Solving problems is inherently rewarding, and I’ve overcome some puzzling hurdles. But I would also like to clean up the code—a lot, if possible—and I’ve wanted to clean up or at least standardize how I style controls. So I created a resource dictionary for that, though it’s not clear that this is any more efficient.

During this entire process, I’ve recreated .NETpad from scratch—well, from my original GitHub repository version—somewhere between 8 and 10 times. The last two were fairly brutal because of all the coding involved, but I wanted to take the time to get what I have changed done correctly (or as correctly as possible). And there’s a lot of fit and finish work, though more remains.

For now, I will document what I’ve done since the last update. This all happened in such a flurry of activity, I’m sure I’ll miss something. But here are the broad strokes, roughly in the order they occurred.

Settings

As noted, the Settings page, which takes over the app window when activated, is pretty much there. (Note the use of toggle buttons instead of toggle switches.)

I’ve implemented each of the settings and settings group found in Notepad settings, though I replaced “Opening files” with my “Auto save” setting because that’s needed, and my app doesn’t (yet) support tabs. I hide two settings from Notepad (“When Notepad starts” and “Autocorrect”) because I’ve not figured out how to implement them yet. That said, I did leave the “App theme” drop-down there; I just disabled the options.

I’m particularly happy with the “Font” drop-down, though the example text area needs some fit and finish work for when the user chooses a stupidly large font. I completely rewrote a lot of the font code.

WPF doesn’t allow me to easily put the “Back” button in the title bar area, as with Notepad—doing so required a lot of custom code—so I put it over to the far right, in the same position as the “Settings” (gear) button in the normal app window.

I also added a “Reset settings” button that resets key font settings. This was something I needed during testing, but it occurred to me that users would want this as well.

There are a few nice touches to this interface. For example, when you open Settings by clicking the “Settings” (gear) icon in the menu bar, it displays normally, but when you use the Font menu item (now in Edit > Font), the “Font” setting expands as it does with Notepad.

As per Notepad, the app displays its title as the document name (if available), an “*” when needed, and then the app name normally. But when in Settings, it just displays the app name in the title bar.

Also, .NETpad supports app scaling via a set of sub-menu items under “View.” I configured this to work with the Settings pane, too. It seems to work well. Here’s what it looks like at 150 percent scaling:

I also suppress the “Save as” dialog when you’re in Settings if “Auto save” is enabled and the document has never been saved. It fires when you exit Settings.

Menu

The menu now more closely resembles that in Notepad, with three main items—”File,” “Edit,” and “View”—plus the “Settings” (gear) icon I previously implemented. I changed the names menu items to use mixed case instead of upper-case, as that’s the more modern style (“Save as” instead of “Save As,” for example.)

I removed “Search with Bing” from “Edit,” as Notepad did. But I moved the “Font” sub-menu item to the bottom of the “Edit” menu.

I had removed my “Themes” sub-menu under “Edit” previously, but I also moved “Word wrap” to “View.” I deleted the “About” menu and its “Help” item and moved the information that was there into Settings.

One thing I don’t like is that the checkmarks next to menu items representing settings that can be toggled (like “File” > “Auto save”) don’t look like similar items in Notepad. It took me a while to figure this out, but this is what these controls look like natively, so Microsoft must be using a custom style there. That’s fine, but I also don’t like that there’s no empty space in the other menu items around those items, and that’s something I will figure out. Restyling the checkmarks is something I’ll look at later.

Resources

I’ve spent a lot of time researching WPF features like styles, resources, and data binding. And I did reimplement most of the hard-coded STYLE attributes I had added as part of this Windows 11 theming update as resources. I was hoping this would be more elegant, but it’s not clear this made a big difference.

Speaking of elegance, I was hoping to bind controls to variables so that they would automatically stay up to date. For example, I use a Boolean variable named AutoSave to represent the state of that feature (on/off), and I felt like it would be nice if the three controls in the app that deal with this information—a menu item, a status bar-based text box, and a toggle button in settings—could somehow be wired up to auto-update accordingly whenever the value of AutoSave changes. This is possible, but it’s not common or easy, and I gave up on it.

Text box

I added spell check, which is natively available for text boxes and some other text controls in WPF. This is a feature the user can toggle on/off (it’s off by default) and it saves the state between app launches. As you would expect, it puts a red line under misspelled words.

It also supports a right-click context menu, though it’s styled with the same font as the text box.

This seems like a solvable problem, but my attempts to fix it with styles have thus far between thwarted. I’ll figure it out, but so far, I can get it to use the standard system font, but when I do, it displays as an old-school (non-themed) menu. Gross. I will figure that out.

What it doesn’t support is autocorrect. (That’s why that settings is hidden for now.) And there’s no “Add to dictionary” option on the context menu, though I could implement that, I think. I’ll work on the context menu stuff.

Next steps…

Next, I will start looking at how I might modernize and otherwise improve the various remaining pop-up windows. My custom windows are gone, but I still use standard File Save/Save as Open dialogs (which will remain), message boxes (for confirmations here and there), and input boxes (for Find, Find/Replace, and Go to line). For now, the message boxes and input boxes are old-fashioned looking, so I’m seeing what I can do to fix that.

If that’s not possible with stock WPF, I could wait and hope for future improvements. Or I could use the WPF UI third-party resource dictionaries, as they offer more modern control styles than does raw WPF. For example, WPF UI provides Windows 10/11-like toggle switches, native-looking content dialogs that I could use instead of message boxes, and flyouts that I could possibly use for the input box UIs. We’ll see.

And then there’s the white whale of this project: Tabs.

WPF natively supports tabs, but I can’t get them styled the way I want. I think I’ll get there.

But once I figure that out, I’ll need to implement a custom title bar for the app, as Microsoft does with Notepad. This is trivial in .NET MAUI, and difficult with the Windows App SDK/WinUI 3 (which is what Microsoft used for Notepad). But it’s very difficult with WPF. If I get to the point where that’s a possibility, then many things went right. But that’s still on the back burner while I work through some more basic issues related to tabs and how this would work with the current app.

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