UWP
came with a new way of DataBinding
, Compiled Binding
, using the {x:Bind}
markup extension, when I was discovering this new feature, I found out that we can actually bind an event to a method !
Example :
Xaml :
<Grid>
<Button Click="{x:Bind Run}" Content="{x:Bind ButtonText}"></Button>
</Grid>
Code Behind :
private string _buttonText;
public string ButtonText
{
get { return _buttonText; }
set
{
_buttonText = value;
OnPropertyChanged();
}
}
public MainPage()
{
this.InitializeComponent();
ButtonText = "Click !";
}
public async void Run()
{
await new MessageDialog("Yeah the binding worked !!").ShowAsync();
}
The result :
And since {x:Bind} bindings are evaluated at runtime and the compiler generates some files that represent that binding, so I went there to investigate what's going on, so in the MainPage.g.cs file (MainPage is the xaml file in question) I found this :
// IComponentConnector
public void Connect(int connectionId, global::System.Object target)
{
switch(connectionId)
{
case 2:
this.obj2 = (global::Windows.UI.Xaml.Controls.Button)target;
((global::Windows.UI.Xaml.Controls.Button)target).Click += (global::System.Object param0, global::Windows.UI.Xaml.RoutedEventArgs param1) =>
{
this.dataRoot.Run();
};
break;
default:
break;
}
}
The compiler seems to know that it's a valid binding, moreover it creates the corresponding event handler, and it calls the concerned method inside.
That is great ! but why ?? A binding target should be a dependency property, not an event. The official documentation for {x:Bind} does mention this new feature, but doesn't explain why and how can a non dependency property be a target of binding, anyone who has a deep explanation for this ?
Well, it's sort of the new feature of the "x:Bind" compiled binding.
https://msdn.microsoft.com/en-us/library/windows/apps/mt204783.aspx
Event binding is a new feature for compiled binding. It enables you to specify the handler for an event using a binding, rather than it having to be a method on the code behind. For example: Click="{x:Bind rootFrame.GoForward}".
For events, the target method must not be overloaded and must also:
I guess your scenario perfectly match item 2.
A binding target should be a dependency property
While this is true for a regular binding, it does not hold for the {x:Bind}
markup extension.
So you can in fact have a non-dependency property like e.g.
public sealed partial class MyUserControl : UserControl
{
public Color BackgroundColor
{
get { return ((SolidColorBrush)Background).Color; }
set { Background = new SolidColorBrush(value); }
}
}
as an {x:Bind}
target like this:
<local:MyUserControl BackgroundColor="{x:Bind ViewModel.BgColor}" />
while
<local:MyUserControl BackgroundColor="{Binding ViewModel.BgColor}" />
would fail.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With