Поделиться через


Функции в 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 для достижения тех же сценариев, что и с помощью преобразователей и MultiBinding в WPF.

Аргументы функции

Можно указать несколько аргументов функции, разделенных запятыми (,)

  • Путь привязки — тот же синтаксис, что и при привязке непосредственно к объекту.
    • Если режим — OneWay/TwoWay, то будет выполнено обнаружение изменений, а привязка повторно оценивается при изменении объекта.
  • Константная строка, заключаемая в кавычки, — кавычки необходимы, чтобы обозначить ее как строку. Hat (^) можно использовать для экранирования кавычек в строках
  • Константное число , например -123.456
  • Булевое значение — указанное как "x:True" или "x:False"

Подсказка

TargetNullValue применяется к результату вызова функции, а не к связанным аргументам.

Двустороновые привязки функций

В двустороннем сценарии привязки вторая функция должна быть указана для обратного направления привязки. Это делается с помощью свойства привязки BindBack. В приведенном ниже примере функция должна принимать один аргумент, который является значением, которое необходимо отправить обратно в модель.

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

См. также