Since the early days of WPF (Windows Presentation Foundation) on Windows Vista, XAML (eXtensible Application Markup Language) has been the primary way to do UI layout in .NET for desktop, Silverlight, Windows Phone, and Xamarin Forms. XAML is an XML representation of a .NET object, most commonly used to represent the user interface. XAML is still available in .NET MAUI, and is a first class citizen for creating UI, with all the data binding support and commands you are used to.
Since the beginning, it has been possible to write UI for XAML based application frameworks using code instead of a XAML file. You would do this by basically writing the code that gets generated when the XAML is compiled, but doing that by hand. I have worked with customers who have done this, especially in the early days of Xamarin Forms when the XAML editor was very bare bones, and at first the XAML wasn’t even compiled, so there were good reasons to do that.
The problem is that the code is very verbose to replicate what is done pretty concisely in XAML layout, and it is also very hard to get a mental picture of the structure of the layout from looking through this code. On top of this, if you want to do data binding in code, it gets even more verbose. Here is some very simple XAML represented in code:
var label = new Label { Text = "Hello from Xamarin Forms", VerticalOptions = LayoutOptions.CenterAndExpand };
var button = new Button {Text = "Click Me", VerticalOptions = LayoutOptions.CenterAndExpand };
var entry = new Entry {Placeholder = "Enter some text", VerticalOptions = LayoutOptions.CenterAndExpand };
var datePicker = new DatePicker { VerticalOptions = LayoutOptions.CenterAndExpand };
MainPage = new ContentPage { Content = new StackLayout { Children = { label, button, entry, datePicker}}};
Pretty awful, right? Things got better in Xamarin Forms 4.6, where C# Markup for Xamarin Forms was introduced. It lets us define layout like this:
using Xamarin.Forms.Markup;
public partial class SearchPage
{
void Build() => Content =
new StackLayout { Children = {
Header,
SearchResults,
Footer
}};
StackLayout Header => new StackLayout { };
CollectionView SearchResults => new CollectionView { };
Label Footer => new Label { };
}
So much easier to read, and understand the structure of the page. MAUI builds on top of this, and introduces a new design pattern to help write UIs in code. So why a new pattern?
The first version of XAML was released in 2006, almost 15 years ago. Actually, it will be almost exactly 15 years old when MAUI is released. So many new frameworks have come and gone since then, and many different attempts at the best way to create your user interface. XAML hasn’t changed too much over these years, except for maybe the introduction of compiled data bindings, which certainly was a big performance and syntax checking improvement, but it’s hard to think of any other major ground breaking changes. There is also a pretty big learning curve to get good at XAML, especially in Xamarin Forms with the lack of a visual designer for editing XAML. Now don’t get me wrong, I love XAML, and it’s impressive that it’s held up as well as it has over the years.
One of the UI patterns that has gained popularity is the Model View Update (MVU) pattern (also called the Elm Architecture based on where it first gained popularity), and variations on this. Now I don’t want to get into semantics about what is or isn’t an MVU pattern, and there has been some heated discussion around MAUI about whether what is being implemented is actually MVU or not, but that’s what the MAUI team is calling it, so I’m going with the naming they use. I have done a lot of ReactJS lately, and from what I see of what the MVU pattern is, there are a lot of similarities. Also I understand that Flutter (Google’s cross platform framework for apps) uses MVU extensively.
Since I’m really just starting out getting familiar with this pattern, I am not going to try to explain it, there are much better places to learn about it from people who have been immersed in it for a while. My goal here is more to make you aware of it, and I’ll post more in the future about it as I learn more.
There are actually two MVU implementations coming in MAUI. The C# implementation is based on Comet, and the F# implementation is based on Fabulous. For more about MVU in MAUI and C#, here is a presentation by the creator of Comet.
Here is an example of some Comet code:
public class MyPage : View {
readonly State<int> clickCount = new State<int> (1);
public MyPage() {
Body = () => new VStack {
new Text (() => $"Click Count: {clickCount}"),
new Button("Update Text", () => {
clickCount.Value++;
}
};
}
}
For those that are coming to MAUI without XAML and MVVM experience, this seems like it will have a smaller learning curve, especially if the developers are already familiar with an MVU-like framework. I have seen recommendations to separate state from the view using partial classes to provide some separation of concerns instead of lumping everything into the file with layout, and I am sure we will see some best practices evolve around this.
The main takeaway from this post is that XAML and MVVM are still completely supported, and will continue to be. I welcome this alternative option and I’m excited to dig into it further, choice is a good thing.
Thanks for the article.
The MVU pattern looks very similar to the Windows form (20 years old) pattern.
Splitting the view and logic with two separate code files (in winforms one was C# generated by the designer).
XAML has the great advantage of enforcing separation of the logic and view by using a presentation language, that is compiled and different from C#.
In my experience I already seen so many people misusing MVVM by creeping logic code in the code behind of their view. and some doing the other extreme by disallowing any code in the code behind. MVVM is a good middle ground that allows designers to work with XAML designers, without having to know C#, allowing to view and modify the UI at design time without running the app or being connected to the network (Design time View Model).
UI are looking all the same because Designers are more and more forced into frameworks that require too much programming knowledge.
There’s another implementation of MVU, works with XF 5 and C#: https://github.com/shirshov/laconic (I’m the author)