Introduction
Miguel tweeted:
"I should have never added Xaml and instead invented our own ...", expressing regrets about having to deal with XAML (standardization) problems.
My response was:
"I would applaud dropping XAML altogether. Advancements in C# (declarative syntax) have eliminated any advantages of a separate markup language for years. Why would you want to hand-code an object serialization format? Why waste time on duplicating dev tools for features that c# already offers?"
David expressed an interest to see how I have been creating Xamarin Forms markup in declarative style C#, instead of in XAML, for the past few years. So I write this post to provide a concrete example, and share the reasoning behind my remark (which was deliberately lacking nuance - it is Twitter after all).
Redirecting Xamarin IDE team effort
Why do I spend time on this? In the past years I only experienced advantages from using declarative C# instead of XAML. Given that the core challenge for the Xamarin IDE teams remains to improve the developer productivity, I would love to see some of the effort now being spent on (imo redundant) XAML tooling to be redirected towards reducing IDE bugs and speeding up the dev cycle, i.e. Live Player.
I recently investigated Google's Flutter (build beautiful native apps in record time), which by design has no separate language for markup and which offers hot reload - which is like a Xamarin Live Player without any limitations and a refresh time of 400-600 ms (I checked on devices and emulators). This is what I want from Xamarin!
This is the competition Xamarin is facing today. Some developers are already switching from Xamarin to Flutter because of developer tooling productivity, which apparently can be more important than language or framework or experience. As a Xamarin veteran, I get why they do this. I feel that unless there is a significant team increase, Xamarin needs to focus and redirect existing effort towards developer productivity, meaning less IDE bugs and faster development cycle.
Example
.
Here is an unabridged example of a simple registration code page in a production app I wrote:
Content = new Grid {
RowSpacing = 0,
RowDefinitions = { new RowDefinition { Height = GridLength.Auto }, new RowDefinition {}},
Children = {
PageHeader.Create(PageMarginSize, nameof(vm.RegistrationTitle), returnToPreviousViewCommandPropertyName: nameof(vm.CancelEnterRegistrationCodeCommand), centerTitle:true),
new ScrollView { Content = new Grid {
RowDefinitions = {
new RowDefinition { Height = 170 },
new RowDefinition { Height = 75 },
new RowDefinition { Height = GridLength.Auto },
new RowDefinition { Height = GridLength.Auto }
},
RowSpacing = 0,
ColumnDefinitions = {
new ColumnDefinition { Width = 160 },
new ColumnDefinition { }
},
Children = {
new Label {
Margin = fieldNameMargin, LineBreakMode = LineBreakMode.WordWrap,
HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.Center, HorizontalTextAlignment = TextAlignment.Center,
}.SetFontSize(WspFontSizes.Size15)
.SetColRow(0, 2, 0, 1)
.Bind(nameof(vm.RegistrationPrompt)),
new Label { Text = "Registration code", VerticalOptions = LayoutOptions.End, Margin = fieldNameMargin }.SetFontSize(WspFontSizes.Size13)
.SetColRow(0, 1, 1, 2),
new Label { HorizontalOptions = LayoutOptions.End, VerticalOptions = LayoutOptions.End, Margin = fieldNameMargin }.SetFontSize(WspFontSizes.Size13)
.SetColRow(1, 2, 1, 2)
.Bind(nameof(vm.RegistrationCodeValidationMessage)),
new Entry {
Placeholder = "E.g. 123456", HeightRequest = 44, Keyboard = Keyboard.Numeric,
BackgroundColor = WspColors.White.ToColor(), TextColor = WspColors.Gray1.ToColor(), Margin = fieldMargin }.SetFontSize(WspFontSizes.Size15)
.Bind(nameof(vm.RegistrationCode), BindingMode.TwoWay)
.Id(AId.RegistrationCodePage_CodeEntry)
.SetColRow(0, 2, 2, 3),
new Button {
Text = "Verify",
Margin = PageMarginSize,
HeightRequest = 44,
HorizontalOptions = LayoutOptions.FillAndExpand,
TextColor = WspColors.White.ToColor(),
BackgroundColor = WspColors.ColorValueAccent.ToColor()
}.SetFontSize(WspFontSizes.Size13)
.Id(AId.RegistrationCodePage_VerifyCodeButton)
.Bind(Button.IsVisibleProperty, nameof(vm.CanVerifyRegistrationCode))
.Bind(nameof(vm.VerifyRegistrationCodeCommand))
.SetColRow(0, 2, 3, 4),
}
}}.SetColRow(0, 1)
}
};
Nothing advanced is going on here, I use standard C# language features to reuse controls (e.g. PageHeader.Create method ) and to simplify data binding (.Bind extension methods). In my eyes the above reads similar to equivalent XAML.
Which is not very surprising given that XAML is at its heart just an object serialization format in XML. In other words, XAML does what the new keyword in C# does.
Now, C# is designed for humans; while XML is better for tools such as visual designers. As a matter of fact, that was the vision for (WPF) XAML: that human designers could use a tool (Blend) to create a UI that developers could consume. However, I experienced how that vision, even in the best possible time and scenario, failed to deliver (I Built a WPF app for Windows tablet together with a XAML book authoring, leading designer, who was a master in Blend, when that was THE tool. The UI was beautiful and totally unmaintainable). So even if there would come an ultimate visual designer tool for Xamarin Forms, equivalent to the best that Blend ever was, it would still fail for the same reasons. Time to move on, like Flutter?
So, anyone (Xamarin devs and Xamarin team) wants to chime in on either XAML versus C# or redirecting Xamarin IDE efforts?
I'm really curious how Xamarin devs (especially experienced ones) see this.
Thanks!