I am at the point in my Project Galaxy development that I need to have said galaxy generated so I can start building against it. I have done this many, many times in the past, so I have it down to almost a science, but because the “Big Bang” process is something that basically flatlines and rebuilds the game board, it’s not something I want to entrust to an online portal. The fear is that some dedicated asshat would find a way to execute the code, reset the game, and everyone would get pissed, including me.
I got it in my head that one way to circumvent this was to create an “offline” management application. Back in the early days of the Internet, we used to call these “desktop applications” because they ran on your local computer rather than “in the cloud” or “on the Internet”. You had to be there. My thought was by having all of the scaffolding code in this offline app it would be local to me and me only; I would only be pushing the results to the database which I could do by directly connecting to it (which is really just another version of “in the cloud” but some concessions have to be made to get this whole project to work).
It’s been nigh over 20 years since I’ve had to work on a desktop app, so I went to where developers hang out (StackExchange) and hunted around for the best option for creating desktop apps for Windows in 2022. You know what I found? Of course you do, it’s in the title.
WPF. It’s still fucking WPF.
If you know, you know. If you don’t, I’ll make you know whether you like it or not so we can all suffer together. “Normal” Windows app development that I was used to from back when I first learned real-world development (VB 4 illegally downloaded over a 3600 baud modem while I slept represent!) involved dragging and dropping form elements onto a canvas, and then adding code to handle those form elements. It’s actually very intuitive this way because you have a visual representation, and usually all you need to do is to send data back and forth to the component from and to the code-bearing back-end.
WPF — Windows Presentation Foundation — surfaced sometime in the early 2000s as kind of an update to the old school “WinForms” method that had put the “visual” in “Visual Basic / Visual C / Visual Studio”. Because the Internet was proving to be more than a passing fad, Microsoft apparently decided that their next platform should cleave more closely to HTML than to whatever was driving Ye Olden Visual Designers, and XAML was born.

Taking the ease of HTML and the hierarchical representation that is XML, XAML is a declarative presentation construction language that threw out the good parts of both HTML and XML and doubled down on the bullshit. I had once been interested in WPF and XAML when it originally launched because as a script-like language that relied on a separation of presentation and function (the only part it gets correct), it was suitable to write once, use anywhere, either as a desktop app or on the web. They even had (and still have, with rumors of its death having been greatly exaggerated) a visual tool called Blend which allowed for less coding and more doing. XAML does solve a key issue with data-driven applications, which is getting and returning data from form elements, through the use of two-way data binding, and since most of my apps were/are data driven, this fact alone made it worth my while to look into what WPF and XAML could do for me.
The issue was — and still is — that XAML is painfully obtuse out of the box. As powerful as the two-way data binding is, it’s not intuitive to set up. For example, I’ve been working on a “Settings” form through which I can modify the connection string for my app.

It’s just a window with a two-column grid layout, the first holding labels, the second holding the textboxes.
Now, here’s the code that designed this:
<Window x:Class="GalaxyManager.Views.Settings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:properties="clr-namespace:GalaxyManager.Properties"
xmlns:local="clr-namespace:GalaxyManager.Views"
mc:Ignorable="d"
Title="Settings" Height="450" Width="400">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0">Server Address</Label>
<TextBox Grid.Column="1" Grid.Row="0" x:Name="txtDBAddress" Text="{Binding Source={x:Static properties:Settings.Default}, Path=DBAddress}"></TextBox>
<Label Grid.Column="0" Grid.Row="1">Server Port</Label>
<TextBox Grid.Column="1" Grid.Row="1" x:Name="txtDBPort"></TextBox>
<Label Grid.Column="0" Grid.Row="2">User Name</Label>
<TextBox Grid.Column="1" Grid.Row="2" x:Name="txtDBUser"></TextBox>
<Label Grid.Column="0" Grid.Row="3">Password</Label>
<TextBox Grid.Column="1" Grid.Row="3" x:Name="txtDBPassword"></TextBox>
</Grid>
</Window>
Honestly, it’s not terrible, but whereas I might just want to bind a textbox to the property that’s accessible via the Settings namespace, I had to add a namespace alias at the window level:
xmlns:properties="clr-namespace:GalaxyManager.Properties"
I then had to contort the code to actually do the binding to the DBAddress textbox:
<TextBox Grid.Column="1" Grid.Row="0" x:Name="txtDBAddress" Text="{Binding Source={x:Static properties:Settings.Default}, Path=DBAddress}"></TextBox>
In plain English, this is telling the textbox to get its text from a data binding whose source is represented by the x:static resource known by the alias properties, which allows us to narrow down to the actual source of Settings.Default. Then we want the specific property DBAddress which holds the data.
Me, thinking that things could be easier, originally tried:
...Text={Binding Path={GalaxyManager.Properties.Settings.Default.DBAddress}}...
Even with the boxcar-like construction, my attempt was far too logical for XAML. I wouldn’t have even known to go anywhere near the way that I had to set it up to work had I not expected the process to be more painful than it really needed to be. And while it does work at this point, I have to ask “why”? Why is XAML such a pain in the ass? And why is it still currently the “best” way to write data-driven desktop apps using .NET?
That is not an open-ended question for the peanut gallery to throw their own personal opinions on other development platforms into the ring, because if I have time to learn another language and platform, I have time to learn XAML, and that’s kind of the point. I don’t want to have to learn XAML to the extent that XAML makes me need to learn XAML, so I think I’ll kick this plan to the curb. Truth be told, we have a XAML-based website still in operation at work, and since I made the mistake of once mentioning that I had an interest in developing using this “next gen” platform, I got saddled with its upkeep. If anyone pings me with a question about it, though, I start to sweat because it’s the biggest piece of crap project I have ever had to work with.
2 Comments
Tipa
April 19, 2022 - 9:40 AMWhy not just use Bootstrap with a node.js back end? This definitely sounds like outdated tech.
Scopique
April 20, 2022 - 7:36 PMThis is what I am doing. My thought was to integrate the admin into the actual game, using the game server to handle the processing and reporting and all that, but then I figured it was a Very Bad Idea(tm). So I am using another Node instance connected to the same database with another React front end. If it ain’t broke…