Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding an event to a method, why does it work in UWP?

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 :

enter image description here

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 ?

like image 380
AymenDaoudi Avatar asked Feb 03 '16 21:02

AymenDaoudi


2 Answers

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:

  1. Match the signature of the event.
  2. OR have no parameters.
  3. OR have the same number of parameters of types that are assignable from the types of the event parameters.

I guess your scenario perfectly match item 2.

like image 112
Jackie Avatar answered Sep 28 '22 06:09

Jackie


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.

like image 20
Clemens Avatar answered Sep 28 '22 05:09

Clemens