Introduction
WPF most thrilling was probably the Binding concept, its now kind of standard in many other client frameworks (like Angular ??)
Anyway like every other good thing its came with a price, like worse performance and severe debugging.
In UWP Microsoft announce X:Bind –the new Binding concept who works in parallel path to old Binding concept, and supposed to leverage the performance, the Debugging, and to simplify things.
However, a lots has changed from Binding to x:Bind.
In this post I will facing off those two tremendous technics by syntax, concepts, performance, debugging , features, and whatever I can provide you.
Behind the hood
As for me, The first thing that came out is ‘what the hell is x:Bind’
I mean Binding it’s a .NET class, so you can override it, inherit it, etc. But (from MSDN)
{x:Bind} is a markup extension only, with no way to create or manipulate such bindings programmatically. For more info about markup extensions..,
In other words , xBind is new generation of markupExtension, so it is not an available class.
also be aware that Markup extension changed from WPF when they was actually a class that Binding and things like StaticResources was inherits from MarkupExtension Type.
Therefore Binding itself is actually new Type of Windows.UI.Xaml.Data namespace. Which is kind of preserve the concept of WPF binding.
x:Bind & Binding Default behavior
xBind can bind to private fields ! not just to public properties as Binding does, xBind default mode is onetime ,( you probably like to override it in your xaml code). while binding is two-way, also new ‘BindBack’ feature allow to bind UI field with two properties at the model in the same time.
xBind does not use dataContext.Properties, but with fields/properties/functions at c# partial class,
(for WPF programmers it’s like setting : DataContext=this;)
Binding by default use Source property, and source property is by default relay on DataContext property which is by default Null, meaning using binding without setting the source will do nothing.
Binding not support for functions directly but to properties only,
Commands are well known for those who ever deals with WPF, but with xBind we have some optional solutions for actions binding, we can bound for clicks (or other routed events) directly to functions, with some rules, if you using click event to bound function must be without arguments or similar to sender/args original Click routedEvent handler function, but even more, xBind allow to bind standard UI Field (text, colors, etc..) to functions, and here its could be even with parameters functions ! or even for two functions together (using the bindBack keyword).
x:Bind and INotifyPropertyChanged
Programmers that using binding well knows this interface, and it remain a player in xBind, however xBind present new technic called Bindings.Update, In old binding (WPF style) every part of data when it get changed from model and we want to refresh the view, we must fire an PropertyChanged event (xaml binding where listening for it behind the scene.)
Its nice and easy, but its lead to extra classes with very long properties schema, now the model/viewModel class can stay just a class, you don’t need to change anything in your model classes or even considering binding support. The only need is two words `Bindings.Update` (yet need to find trigger for calling this method).
x:Bind vs Binding in DataTemplates
Binding can use in verity of DataTemplates, since binding compiled at runtime with reflection they vary elastic and forgiving about programmer mistakes. We can use Binding for few hierarchical types together etc.. But xBind has a restrictions,
x:DataType directive is must, also its very convenient in local xaml file resources and quite difficult at global resource files,
since x:bind actually used codeBehind items to evaluate the data, and DataTemplates by their nature are template for presenting something that not exactly exist for now, its only a pattern for hoe to present Data-item, so again x:bind looks for CodeBehind, and DataTemplate is a virtual xaml that rise at runtime.
But the real Q is if necessary to use it, so its yes if you want to spare Commands, or bind Functions or like benefit the pre compile validation of the syntax (xBind check your syntax of Properties types etc.) but among the other achievements, xBind provide better performance, (will discussed later) so is it while using DataTemplates either ?
So I will compare 3 things – loading time, CPU, memory.
To emphasize – I am using xBind as Datasource fro the collection anyway,
<GridView ItemsSource="{x:Bind Persons}" />
just compare the Datatemplate internal implementation.
<DataTemplate x:Key="localPersonTemplatexBind" x:DataType="local:Person">
<StackPanel Background="Red">
<TextBlock Text="{x:Bind Id}" />
<TextBlock Text="{x:Bind Name}" />
<TextBlock Text="{x:Bind Age}" />
</StackPanel>
</DataTemplate>
Or,
<DataTemplate x:Key="localPersonTemplateBinding" x:DataType="local:Person">
<StackPanel Background="Azure">
<TextBlock Text="{Binding Id}" />
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Age}" />
</StackPanel>
</DataTemplate>
So, for Binding DataTemplate:
Loading time : 4.00 – 4.6 sec.
CPU on idle : 0.
CPU on extreme : 20 approx.
RAM on idle : 85.
RAM on extreme : 85.
So, for xBind DataTemplate:
Loading time : 3.9 – 4.3 sec.
CPU on idle : 0.
CPU on extreme : 20 approx.
RAM on idle : 78.
RAM on extreme : 78.
So, Not a quite Shocking yet surprising.. x:Bind affecting the loading time and about 10 perc. Of the memory.. ( * e.g. for individual machine..).
x:Bind vs Binding in performance
after former interesting Datatemplates digging, lets have another swipe on performance. Even that we focused on UWP I cant missed the opportunity to compare against WPF either.
The bench of this application compare is 2000 items in list (with simple template) in release mode.
Wpf start time: 3.6- 3.7.
Wpf on idle - cpu: 0 , ram : 93.
Wpf on mouse over - cpu : 15-20, ram: 94.
Wpf on extreme: cpu 20-30 , ram 130.
Uwp Binding start time: 1.2- 2.
Uwp Binding on idle - cpu: 0 , ram : 32-36 .
Uwp Binding on mouse over - cpu : 4.5, ram: 32-36.
Uwp Binding on extreme: cpu 20-35 , ram 48.
Uwp x:Bind start time: 0.5- 1.0.
Uwp x:Bind on idle - cpu: 0 , ram 20.
Uwp x:Bind on mouse over - cpu : 4-5, ram: 21.
Uwp x:Bind on extreme: cpu 10-20 , ram 38.
So WUP is better than WPF, and xBind better than Binding.
How? And why ?
Well, first Universal application are better since they are without connection to binding, its about the new application architecture and the OS itself.
When it comes to Binding itself, obviously Binding use reflection and X:Bind just execute the generated well compiled code, and its type safe so its faster.
In addition, xBind forces you to write better and well carefully code,
to be honest I dislike this method but I do like the result. For example:
no more Relative traverses over the Visual-Tree as Binding can do,
no more default Bind mode (direction and update) the Binding mode must be specify explicitly & so on..
you can download a full application Demo of the Performance in this post.
x:Bind with methods & events
Back to the start, Xbind allow us to directly binding Events to Functions which is awesome, it just downgrade the Command pattern , Binding of course just can’t . there is no restriction about binding to method, you can bind with arguments, to return value etc. & of course the default EventHandler signature with default parameter or without.
For example:
<VariableSizedWrapGrid>
<Button Content="click to void method" Click="{x:Bind Foo, Mode=OneWay}" />
<Button Content="double method with args" Width="{x:Bind Foo2(100),Mode=OneWay}"/>
<Button Content="sting method" ToolTipService.ToolTip="{x:Bind Foo3(),Mode=OneWay}" />
<Button Content="Event pointer enterd method" PointerEntered="{x:Bind Foo4}" />
</VariableSizedWrapGrid>
private void Foo()
{
}
private double Foo2(int val)
{
return val+100;
}
private string Foo3()
{
return "Hello";
}
private void Foo4(object sender, PointerRoutedEventArgs e)
{
}
Debugging & validate x:Bind
Validation - xBing use precompile internal validation, so can spare some runtime failures, also might lead to better and efficient code, for example, use Two-Way bindings while one of the endpoints is missing converter will cased to compile time error and can avoid from runtime errors.
Debugging,
for FED developers who working with markup languages, debug the UI level can be hard task to accomplish, for example if the value doesn’t arrived properly to view we use external tools or writing debug components.. xBind just made iteasier, the markup binding generate reading file and we can debug through
xBind & MVVM architecture
Years ago when MVC/MVVM become a popular programmers easy thrilling, we use to separate everything to small units, those small units together orchestrate the application building blocks,It where start with small views , view-models (no matter if View first or view-model first), services, data-templates also where separate into quarantine areas, styles & templates could even store at different assembly and so on.
Now, its all change a little, but in general all the same.
XBind (if you choose to use it) like to see everything in close distance, like DataTemplates at same file and Xbind properties at the partial *.cs File, to be honest I like it, and you can think of it as an Angular Component if you familiar with,
MVVM View-First: nothing has changed but instead of DataContext we using *ViewModel instance at the Partial *.cs file (codeBehind) and bind our xaml fields to VM.Properties and so on,
MVVM View-First: more problematic, yet you could do it as the following Example:
View xaml file:
<Grid Background="LightBlue">
<ContentControl Content="{x:Bind VM}" ContentTemplate="{StaticResource itemServieTemplate}"/>
</Grid>
View.cs file:
public sealed partial class MainPage : Page
{
public ItemsServiceViewModel VM
{
get; set;
}
public MainPage()
{
VM = new ItemsServiceViewModel();
this.InitializeComponent();
}
}
App.xaml- Datatemplates:
<ResourceDictionary>
<!--
<DataTemplate x:Key="z" x:DataType="local:ItemViewModel">
<StackPanel>
<TextBlock Text="fds" />
<TextBlock Text="{x:Bind Title}"/>
<TextBlock Text="{x:Bind ItemCategory}"/>
</StackPanel>
</DataTemplate>
<!--
<DataTemplate x:Key="itemServieTemplate" x:DataType="local:ItemsServiceViewModel">
<Grid Background="LightGreen" BorderBrush="Black" BorderThickness="3">
<ListBox ItemsSource="{x:Bind Items,Mode=OneWay}" ItemTemplate="{StaticResource z}" />
<Button VerticalAlignment="Bottom" Content="Add Item Test" Click="{x:Bind AddItem}"/>
</Grid>
</DataTemplate>
</ResourceDictionary>
ViewModels :
public class ItemViewModel : ViewModelBase
{
public ItemViewModel(Item _model)
{
Model = _model;
}
private Item model;
public Item Model
{
get { return model; }
set
{
model = value;
Notify();
}
}
public string Title { get { return model.Title; } }
public Category ItemCategory { get { return model.ItemCategory; } }
public class ItemsServiceViewModel : ViewModelBase
{
public ObservableCollection<ItemViewModel> Items
{
get; set;
}
public void AddItem()
{
ItemViewModel newItem = new ItemViewModel(new Item("^^", Category.Food));
Items.AddItem(newItem.Model);
}
}
Model:
public enum Category
{
Food = 1,
Music = 2
}
public class Item
{
public Item( string titile , Category cat)
{
Title = titile;
ItemCategory = cat;
}
public string Title { get; set; }
public Category ItemCategory { get; set; }
}