Compartir a través de


Funciones en x:Bind con WinUI

Las aplicaciones WinUI permiten usar funciones como paso final de la ruta de acceso de enlace de datos en la {x:Bind} extensión de marcado. Esta característica simplifica la conversión de valores y permite que los enlaces dependan de varios parámetros, lo que hace que la aplicación sea más dinámica y eficaz.

Sugerencia

Para obtener información general sobre el uso del enlace de datos en tu aplicación con {x:Bind} (y para una comparación exhaustiva entre {x:Bind} y {Binding}), consulta Enlace de datos en profundidad y {x:Bind} Extensión de marcado.

En el ejemplo siguiente, el fondo y el primer plano del elemento están enlazados a funciones que realizan la conversión en función del parámetro de color.

<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>
public 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);
    }
}

Uso de atributos XAML

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

Ruta de acceso a la función

Especifique la ruta de acceso a la función como otras rutas de acceso de propiedades. La ruta puede incluir puntos (.), indizadores o conversiones para localizar la función.

Use la XMLNamespace:ClassName.MethodName sintaxis para especificar funciones estáticas. Por ejemplo, use la siguiente sintaxis para enlazar a funciones estáticas en código subyacente.

<Window 
     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>
</Window>
namespace MyNamespace
{
    static public class MyHelpers
    {
        public static double Half(double value) => value / 2.0;
    }
}

Puede usar también funciones del sistema directamente en lenguajes de marcado para lograr escenarios sencillos, como el formato de fechas, el formato de texto, las concatenaciones de texto y más. Por ejemplo:

<Window 
     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)}" />
</Window>

Si establece el modo en OneWay o TwoWay, la ruta de acceso de la función admite la detección de cambios. El motor de enlace vuelve a evaluar el enlace si cambian esos objetos.

La función a la que estás vinculando necesita:

  • Ser accesible al código y a los metadatos, por lo que funciona como interno o privado en C#, pero C++ necesita que los métodos sean métodos públicos en WinRT.
  • Compatibilidad con la sobrecarga basada en el número de argumentos, no en el tipo, e intenta coincidir con la primera sobrecarga que tenga el mismo número de argumentos.
  • Asegúrese de que los tipos de argumentos coincidan con los datos que se están pasando: el motor de enlace no realiza conversiones de reducción.
  • Tener un tipo de valor devuelto que coincida con el tipo de la propiedad que utiliza la vinculación

El motor de enlace reacciona a las notificaciones de cambio de propiedad desencadenadas con el nombre de la función y vuelve a evaluar los enlaces según sea necesario. Por ejemplo:

<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)
    {
        var foo = new Uri(...);        
        if (isCancelled)
        {
            foo = cancellationToken;
        }
        else 
        {
            if (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 fullName; }
        set
        {
            fullName = value;
            OnPropertyChanged();
            OnPropertyChanged("IconToBitmap"); 
            //this ensures Image.Source binding re-evaluates when FullName changes in addition to Icon and CancellationToken
        }
    }
}

Sugerencia

Use funciones en x:Bind para lograr los mismos escenarios que aquellos admitidos a través de los Convertidores y MultiBinding en WPF.

Argumentos de función

Especifique varios argumentos de función separados por comas (,).

  • Ruta de enlace: use la misma sintaxis que si estuviera vinculando directamente a ese objeto.
    • Si establece el modo en OneWay o TwoWay, el enlace detecta los cambios y vuelve a evaluar cuándo cambia el objeto.
  • Cadena constante entre comillas: incluya comillas para designarla como una cadena. Use el sombrero (^) para escapar comillas en cadenas.
  • Número constante: por ejemplo, -123.456.
  • Boolean: especifique como "x:True" o "x:False".

Sugerencia

TargetNullValue se aplica al resultado de la llamada de función, no a ningún argumento enlazado.

Enlaces de funciones bidireccionales

En un escenario de enlace bidireccional, debe especificar una segunda función para la dirección inversa del enlace. Use la BindBack propiedad de enlace para esta función. En el ejemplo siguiente, la función toma un argumento, que es el valor que se debe devolver al modelo.

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

Consulte también