Life With WPF: 10 Things Wrong With WPF Today
[Caveat: This is constructive criticism about XAML and the current version of WPF. They both have their strengths and things I love about them and they both may become better over time, but this is about what we have today.]
After Tomer published his list of 10 Reasons to Love XAML, I wrote a long rebuttal. After reviewing the points I wrote, I decided to instead counter it with a list of ten of the things I think are wrong with WPF and XAML today. I'm originally a Windows Forms developer, so at times my points may seem like a comparison with it.
- Separation of Code From Design?
Developers shouldn't need to think about styling their data's logical structure. This is very nicely implemented in HTML, where the developer denotes <div> when they want to divide their structure. The developer doesn't need to know where that div's contents will sit at the end of the day, when the page is presented to the end-user. For them, it's a simply <div>.
In WPF, there's an attempt to embrace this principle, but it just doesn't go far enough. Why should I, as a developer, when faced with the decision of which container to use for my elements, have to decide between a StackPanel, a Canvas, a Grid, a WrapPanel, a DockPanel or a UniformGrid (which are only some of the choices for a panel, not to mention everything else that isn't a panel).
"Let the designers have the first go then," you'd say. And you'd be wrong. Just try it and you'll see so many WPF 'sins', you'll simply have to do the whole thing over again. Just take a look at Dr. Greenshpan's lecture (last link on the right, when it finally decides to start working again; sorry, Hebrew only) from MSDA2, where after a year's work, they reached the exact same conclusion - the iterations of design-development should start with the developer. Why should a designer care if they have a StackPanel or a VirtualizingStackPanel? Why should a designer care if they have 5000 BitmapEffects? I, on the other hand, would.
The problem starts and ends with both the designer and the developer having to deal with the same files and object structures, simply because the separation of logic from visualization is incomplete. After all, in a well-defined work environment, no web developer would give their designer their HTML sources much in the same way that no web designer would let a developer mess with their CSS.
- No Code = Run-Time Errors Galore!
There are two distinguishable schools of thought when it comes to infrastructure development: The first being the one of Generators, where the tool you use creates code for you and parses said code when you need to change something using the tool; The second being the Framework, where the tool you use is what gives you services, so you have to write less code.
Full disclosure: I'm firmly in the Generators camp, even though it's been a while since I wrote one.
The problem here is not that WPF is a Framework (and a little bit of a generator too - more on this in the next paragraph). After all, the CLR is a Framework and the .NET Framework is, you guessed it, a Framework. I'm all for a Framework, but only when it's nice a the developer. WPF is not nice to .NET developers: It throws exceptions that sometimes have nothing to do with the error encountered. It writes a lot of stuff to the Trace output and quietly fails. If it wasn't for tools like Mole, which incidentally was not released by Microsoft but rather by a few good developers from the community, the average developer could spend several hours a day just trying to find out what the heck went wrong with what they've done.
A 'funny' anecdote is whenever you get a compile-time error from a file generated by the compiler, like Window1.g.cs, when it says that a namespace was not found or that you can't inherit from one class or the other. Good luck tracking that one down in one of your XAML files (or maybe it's not even there! Yay, Terrance, let's look for treasure!)
- Strong Typing? Generics? Never Heard of Those
WPF sits on top of CLR 2.0, but fails to use its characteristics:
I want the most possible compile time errors to occur, so that I don't have to deal with them at run-time.
- I want my Dependency Properties to be typed, rather than checked at run-time.
- I don't want the run-time to yell at me when I send the wrong type of parameter or the wrong parameter order to a converter. I want the compiler to check that for me.
- The CLR team invented CLR Generics for a reason - why can't I use my generic classes with WPF? Is it simply because angle brackets don't translate well to XML?
- XAML Adds Complexity and Logic/Data Cohesion
Let's face it - XAML is a form of DSL. It includes new syntax for binding, resource references, property references and so on, a different parser and compiler, three more mediating layers (which comes down to six layers already: XAML->WPF->.NET Framework->BAML->IL->ASM) and overall - more complexity.
Wait, no, it's actually data - it's a hierarchical structure of your user interface. You could just as easily store it in a database with a hierarchical structure and load the appropriate pieces at runtime. Just think of how LocBaml (and we'll come to that too) treats BAML.
So which is it? Logic or Data? It's both.
- Don't Like the Control's Style? Do Over!
The WPF mindset says you have to style your control. That's all well and good, but what if my control is made up of other controls and I want to style those? No can do, bub, unless the control's original developer explicitly let you do that. So what do you do instead? You redesign the control - copy/paste the original design and do what you like with it.
This is horrible news for those of us who like code (and design) re-use. You simply unlink the new design form the old one and do it all over again, even if what you wanted to change was a sub-sub-sub-sub-sub control's background color. And what happens when the original control gets updated to a newer, cooler design and you simply would love to get that one? You guessed it - you copy/paste and Redo From Start.
- XAML is Code-Behind-Language Dependant
And if you didn't know that, here's an example of why.
- Converters Seem Like a Patch
Converters are really useful - you want to take a piece of data and convert it to a different representation, so you write a piece of code in your code behind and reference your binding to it. But then you realize that the feature is a very simple, stripped down version of the idea:
Lack of a Good Tool for Developers
- You only get to pass one static parameter. Want to pass on more? You'd have to create your own data structure. And did we mention it wasn't statically typed? (see #4)
- You can't pipe converters for re-use (instead of converting from Type1 to Type2 with a preexisting Type1toType2Converter and then to Type3 with a preexisting Type2toType3Converter, you have to write a new piece of code for a Type1toType3Converter), unless you go ahead and create your own framework for it.
- Values aren't named, so you have to rely on the - you guessed it - untyped order.
- Conversion, when there's no converter specified, is done using Type Converters, a framework you can not extend.
- There are bugs and missing features.
Lack of a Complete Tool for Designers
- Cider (Designer View): No one I know uses Cider. We all write XAML by hand. I've never seen Tamir open a Cider window. Tomer went as far as to make the XML editor his default editor for XAML files.
Do you know how to attach to events using Cider? I don't, because as far as I know except for the default event - you can't.
Have you noticed that half of the properties in the grid are type names, so you can't edit them?
- XAML View: How many times have you received weird warnings from your XAML editor? How many times did it show you a compilation error as long as you didn't actually go and compile it?
Also, a good IDE allows the user to write code without using its auto-completion features, but the XAML editor interferes with your intuitive writing flow and you have to get used to it, instead of it being used to you.
I have to say that as far as this item is concerned - I have very little personal experience.
For as long as I have worked with the designers on the current project, I've heard a whole range of statements from "Blend can't do this... well, at least not in the current version" to "Blend knows how to do that, but it simply doesn't work that well with it." These problems were so big they have resorted to working with a CTP of version 2.0.
Localization as a Second Class Citizen
I have no idea why the people behind WPF took a leap backwards from Windows Forms when they made LocBaml. With absolutely no internal Visual Studio and/or Blend support, you have to resort to translating plain text files and using command line tools to compile them.
My current client decided to completely stop using it (also because it needed features that just didn't and couldn't exist in LocBaml, but did in Windows Forms, such as replacing the language at runtime) and asked for a whole new mechanism.
...and I haven't even talked about the incompleteness of the WPF framework (for instance - it doesn't have any color-oriented transformations (I had to resort to GDI+ for that one)) or some other little annoyances (see footnote here)...
I don't want anyone to think I dislike WPF. I don't dislike it. It has it's place in the world and has already proven itself to be a very useful skill in my arsenal. All I hope for is that some, if not all of the above problems are tended to. Version 2.0 - I'm waiting for you with open arms! :D
Wow, that was long. I hope you got through it. I don't think I would have been able to myself. ;)