Freigeben über


Funktionen in x:Bind mit WinUI

Mit WinUI-Apps können Sie Funktionen als letztes Element des Datenbindungspfads in der {x:Bind} Markuperweiterung verwenden. Dieses Feature vereinfacht die Wertkonvertierung und ermöglicht Bindungen, von mehreren Parametern abhängig zu sein, wodurch Ihre App dynamischer und effizienter wird.

Tipp

Allgemeine Informationen zur Nutzung der Datenbindung in Ihrer App mit {x:Bind} (und für einen umfassenden Vergleich zwischen {x:Bind} und {Binding}), finden Sie unter Datenbindung im Detail und der {x:Bind}-Markuperweiterung.

Im folgenden Beispiel sind der Hintergrund und der Vordergrund des Elements an Funktionen gebunden, die eine Konvertierung basierend auf dem Farbparameter ausführen.

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

XAML-Attributverwendung

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

Pfad zur Funktion

Geben Sie den Pfad zur Funktion wie andere Eigenschaftspfade an. Der Pfad kann Punkte (.), Indexer oder Umwandlungen enthalten, um die Funktion zu finden.

Verwenden Sie die XMLNamespace:ClassName.MethodName Syntax, um statische Funktionen anzugeben. Verwenden Sie beispielsweise die folgende Syntax, um eine Bindung an statische Funktionen in CodeBehind auszuführen.

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

Sie können Systemfunktionen auch direkt im Markup verwenden, um einfache Szenarien wie Datumsformatierung, Textformatierung, Textverkettungen und vieles mehr zu erreichen. Beispiel:

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

Wenn Sie den Modus auf OneWay oder TwoWay festlegen, unterstützt der Funktionspfad die Änderungserkennung. Das Bindungsmodul wertet die Bindung erneut aus, wenn sich diese Objekte ändern.

Die Funktion, an die Sie binden, muss Folgendes erfüllen:

  • Seien Sie zugänglich für den Code und die Metadaten – damit interne oder private Elemente in C# funktionieren, aber in C++ müssen Methoden als öffentliche WinRT-Methoden definiert sein.
  • Unterstützung des Überladens basierend auf der Anzahl von Argumenten, nicht auf dem Typ, und es versucht, die erste Überladung mit dieser Anzahl von Argumenten abzugleichen.
  • Weisen Sie Argumenttypen auf, die den übergebenen Daten entsprechen – das Bindungsmodul führt keine schmalen Konvertierungen durch.
  • Stellen Sie sicher, dass der Rückgabetyp dem Typ der Eigenschaft entspricht, die die Bindung verwendet.

Das Bindungsmodul reagiert auf Eigenschaftenänderungsbenachrichtigungen, die mit dem Funktionsnamen ausgelöst werden, und wertet Bindungen nach Bedarf erneut aus. Beispiel:

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

Tipp

Verwenden Sie Funktionen in x:Bind, um dieselben Szenarien zu erreichen, wie sie durch Konverter und MultiBinding in WPF unterstützt wurden.

Funktionsargumente

Geben Sie mehrere Funktionsargumente an, die durch Kommas (,) getrennt sind.

  • Bindungspfad – Verwenden Sie dieselbe Syntax wie die direkte Bindung an dieses Objekt.
    • Wenn Sie den Modus auf "OneWay" oder "TwoWay" festlegen, erkennt die Bindung Änderungen und wertet sie erneut ab, wenn sich das Objekt ändert.
  • Konstante Zeichenfolge, die in Anführungszeichen eingeschlossen ist – Fügen Sie Anführungszeichen ein, um sie als Zeichenfolge zu kennzeichnen. Verwenden Sie den Hut (^), um Anführungszeichen in Zeichenfolgen zu escapen.
  • Konstante Zahl – z. B. -123,456.
  • Boolean – Geben Sie als "x:Wahr" oder "x:Falsch" an.

Tipp

TargetNullValue gilt für das Ergebnis des Funktionsaufrufs, nicht für gebundene Argumente.

Bidirektionale Funktionsbindungen

In einem bidirektionales Bindungsszenario müssen Sie eine zweite Funktion für die umgekehrte Richtung der Bindung angeben. Verwenden Sie die BindBack Bindungseigenschaft für diese Funktion. Im folgenden Beispiel verwendet die Funktion ein Argument, bei dem es sich um den Wert handelt, der an das Modell zurückgeschoben werden muss.

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

Siehe auch