Compartir a través de


Funciones en x:Bind con el SDK de aplicaciones para Windows

Nota

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

En las aplicaciones del SDK de Windows App, {x: Bind} admite el uso de una función como el paso hoja de la ruta de acceso de enlace. Esto permite lo siguiente:

  • Lograr la conversión de valores de una forma más sencilla
  • Obtener una manera de que los enlaces dependan de más de un parámetro

En el siguiente ejemplo, el primer y segundo planos del elemento están enlazados a las funciones dedicadas a realizar la conversión según el 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 del atributo XAML

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

Ruta de acceso a la función

La ruta de acceso a la función se especifica como otras tantas rutas de acceso de propiedades y puede incluir puntos (.), indexadores o conversiones para localizar la función.

Las funciones estáticas pueden especificarse mediante la sintaxis XMLNamespace:ClassName.MethodName. Por ejemplo, usa la sintaxis siguiente para enlazar a funciones estáticas en el 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;
    }
}

También puede usar funciones del sistema directamente en el marcado para crear escenarios sencillos, como el formato de fecha, el formato de texto, las concatenaciones de texto, etc. 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 el modo es OneWay/TwoWay, se cambiará el proceso de detección realizado en la ruta de acceso de la función y se volverá a evaluar el enlace si se realizaron cambios en esos objetos.

La función a enlazar debe tener en cuenta lo siguiente:

  • Debe ser accesible al código y a los metadatos, por lo que los métodos internos o privados funcionan en C#, pero C++ necesita métodos públicos de WinRT
  • La sobrecarga debe basarse en el número de argumentos, no en el tipo; se intentará hacer coincidir la primera sobrecarga con el número de argumentos que haya.
  • Los tipos de argumento deben coincidir con los datos que se pasan; no se realizan conversiones de restricción.
  • El tipo de devolución de la función debe coincidir con el tipo de propiedad que está usando el enlace.

El motor de enlace reacciona a las notificaciones de cambio de propiedad que se activan 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

Puede usar las funciones de x:Bind para lograr los mismos escenarios que se consiguen con convertidores y enlace múltiple en WPF.

Argumentos de función

Se pueden especificar varios argumentos de función separados por comas (,)

  • Ruta de acceso: debe tener la misma sintaxis que al enlazar directamente con el objeto.
    • Si el modo es OneWay/TwoWay, se realizará la detección de cambios y se volverá a evaluar el enlace en cuanto cambien los objetos.
  • La cadena de la constante debe estar entre comillas: es necesario usar las comillas para designarla como una cadena. Asimismo, puedes usar el acento circunflejo (^) para evitar las comillas de las cadenas.
  • Número de constante: por ejemplo, -123.456.
  • Elemento booleano: especificado como "x:True" o "x:False".

Enlaces de funciones bidireccionales

En un escenario con un enlace bidireccional, es necesario especificar una segunda función para la dirección inversa del enlace. Esto se hace mediante la propiedad de enlace BindBack. En el ejemplo siguiente, la función debe tomar un argumento que sea el valor que se debe devolver al modelo.

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

Consulte también