Friday, March 21, 2025

My talk at MAUI Day in London

For most developers working with MAUI (or WPF, or WinUI, or UWP?), creating the UI means using XAML. I've probably spent more time thinking about how this could be better than anyone--not a boast, and I wish this wasn't the case--so it was a privilege to share my thoughts with an audience who uses this technology every day.

With MAUI.. so productive (it's an art) you know you're good when you can even do it with XAML
Yes, I included multiple Taylor Swift references in my slides. What of it?

This was originally posted on LinkedIn as a 1, 2, 3, 4, 5 part series. The actual talk was only 3 sections, but writing it up in 5 parts felt more appropriate.


The following is a brief summary of the talk (and without music, memes, most of the 116 slides, some of the demos, lots of energy, and only a few things being thrown.) That's the thing about in-person events. They're not the same as blog posts or recordings.



Part 1 - If XAML is bad, why is no one doing more than "just" complaining?


XAML is the default option for defining UIs in MAUI (and WinUI, WPF, & UWP) yet everyone seems to agree that XAML is far from great. It can be verbose, hard to read, hard to understand, and hard to maintain.

Lots of people complain about it, but no one does anything about it.*


If it's so bad as to be worth repeatedly complaining about:

  • Maybe the solutions are so obvious to everyone else that it doesn't even need saying. But, if that's the case, why does everyone: complain, write objectively bad (I said "poopy" in my talk) code, and write code that looks like it could have been written 18+ years ago?
  • Maybe the complaints aren't real; people just like complaining, and XAML got the short straw when it came to choosing what everyone should moan about. But that can't be the case, as it is objectively bad.
  • Maybe what I see as bad is "good enough" for everyone else. But if that's the case, why all the complaints?

Surely I can't be the only one who sees the issues and has thought about doing things differently?

If that's the case, it's a very scary thought.


XAML has been used by hundreds of thousands of people since it came out in 2006 (for building WPF apps) and little has changed since then:
  • The books from that time are still mostly relevant.
  • The examples from that time are still mostly relevant.
  • The way it is taught has not changed since that time.

Are there other languages that are actively encouraged to be used and have seen so little development in almost 20 years?

Imagine trying to use a 19-year-old book on C# today!


It's not just that there are no new versions, it's that the way we think about it hasn't changed. When every other aspect of technology is evolving and being updated at a great pace, why has something that we all know to be bad not been given any consideration to how it could even be used in better ways?


How do people justify choosing to use this technology today?

If an employee or co-worker told me, "We're going to use X technology, we know it's not great, and we make fun of how bad it is, but we're going to use it anyway." it would raise some serious red flags:
  • Why are you using it?
  • What are the alternatives?
  • Are there ways it can be used that address some of the problems?
  • What other decisions have you made with the same justification?
  • Why is this acceptable?
Developers are supposed to be smart people. Does this seem smart?


*Some people (probably between 6 and 12% of MAUI developers) have decided to abandon XAML and use C# instead. 

The argument goes something along the lines of "XAML is bad, but I like C#; why don't I [or we] just use C# for everything."

It's a reasonable argument and certainly possible, but I don't think it's the silver bullet that some claim:
  • Most UIs defined in C# (all examples I've seen) adopt the same structures, patterns, and mistakes seen in XAML files. The code is basically the same as the equivalent XAML. Just because it's a different syntax, doesn't make it better.
  • Claims of a "fluent interface" are exaggerated due to the use of method chaining for some functionality. In reality, the need to combine setting some properties directly, setting some properties via chained methods with the property name, setting some properties via a chained method with a different name, and having to rely on massively overloaded fallbacks for some functionality means you can only really be fluent if you're very familiar with all the options and which to use when.
  • That C# is "easier" and has "helpers" available ignores the fact that XAML can be written to be "easier" to read and helpers can be created to work with it too.
  • Claims that the use of C# creates a faster application than using XAML, ignores the benefits, of using compiled XAML. More importantly, the performance of code is often down to the way it's written and used, rather than an underlying benefit. I've not seen these performance claims backed up with real data to show the benefit, and people arguing this position don't seem as concerned with optimizing every aspect of their code for performance. If performance is a problem or is critical to an application, then, of course, you should do what's necessary to produce software that performs adequately. If you claim to make a decision for performance reasons but don't measure performance or optimize for performance consistently, I don't consider it a good argument.
  • That C# needs to use fewer "magic strings" ignores that there are ways to remove the need to use any kind of "magic value" in most XAML scenarios and that most C# code (including demos and reference examples) is littered with "magic numbers".
  • One argument for using XAML is that it encourages the separation of logic from presentation code. Though it's possible to maintain this separation when using C# for everything, it can lead to more complex code, and the effort required to separate things means it is rarely done.
  • Even if everyone did decide to switch to using C#, does that mean they need to rewrite all their existing XAML? Would that be the best use of people's time? Would everyone be able to do this confidently because they have good UI test coverage and so could avoid introducing any unintended changes while doing the rewrite? - No!
  • And if using a single language for everything is so great and such a wonderful solution, why don't we see this elsewhere on other platforms and with other technologies? For the people switching to Blazor because they don't like XAML, they still use HTML and C#. Why is almost all web development done with at least three languages (HTML, JS, & CSS)?

I'm not going to stop anyone from using C# for their UIs. In fact, I use it for some things myself. When there is logic required in determining what the UI should look like or be comprised of, using C# can be much more productive and performant than trying to do everything in XAML.

There was never meant to be a decision between using XAML or C#. It has always been the case that you get the best results when you use both. XAML and C# work together.


Of course, if the tools and languages you're using to create your app UIs are as good as you need and can imagine, and you're super productive, and couldn't possibly get any better, keep doing what you're doing.

I've yet to meet anyone where this is the case, and there was no one at the conference who admitted to this situation either.


I was worried I was "bringing sand to the beach" to present these ideas to a room full of experts and highly experienced individuals who work with XAML on a regular basis.

Sadly, I'm still to find others who are not writing the same bad XAML as everyone else.



Part 2 - How XAML can be written in more maintainable and developer friendly way.



Aside: What does good XAML look like? - If you've never thought about it before, take a minute to consider this. Barely anyone has a good idea.



It's not "just XAML" or "only a markup language".

What we put (type) in files that become part of an application and which we later need to read and possibly edit all have a lot in common. Yes, C# and XAML look very different and are typically used for different tasks and in different ways, but there are some truths that hold for both (or all) programming languages.



For any "code" that we'll have to maintain, we want it to be:

  • Easy to write
  • Easy to read (and understand)
  • Consistent
  • Well formatted
  • Unambiguous
  • As concise as possible without inhibiting understanding
  • Without unnecessary duplication or redundancy

There's nothing controversial in that list. Is there?

Nothing you'd disagree with? - If there is, please leave a comment.



But, does that sound like most XAML you've ever seen?

I doubt it. And I think that's a problem.



If you think about it for a moment you'll start to question this too.



Above I got you to think about 'what good XAML looks like'. Almost everyone I've ever asked this question doesn't have an answer. The couple that did, said "it should be well formatted."

If formatting is the standard for quality, I think we have a big problem.

And, as people do want more maintainable XAML, we have a big problem.



So, what can we do?



I think consistent formatting is just the start.

Here are some other things to do:

  • [Only] include useful, relevant comments.
  • Order content within the file so that it matches the order of items being output.
  • Structure the use of files within directories in a consistent manner.
  • Avoid miscellaneous files that become a "dumping ground" for assorted functionality.
  • Follow the Single Responsibility Principle. Give elements in the XAML a single task and, therefore, a single reason to need changing.
  • Simplify layout structures within files.
  • Avoid using unnecessary elements.
  • Avoid setting redundant or duplicate property values. 
  • Avoid specifying properties with their default values (unless there's a good reason and you add an appropriate comment to explain it to people looking at the code in the future .)
  • Don't repeatedly define the same values/items.
  • Make use of language features.
  • Use inheritance where appropriate.
  • Don't use "magic strings"
  • Don't use "magic numbers"
  • Encapsulated repeated logic.
  • Use language features (such as a custom MarkupExtension) to show relationships between values and make those relationships clearer.
  • Avoid repetition of text. (So you only need to change it once, in one place.)
  • Use semantically meaningful names that show where and when to use something. (Not what it does or looks like.)
  • Don't use variations of "Hungarian Notation" when naming UI elements or resources.
  • Use inheritance to simplify code. (There are tools that can help with this.)
  • Create new types that combine existing ones that are repeatedly used together.
  • Create new controls to isolate stand-alone pieces of logic.

There is more detail on the above can be found in the MAUI - Focus on XAML workshop. (Sorry that this means giving you homework, but I'm not sure it's in anyone's benefit to repeat that here.)



Applying the above means that it's easy to go from code like this:

Complex and deeply nested XAML code
This code produces the screen in the screenshot.

To something much shorter, clearer, and easier to maintain, while still producing the same output (the image in the top right):


A small amount of meaningful XAML that is easy to maintain - and produces the same UI as the last example
Yes, this produces the same as the above, shown in the inset screenshot.


 
Additionally, as there are often multiple ways of achieving the same results, why not use some of those things to reduce the nesting, verbosity, and complexity of XAML with something much shorter and clearer.

For example, why not use an Attached Property to add a gesture recognizer? Like this:

3 highlighted examples of different ways of achieving the same result
3 ways of triggering an event or command when a button is tapped.


Or something similar for adding behaviours to a control:

eight lines of code or one?
2 ways of triggering a command when the button is "Clicked"

Or maybe you want an easier way to specify the values to pick from:

Give a picker three options with 7 lines of code, or as a single property taking a comma separated list?
Again, both code snippets produce the same UI.


Have a look through the above examples. Take a moment to get past the shock of seeing XAML that isn't as unnecessarily verbose as you're used to.

Which is easier to read and understand?

Which is quicker to type?

Which would you rather maintain?



Why doesn't everyone write code like the above? Each attached property is only a few lines of C#, and yet it makes working with the XAML massively more pleasant.



We're not limited to attached properties.

Creating custom Markup Extensions can greatly reduce the amount of text needed to apply a conversion to a binding and also make the text clearer. 

For example, the following shows four versions of a string being displayed. The first is without any conversion, the following examples show different ways of using a converter.
Text="{conv: AsUpperCase SomeTextProperty}"
Isn't it nice when there are fewer words needed and those words are all necessary and helpful!

Plus, creating the extension only required adding an attribute to an existing converter. How simple is that?
AsMarkupExtensionAttribute !


Using XML namespaces and carefully choosing names can make code embarrassingly easy to read and understand. Even if you're not familiar with XAML or the code base, is there any confusion about what the following would do?

Lots of short, meaningful pieces of code -- like no one is used to seeing in XAML
Some people complain about the inclusion of XML namespace aliases, I prefer to use them in ways that provide clarity.


Or, maybe we use a markup extension to reduce the creation of a complex item with properties (StartPoint, EndPoint, and Offset) that I can't and don't want to have to remember:

Two ways of creating a horizontal gradient. One with 7 lines of code, the other with only 1.
Two ways of creating a horizontal gradient. One with 7 lines of code, the other with only 1.
Yes, both code snippets produce the same output (as seen in the top right)




XAML doesn't have to be verbose and complex, it comes with ways to use it that are significantly easier to maintain and (relatively) a pleasure to work with.

What is stopping everyone (anyone?) from writing XAML like the simpler versions above? I'm not aware of anything. - If you have an answer, please share it.



Part 3 - Creating XAML doesn't need as much typing as you might think


The tools we get "out of the box" for working with XAML in MAUI basically come down to creating a sparsely populated application and the need to type everything by hand (with a bit of intellisense).

I've created some tools (and experiments) that make getting from nothing to a basic project architecture much easier, and from an empty file to useful appropriate XAML content much faster.



The MAUI App Accelerator is a Visual Studio extension that enables the creation of MAUI apps through a wizard-style interface. (Remember I said I like GUIs.)

It allows you to specify :
  1. Which version of .NET to use (You should be using .NET 9 for your MAUI apps!)
  2. Whether you want to use XAML+MVVM, XAML+CodeBehind, or C# to create your UI
  3. If you want to use the Shell, and what sort of navigation style (tabs or flyouts) to use
  4. How many pages you want in the app, what they should be called, and what (if any) default content they should include
  5. What features, functionality, libraries, and dependencies should also be included in the app
It then produces an application with all these options, all correctly configured and with dependencies and initialization already done. 

It doesn't sound like the most revolutionary thing in the world, but it can definitely save minutes and maybe even hours to go from nothing to a complex working application full of correctly configured and useful dependencies.


That's great for new apps, but what about extending existing apps?

Well, version 2.0 is "coming very soon", and among numerous other improvements is the ability to use the same wizard to add new pages and features. Of course, it does this with the same level of integration into the existing app, so it automatically registers dependencies, adds resources, and correctly configures and initializes all it adds.

Screenshot showing the new "Add page..." and "Add feature..." options
These new options can be a massive time saver


So, that's great, we can now build the basic structure of our application much faster, but what about getting the XAML we want inside the pages of the app?

I have two ideas to show on that subject.


First is the Pro XAML Toolbox

This is a variation on the default Toolbox, but it adds more useful and appropriate content to the page. Many options are configurable, and items can be dragged where desired or double-clicked to be added where the cursor is.
The Pro XAML Toolbox in action. Showing different elements being very quickly added by dragging and double-clicking on elements  in the toolbox
See how quickly a page can be filled with useful, appropriate XAML

While that allows the creation of XAML much faster than typing by hand, I still think there is a faster way.



For most data types in a ViewModel, it's possible to make a reasonable assumption about the UI controls that can be used to display and allow interaction with them.

When those assumptions are codified (in a configurable way--of course), then it's possible to generate the XAML corresponding to a particular ViewModel file.

My preferred way of implementing this is to simply drag the ViewModel file onto the View and have the XAML code be automagically added.

When doing this, the file is analysed, and appropriate elements are created depending on the types, their names and if they can be changed.

See below that:
  • A bool called IsRefreshing becomes bound to an ActivityIndicator.
  • An ObservableCollection<T> produces a CollectionView and the DataTemplate includes entries for each of the properties for the Type.
  • Commands cause buttons to be added to the XAML to trigger the invocation of the command.
  • etc...
Animated screen capture of a file being dragged onto a file and appropriate XAML being created
No steps were removed. It really is this fast

It's also possible to open the ViewModel, select some properties and choose "Copy as XAML" which you can paste wherever you want.



As with the Pro XAML Toolbox, this isn't going to always give you exactly what you need, but it is much quicker and easier to make small modifications to something that is almost right than it is to type the entire thing from scratch.



This isn't all just me showing off. I'd much rather that someone else had created the above (and shown how XAML can be made more maintainable.)

The above is to show that other things are possible.

Given that this is possible, why has no one else done anything like this before? (There are a few command-line-based template options available, but nothing else with a GUI or as much flexibility. And nothing beyond that.)




Ok, we've seen that while everyone agrees that most XAML is bad, it doesn't have to be that way.  I've also shown that there are ways of writing XAML to make it much easier and more pleasurable to work with, and that it's possible to create tools to make working with XAML files easier.

Is this as far as we can go?

Is this as good as it can get?



Microsoft doesn't seem interested or motivated to consider any big changes. 

No one else is doing anything in this area.

That's not going to stop me.

Thanos:  "Fine. I'll do it myself."
Not that I want to be comparable to Thanos in other ways



Part 4 - What if we didn't write XAML?

If XAML has so many problems and it's taken this many years to identify and try and address them, maybe we should look for something new to replace it.

However, introducing a new language to replace XAML would have a number of challenges:

  • It would need to be able to work with existing XAML (& C#?) to avoid the need to rewrite all that already exists.
  • Many people would still assume the need to rewrite in the new option as the other option(s) would (eventually) go away.
  • Assuming that the new language also came from Microsoft, the number of things they need to support and maintain would be increased (they'd need to ensure all pre-existing things continue to work) and this extra requirement would slow down development/advancement in other areas.
  • What about all (sigh) the tools that already exist? Would they need replacing or updating?
  • It would require thorough documentation (which takes time and effort).
  • All the SEO goodness of existing docs, blogs, etc. would make it hard to find appropriate, up-to-date information about whatever is new.
  • Developing a new language is hard to get right.
  • Developing all the required integrations with developer pipelines and other tooling (there's more to MAUI than just XAML) is complex and would be a lot of effort.

That's a lot of reasons not to do it, or to not expect something anytime soon.


It's especially tricky as my expectation (based on 25+ years in the Microsoft/.NET developer ecosystem) is that developers are highly unlikely to pay for a solution that doesn't come from Redmond. Nor would there be a lot of participation in creating an open-source solution.


But, I'm channelling my inner Thanos right now, and I think I have a possible solution.

Come. Let me help you.
Is this too much Marvel?



Rather than replace what already exists (both code bases and toolchains), why not sit on top of that? 


I've created a rough specification and prototype of a new language that produces XAML.
The output XAML (& C#) can then be used just like the files you have and write today.

The intention is to define the UI in the new language which then produces XAML and everything continues to work as before. 
Tooling and IDE integrations quickly make this feel natural.


This way, everything that currently works will continue to work. New things are extras and on top.

  • By having a new language that can produce XAML (& C#) files that are used as the project system and developer tools currently expect, there isn't the time and effort needed to change what already exists. We can experiment and iterate faster on possible alternative solutions.
  • By producing files that are valid even if the experimental language goes away or you decide not to use it, there is little risk. You still have working code, and you're not stuck with something that needs to be rewritten in a way you can support and maintain going forward.
  • As it works on top of existing files, it can be used in whole or part within a project or a team. Just start using it for the files (pages/controls/dictionaries) that you want. It's entirely optional.
  • By treating XAML as acceptable input, it's also really easy to try it out. Just copy the existing XAML into the new file and start modifying it there. You can progressively switch to the new, simplified syntax and make use of new functionality a bit at a time. If there's anything that can't be done with the new language (or you don't know how) simply fall back to doing it with XAML.
  • By generating code at design time, it's possible to do things that hand-written XAML can't.

Added bonus: this could also work with WPF and WinUI. There is nothing here that is specific to MAUI.


So:
  • Low effort
  • Low risk
  • Big improvement


I think this is worth exploring further.



Because it's helpful to have a name to refer to things, I call it ENAMEL. (Experimental Native Application Markup Extension Language)

Here's a very basic teaser of it in action:

Video of Visual Studio. Enamel file is edited, causing the XAML file to be updated and a "previsualization" of the page reflecting that change.
An ENAMEL (.enml) file in use inside Visual Studio

The above animation shows 3 windows inside Visual Studio. 
  • On the left is an .enml file in an editor window. 
  • In the middle is the .xaml file produced from the ENAMEL. 
  • On the right is a design-time "pre-visualization" of what the page will [approximately] look like.
Yes, this is the default new page with some additional buttons at the bottom.

In the animation:

  1. A property (highlighted in pink) is uncommented in the ENAMEL and the file saved.
  2. This causes the XAML to be updated (yellow highlight) and that property added.
  3. This change is also reflected in the "pre-visualization" of the XAML. 


Aside 1: The highlighting of parts of the code was done with this extension


Aside 2: The "pre-visualizer" is a tool I previously built for myself to give me an approximation of what the rendered app will look like. It doesn't remove the need for running and testing the app on real devices but it increases my confidence that the XAML I have will produce the output I expect. While tools like Hot Reload and Live Preview are useful, the "pre-viz" helps me avoid the frustration and disappointment of compiling and launching the app to discover I've left something out or made a silly mistake. This isn't specific to ENAMEL.


I'm not going to show here the details of the ENAMEL language that I showed on the day.

I'm not doing this to be a tease. I will share more details soon.

I'm trying to avoid making the discussion about my specific implementation when I want it to be about the concept.



The point I'm trying to make is that once I identified that there was a way to create a simple experiment with alternatives, it was easy to produce something that let me try it out.



I admit that I was well-placed to produce such a seemingly polished proof-of-concept. I've built DSLs (Domain Specific Languages) before and have experience integrating with Visual Studio.

To get as far as I did took a total of less than two days effort to implement. (Not including time spent in advance thinking about rules/syntax for the language.) Most of the Visual Studio integration was cut and pasted from previous projects, and I spent less than an hour doing the simplest possible thing I could to get basic colorization (classification) of the code.

In reality, all it's doing is taking a multi-line string as input, parsing it and returning another string containing XAML. It's basic stuff that anyone with at least some basic C# experience could do. If it was a separate app or had a command line interface to turn one file into another it wouldn't seem so remarkable.



Forget my implementation. Is this a good idea?


How would you feel about using a new, powerful, yet simple language to define your UI?
And, that then gets turned into XAML and used when compiling your app?


I know there are much smarter people than me out there who may have much better ideas.


I'm not trying to say I have the solution.
I am trying to say that we need a solution; how about this as a starting point?


What do you think:
  • How can we make existing and future XAML easier to work with?
  • If it's another language, what should it be like?
  • If not another language, then what?


Part 5 - Now what? The future of writing XAML and me



So, now what?



On the day, I stated what thought the best and worst possible outcomes of my talk would be.



The best possible outcome would have been if multiple attendees could point out why I was wrong and explain why what we had at the moment was actually much better than I realized.

This would be the best option as only my time would have been wasted. 



The worst possible outcome would be if I'm right.

It's bad because it means everyone has been wrong. "Forever". And no one has pointed this out before. It's also bad because it probably means most people will want to wait for a solution from Microsoft and that's unlikely to come any time soon.



Ok, so this isn't life or death stuff, but it's what tens (hundreds?) of thousands of developers spend time on every day. If that time is being wasted and people are working more slowly because it's hard and frustrating to do what they want, I still think this is worth improving. How could that time better be used? What are we missing out on because of all the time lost to fighting "poopy" XAML?



Maybe there's a middle ground between my best and worst scenarios.



I'd love to continue to develop these tools and ideas. However, I'm currently in need of paid work, and what I get will determine how much time and energy I can spend to continue this.

  • In an ideal world, there's someone in need of my development skills and an interest in these tools so that I can continue to develop them in ways that become beneficial to that company/project(s) and the wider community.
  • Or maybe there's a company I can help build some software and this will leave me to continue developing these things in my own time.
  • Or, maybe there's a company somewhere that has seen my creativity, skills, and way of thinking, and has an opportunity for me to discover entirely new things to work on. (And I find that so exciting I forget all about XAML and someone else can lead the charge to make things better.)


I'm also torn because despite having worked with these technologies for so long, I'm wondering: if this is an ecosystem where no one else is even thinking that things could be better while admitting that they're bad, do I want to keep working with these technologies?

I have the tools (and now the language) I've always wanted to work with these technologies and build native (mobile & desktop) apps. Part of me would be happy to keep them around while I have side projects that benefit from them. If I get work in a different industry and no one is interested in taking them forward, it won't have been a complete waste of my time.




Don't Clap (for me)


I ended with the "DON'T CLAP" slide I have included above.

It's easy to treat clapping as the recognition of the end of something and then mentally switch to something else. I didn't (and don't) want me talking about this topic to be a temporary distraction or a momentary diversion only for everyone to go back to things as they were. I wanted (and still want) this to be the start of a discussion about how things can improve.

I don't have and can't provide all the answers. You're probably much smarter than me. I want to know your thoughts on this subject. Ok, you may still be taking in some of these ideas, but once you have thoughts, please share.



Yes, this is your prompt to leave a comment with your thoughts before you leave. 😃

If you don't want to (or can't) comment here, you can reach me via most social networks.


0 comments:

Post a Comment

I get a lot of comment spam :( - moderation may take a while.