Funzioni in x:Bind

Nota

Per informazioni generali sull'uso del data binding nell'app con {x:Bind} (e per un confronto completo tra {x:Bind} e {Binding}), vedere Informazioni approfondite sul data binding e Estensione di markup {x:Bind}.

A partire da Windows 10 versione 1607, {x:Bind} supporta l'uso di una funzione come passaggio foglia del percorso di binding. Ciò permette:

  • Un modo più semplice per ottenere la conversione di valori
  • Di usare binding che dipendono da più parametri

Nota

Per usare funzioni con {x:Bind}, la versione minima dell'SDK di destinazione dell'app deve essere 14393 o successiva. Non puoi usare funzioni quando l'app è destinata alle versioni precedenti di Windows 10. Per altre info sulle versioni di destinazione, vedi Codice adattivo per la versione.

Nell'esempio seguente, lo sfondo e il primo piano dell'elemento sono associati a funzioni per la conversione in base al parametro del colore

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

Utilizzo attributo XAML

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

Percorso della funzione

Il percorso della funzione viene specificato come gli altri percorsi delle proprietà e può includere punti (.), indicizzatori o cast per localizzare la funzione.

Le funzioni statiche possono essere specificate usando la sintassi XMLNamespace:ClassName.MethodName. Usare, ad esempio, la sintassi seguente per l'associazione alle funzioni statiche in code-behind.

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

Puoi usare anche le funzioni di sistema direttamente nel markup per realizzare scenari semplici come la formattazione della data, la formattazione del testo, le concatenazioni di testo e così via. Ad esempio:

<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>

Se la modalità è OneWay/TwoWay, verrà eseguito il rilevamento delle modifiche sul percorso della funzione e il binding verrà valutato nuovamente in presenza di modifiche a tali oggetti.

Per la funzione oggetto del binding è necessario quanto segue:

  • Che sia accessibile al codice e ai metadati; i valori internal/private funzionano in C#, ma per C++/CX sarà necessario che i metodi siano metodi WinRT pubblici
  • L'overload si basa sul numero di argomenti, non sul tipo, e tenterà di trovare la corrispondenza con il primo overload con molti argomenti
  • I tipi di argomento devono corrispondere ai dati passati; non vengono eseguite conversioni verso un tipo di dati più piccolo
  • Il tipo restituito della funzione deve corrispondere al tipo della proprietà che usa il binding

Il motore di binding reagisce alle notifiche di modifica delle proprietà generate con il nome della funzione e valuta nuovamente le associazioni in base alle esigenze. Ad esempio:

<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
        }
    }
}

Suggerimento

Per ottenere gli stessi scenari supportati tramite i convertitori e MultiBinding in WPF, puoi usare le funzioni in x:Bind.

Argomenti di funzione

È possibile specificare più argomenti di funzione, separati da virgole (,)

  • Percorso di binding: stessa sintassi del binding diretto all'oggetto.
    • Se la modalità è OneWay/TwoWay, verrà eseguito il rilevamento delle modifiche e il binding verrà valutato nuovamente in caso di modifiche all'oggetto
  • Stringa costante racchiusa tra virgolette. Le virgolette sono necessarie per designarla come stringa. L'accento circonflesso (^) può essere usato come carattere di escape per le virgolette nelle stringhe
  • Numero costante, ad esempio -123,456
  • Valore booleano, specificato come "x:True" o "x:False"

Binding di funzioni bidirezionale

In uno scenario di binding bidirezionale, è necessario specificare una seconda funzione per la direzione inversa del binding. Questa operazione viene eseguita usando la proprietà di binding BindBack. Nell'esempio seguente, la funzione deve accettare un argomento che corrisponde al valore di cui effettuare nuovamente il push al modello.

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

Vedi anche