x:Bind 中的函数

注释

有关在应用中使用数据绑定与 {x:Bind} 配合的常规信息(以及有关 {x:Bind}{Binding}之间的全面比较),请参阅 深入的数据绑定{x:Bind} 的标记扩展

从 Windows 10 版本 1607 开始,{x:Bind} 支持将函数用作绑定路径的末端步骤。 这使得:

  • 实现值转换的更简单方法
  • 一种让绑定依赖于多个参数的方法

注释

要使用带有 {x:Bind}的函数,您的应用程序的最低目标 SDK 版本必须为 14393 或更高。 当应用面向早期版本的 Windows 10 时,无法使用函数。 有关目标版本的详细信息,请参阅 版本自适应代码

在以下示例中,项的背景和前景被绑定到用于颜色参数转换的函数上。

<DataTemplate x:DataType="local:ColorEntry">
    <Grid Background="{x:Bind local:ColorEntry.Brushify(Color), Mode=OneWay}" Width="240">
        <TextBlock Text="{x:Bind ColorName}" Foreground="{x:Bind TextColor(Color)}" Margin="10,5" />
    </Grid>
</DataTemplate>
class ColorEntry
{
    public string ColorName { get; set; }
    public Color Color { get; set; }

    public static SolidColorBrush Brushify(Color c)
    {
        return new SolidColorBrush(c);
    }

    public SolidColorBrush TextColor(Color c)
    {
        return new SolidColorBrush(((c.R * 0.299 + c.G * 0.587 + c.B * 0.114) > 150) ? Colors.Black : Colors.White);
    }
}

XAML 属性用法

<object property="{x:Bind pathToFunction.FunctionName(functionParameter1, functionParameter2, ...), bindingProperties}" ... />

函数的路径

函数 的 路径与其他属性路径指定方式相同,可以包含 (.),索引器类型转换 以定位函数。

可以使用 XMLNamespace:ClassName.MethodName 语法指定静态函数。 例如,使用以下语法在后台代码中绑定静态函数。

<Page 
     xmlns:local="using:MyNamespace">
     ...
    <StackPanel>
        <TextBlock x:Name="BigTextBlock" FontSize="20" Text="Big text" />
        <TextBlock FontSize="{x:Bind local:MyHelpers.Half(BigTextBlock.FontSize)}" 
                   Text="Small text" />
    </StackPanel>
</Page>
namespace MyNamespace
{
    static public class MyHelpers
    {
        public static double Half(double value) => value / 2.0;
    }
}

还可以直接在标记中使用系统函数,用于实现日期格式、文本格式、文本串联等简单操作,例如:

<Page 
     xmlns:sys="using:System"
     xmlns:local="using:MyNamespace">
     ...
     <CalendarDatePicker Date="{x:Bind sys:DateTime.Parse(TextBlock1.Text)}" />
     <TextBlock Text="{x:Bind sys:String.Format('{0} is now available in {1}', local:MyPage.personName, local:MyPage.location)}" />
</Page>

如果模式为 OneWay/TwoWay,则将对函数路径进行更改检测,如果这些对象发生更改,绑定将被重新评估。

要绑定到的函数需要:

  • 代码和元数据可以访问 - 因此,内部/私有工作使用 C#,而 C++/CX 需要公共 WinRT 方法。
  • 重载基于参数的数量,而不是类型,它将尝试与具有相同数量参数的第一个重载匹配。
  • 参数类型需要匹配传入的数据 - 我们不会缩小转换范围
  • 函数的返回类型需要匹配使用绑定的属性的类型

绑定引擎对使用函数名称触发的属性更改通知做出反应,并根据需要重新评估绑定。 例如:

<DataTemplate x:DataType="local:Person">
   <StackPanel>
      <TextBlock Text="{x:Bind FullName}" />
      <Image Source="{x:Bind IconToBitmap(Icon, CancellationToken), Mode=OneWay}" />
   </StackPanel>
</DataTemplate>
public class Person : INotifyPropertyChanged
{
    //Implementation for an Icon property and a CancellationToken property with PropertyChanged notifications
    ...

    //IconToBitmap function is essentially a multi binding converter between several options.
    public Uri IconToBitmap (Uri icon, Uri cancellationToken)
    {
        Uri foo = new Uri(...);        
        if (isCancelled)
        {
            foo = cancellationToken;
        }
        else 
        {
            if (this.fullName.Contains("Sr"))
            {
               //pass a different Uri back
               foo = new Uri(...);
            }
            else
            {
                foo = icon;
            }
        }
        return foo;
    }

    //Ensure FullName property handles change notification on itself as well as IconToBitmap since the function uses it
    public string FullName
    {
        get { return this.fullName; }
        set
        {
            this.fullName = value;
            this.OnPropertyChanged ();
            this.OnPropertyChanged ("IconToBitmap"); 
            //this ensures Image.Source binding re-evaluates when FullName changes in addition to Icon and CancellationToken
        }
    }
}

小窍门

可以使用 x:Bind 中的函数来达到与 WPF 中的转换器和 MultiBinding 所支持的相同功能或场景。

函数参数

可以指定多个函数参数,用逗号 (,) 分隔

  • 绑定路径 – 与直接绑定到该对象的语法相同。
    • 如果模式为 OneWay 或 TwoWay,系统将在对象更改时执行更改检测,并重新评估绑定。
  • 括在引号中的常量字符串 – 需要用引号将其指定为字符串。 Hat (^) 可用于转义字符串中的引号
  • 常量数 - 例如 -123.456
  • 布尔值 – 指定为“x:True”或“x:False”

小窍门

TargetNullValue 将应用于函数调用的结果,不适用于任何绑定参数。

双向函数绑定

在双向绑定方案中,必须为绑定的反向方向指定第二个函数。 这是通过使用 BindBack 绑定属性来完成的。 在下面的示例中,该函数应采用一个参数,即需要推送回模型的值。

<TextBlock Text="{x:Bind a.MyFunc(b), BindBack=a.MyFunc2, Mode=TwoWay}" />

另请参阅