将事件绑定到方法,为什么在UWP中有效?
Binding an event to a method, why does it work in UWP?
UWP
带来了 DataBinding
、Compiled Binding
的新方式,使用 {x:Bind}
标记扩展,当我发现这个新功能时,我发现我们实际上可以将事件绑定到方法!
示例:
Xaml :
<Grid>
<Button Click="{x:Bind Run}" Content="{x:Bind ButtonText}"></Button>
</Grid>
代码隐藏:
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();
}
结果:
并且由于 {x:Bind} 绑定是在运行时评估的,并且编译器会生成一些表示该绑定的文件,所以我去那里调查发生了什么,所以在 MainPage.g.cs 文件中(MainPage 是有问题的 xaml 文件)我发现了这个:
// 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 official documentation for {x:Bind} 确实提到了这个新功能,但没有解释非依赖性 属性 为什么以及如何成为绑定的目标,有人对此有深入的解释吗?
嗯,这是 "x:Bind" 编译绑定的新功能。
https://msdn.microsoft.com/en-us/library/windows/apps/mt204783.aspx
事件绑定是编译绑定的新功能。它使您能够使用绑定指定事件的处理程序,而不必是代码背后的方法。例如:Click="{x:Bind rootFrame.GoForward}".
对于事件,目标方法不得重载并且还必须:
- 匹配事件的签名。
- OR 没有参数。
- 或者具有相同数量的可从事件参数类型分配的类型参数。
我猜你的场景完全符合第 2 项。
A binding target should be a dependency property
虽然这适用于常规绑定,但不适用于 {x:Bind}
标记扩展。
所以你实际上可以有一个非依赖性 属性 就像
public sealed partial class MyUserControl : UserControl
{
public Color BackgroundColor
{
get { return ((SolidColorBrush)Background).Color; }
set { Background = new SolidColorBrush(value); }
}
}
作为这样的 {x:Bind}
目标:
<local:MyUserControl BackgroundColor="{x:Bind ViewModel.BgColor}" />
同时
<local:MyUserControl BackgroundColor="{Binding ViewModel.BgColor}" />
会失败。
UWP
带来了 DataBinding
、Compiled Binding
的新方式,使用 {x:Bind}
标记扩展,当我发现这个新功能时,我发现我们实际上可以将事件绑定到方法!
示例:
Xaml :
<Grid>
<Button Click="{x:Bind Run}" Content="{x:Bind ButtonText}"></Button>
</Grid>
代码隐藏:
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();
}
结果:
并且由于 {x:Bind} 绑定是在运行时评估的,并且编译器会生成一些表示该绑定的文件,所以我去那里调查发生了什么,所以在 MainPage.g.cs 文件中(MainPage 是有问题的 xaml 文件)我发现了这个:
// 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 official documentation for {x:Bind} 确实提到了这个新功能,但没有解释非依赖性 属性 为什么以及如何成为绑定的目标,有人对此有深入的解释吗?
嗯,这是 "x:Bind" 编译绑定的新功能。
https://msdn.microsoft.com/en-us/library/windows/apps/mt204783.aspx
事件绑定是编译绑定的新功能。它使您能够使用绑定指定事件的处理程序,而不必是代码背后的方法。例如:Click="{x:Bind rootFrame.GoForward}".
对于事件,目标方法不得重载并且还必须:
- 匹配事件的签名。
- OR 没有参数。
- 或者具有相同数量的可从事件参数类型分配的类型参数。
我猜你的场景完全符合第 2 项。
A binding target should be a dependency property
虽然这适用于常规绑定,但不适用于 {x:Bind}
标记扩展。
所以你实际上可以有一个非依赖性 属性 就像
public sealed partial class MyUserControl : UserControl
{
public Color BackgroundColor
{
get { return ((SolidColorBrush)Background).Color; }
set { Background = new SolidColorBrush(value); }
}
}
作为这样的 {x:Bind}
目标:
<local:MyUserControl BackgroundColor="{x:Bind ViewModel.BgColor}" />
同时
<local:MyUserControl BackgroundColor="{Binding ViewModel.BgColor}" />
会失败。