The title might not be correct but I wasn’t sure how to word it properly, so here’s my ‘problem’:
My first introduction to coding/programming was the book ‘Automate the boring stuff with python’ where I learned the basics and created some small console applications that were mostly just webscraping stuff.
I quickly switched over to C# – specifically to Unity – because I wanted to try my hand at game developement. And while I learned a ton of stuff and now feel somewhat comfortable in my programming skills, I feel very confined to the Unity Engine. I basically have no idea how to build anything outside of the Unity environment.
My plan is to start expanding my horizons by making a small iniative tracker application that makes running my DnD games easier. I have already drafted up some plans on how to structure the whole ‘back-end’ (for a lack of a better word) but I am completely lost when it comes to actually creating an application with a UI.
I have started looking into WPF but it seems to have quite a steep learning curve (which I don’t mind that much) and I have heard from friends and some online sources I’ve come across that WPF is somewhat outdated. So while I don’t mind putting in effort to learn something new, I’d rather put that time into something that is relevant and thriving.
I have heard of stuff like .NET Core and .NET Framework or ASP.NET but to be honest it’s quite overwhelming and I don’t actually understand what each of these is/does.
I’d be very glad for any helpful pointers or advice!
Here’s how it sits. It’s kind of weird. Let’s talk about your options, then circle back to how to decide. It got big, so look at my reply to myself to see the TL;DR.
ASP .NET is fine, and the world of web dev has it kind of easy right now in terms of choice, because ASP .NET Core is good and MS doesn’t have other, competing frameworks in addition to it. There’s Blazor, which is kind of new, but that’s just some new stuff on top of ASP .NET Core.
Desktop development is a mess. MS hasn’t made it easy to tell new people what to do.
Windows Forms is the oldest framework. It’s a logical descendant of the VB6 development tools. People hate VB, but the IDE and UI designer were great and the “Rapid Application Development” philosophy they followed is why WinForms has a repuation as being “easy to learn”. The main fault of Windows Forms is it seems a bit outdated today. The next-worst fault is WinForms doesn’t inherently support any kind of Presentation Model pattern. I’ll circle back to this point.
WPF is part of why WinForms development suddenly stopped around Vista. MS intended for WPF to replace WinForms, and it does address many of WinForms’ faults. It has inherent support for a presentation model pattern. The main problem with WPF is MS made some bad choices that caused the community to fracture and, ultimately, stop developing applications for Windows entirely.
I can expound on that in another post if requested, let’s stay on topic! Because the community disintegrated, you’ll find a lot of materials in the 2008 or so timeframe for WPF then… almost nothing. That old information is still good! WPF is recently starting to heal from these old wounds, but we’ve also got other choices.
UWP is potentially a bad idea. It’s like a 4th-generation descendant of WPF, but it only works on Windows 10 and you have to interact with the Windows Store for deployment. It hasn’t exactly set the world on fire, and it’s not a very popular choice. But it deserves to be on this list.
Sometime next year, we’re going to see MAUI. This is a new framework from Microsoft based on the Xamarin Forms framework, which I haven’t mentioned so far. Xamarin Forms is like a 5th-generation descendant of WPF, but it’s odd because it’s based more on WPF than UWP (usually each generation looks more like the last.)
MAUI is going to be cross-platform to the extent one app should work on Windows, Mac, iOS, and Android. However, it’s so new there aren’t even any samples or previews to point you to. But it deserved to be mentioned.
This leaves two third-party frameworks: Uno and Avalonia. These are based on WPF, I won’t call them “descendants” because they didn’t come from Microsoft.
These are interesting because they’re already cross-platform (on Windows/Mac, not sure about Linux. I think Uno can target iOS/Android, not sure.)
There are also a handful of third-party, cross-platform frameworks that are more like Windows Forms, but I honestly almost never hear anyone talk about them. One benefit of picking a popular framework is you can actually get people to answer questions when you get stuck! I’m not going to mention them because I don’t think it’d be a great idea to pick them.
OK, so basically you have to decide web or desktop, and if you pick desktop you have a lot of further choices to make. All of the “good” choices involve a Presentation Model pattern. I’ll talk about what that means by way of comparing WinForms to WPF.
In WinForms, your Form has two files you care about, with 3 views. The “Designer” file contains JUST the code that creates the UI for your form. You don’t tend to edit that code. Instead there is a drag-and-drop editor that allows you to place buttons, text boxes, and other controls. Doing that generates the code that goes in the “designer” file for you.
The “code-behind” file is where your UI logic goes. So if a form has a Button on it, and I want something to happen when I click the Button, I put an event handler in the code-behind and tell the Form to connect the button’s click event to that event handler. Then I write code in the event handler to do whatever in response to the button click. I might get a user’s name from a TextBox, use that to do some work, then update another TextBox with the results.
The “problem” here is we tend to end up with very “fat” Form files. You aren’t encouraged to separate stuff that’s plain old logic from stuff that’s just for your UI. WinForms has an issue with list controls. If I want to display 10 Customer
objects in a list, I tend to have to manually create objects like ListViewItem
and do extra work to copy information from the Customer
object into that object, and that also tends to mean I need to write code to convert back from UI objects to my program’s objects.
This creates two issues. First, having your logic so tightly tied to your UI means if you ever want to chagne the UI, you end up having to edit your logic as well. That increases the odds you’ll make a mistake. Second, we like to use automated tests to verify our software. Forms and other UI types are notoriously difficult to use from test environments, and thus WinForms is very difficult to test… UNLESS you know Presentation Model patterns and make the effort to use them.
In WPF, you can do things like they were done in WinForms. In this case, the “Designer” file is a XAML file. XAML is an HTML-like markup language that has some features important to WPF. You can also use a drag-and-drop XAML designer, if you wish. The XAML file has a code-behind file, and you can set up event handlers and manually work with controls in WPF just as WinForms did. But there’s a better way.
The better way is why people say WPF has a steeper learning curve. Don’t listen to them. You can handle it.
Presentation Model is the idea “your UI and your logic should be separate and isolated from each other”. The Presentation Model pattern WPF uses is MVVM, but really most patterns are very similar these days. Knowing the short story makes seeing detailed explanations easier.
MVVM stands for “Model-View-ViewModel”, it’s just a description of how things are separated.
The idea is your XAML file is “the UI”, or the “View” in MVVM. MVVM tends to not use the code-behind for much and avoids event handlers or directly manipulating controls. There are some cases where we do use the code-behind: my WPF growth was stunted a little because I thought it was always “wrong”. But let’s keep going.
The “Model” is where all your program logic that doesn’t give a flip about UI goes. It’s the stuff you’d still write if you were making a WinForms app or a console app or even a web app. It doesn’t know or care about WPF.
The View depends on a file called the ViewModel for its logic. The ViewModel is like an in-code representation of the View.
If there’s a TextBox on the View, there’s likely a corresponding string
property on the ViewModel. For events like button clicks, there’s a special kind of object called Command
that is stored in a property. A command is executed when the event happens.
The focus on properties here is because there is a WPF feature called “data binding” that connects the View and ViewModel. In Xaml, there is a way to say something like, “If I have a ViewModel, and it has a Name property, I would like my Text property to be bound to that property.” So if the user types into the TextBox, the property is updated to contain that text.
If you change the property in the VM, the TextBox’s text changes. In this way, if you want to change the UI, all you have to do is make sure you bind the new UI’s appropriate properties to the VM and you don’t have to change the logic.
I like to say the way it works is the ViewModel is like glue between the View and Model.
WPF also handles the “list” situation more elegantly. It has a concept of “templates”, that are basically “if you see this object, use this UI to display it and bind to the properties this way”. So instead of having to manually convert back and forth, you just expose a list of objects and the XAML automatically applies the template to each one.
People look at that and think it’s really hard. But let’s compare it to the MVC pattern that ASP .NET Core uses and I think you’ll find something interesting.
MVC is a Presentation Model pattern. It stands for Model-View-Controller.
This is a web framework. So the user goes to a URL. A part of your application called “routing” looks at the URL and uses it to try to find a Controller intended to handle the URL.
When it finds a Controller, it creates the object and calls a particular method on it. That method looks at any data that came in via query or POST data, then uses Model objects to do some work. Just like in WPF, the Model refers to the parts of your application that don’t care about UI.
Once a result is generated, a View is selected. The View is generally written in a markup language that’s like HTML, but has some extra syntax. This syntax enables data binding to a model, with templating features much like WPF. So, just like how a ViewModel and View use binding in WPF, a View and Model use binding in ASP .NET MVC!
Practically every modern UI framework uses a Presentation Model pattern. HTML frameworks like React, Angular, and Vue use it. Android cribbed so much from WPF they call their markup language AXML. Apple got here first: Cocoa has been using MVC for Mac applications since the 90s. WinForms is unique in that it doesn’t use one of these patterns! So that means learning WinForms can sort of make it harder to learn other frameworks.
I say start with WPF. If you start with WinForms, I think you’ll feel like you’re learning more faster, but there’s going to be a problem later.
At some level of complexity, it’s hard to keep adding features without using Presentation Model. When you reach that point in WinForms, it will be like you hit a brick wall: you have to stop and go back to “learning” before you can proceed, and you’ll have to rewrite big chunks of whatever you were working on.
On the other hand, if you start with WPF and focus on MVVM, it will take you longer to start writing reasonably complex programs. However, by the time you get to “complex enough to need MVVM”, you won’t have to stop to learn new concepts, you’ll already have them. Further, we know MAUI is going to use MVVM along with a new pattern called MVU that, surprise, involves Views, Models, and something that glues them together with data binding. So if you know WPF, MAUI will be easier to pick up.
Further, if MAUI fails and MS decides to tell everyone to use HTML frameworks instead, all of the HTML frameworks use Views that are glued to Models via data binding. (They call it “reactive properties” but it’s data binding.) So even if WPF dies after you learn it, the things you learned using it will help you learn what replaces it.
WinForms is the last branch on its tree. There is almost no chance MS will make a new framework based on it, and an even smaller chance a third-party will make a new one. It’s not a bad framework, but learning it today won’t help you learn what’s going to come out in a few years.