次の方法で共有


x:Bind with WinUI の関数

WinUI アプリを使用すると、 {x:Bind} マークアップ拡張機能のデータ バインディング パスのリーフ ステップとして関数を使用できます。 この機能により、値の変換が簡略化され、バインドが複数のパラメーターに依存できるようになり、アプリの動的で効率的になります。

ヒント

{x:Bind}を使用したアプリでのデータ バインディングの使用に関する一般的な情報 (および{x:Bind}{Binding}の比較) については、「データ バインディングの詳細」と「{x:Bind} マークアップ拡張」を参照してください。

次の例では、項目の背景と前景は、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);
    }
}

XAML 属性の使用方法

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

関数へのパス

他のプロパティ パスと同様に、関数へのパスを指定します。 パスには、 ドット (.)、 インデクサー、または キャスト を含め、関数を検索できます。

XMLNamespace:ClassName.MethodName構文を使用して静的関数を指定します。 たとえば、次の構文を使用して、分離コード内の静的関数にバインドします。

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

また、マークアップでシステム関数を直接使用して、日付の書式設定、テキストの書式設定、テキスト連結などの単純なシナリオを実現することもできます。 例えば次が挙げられます。

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

モードを OneWay または TwoWay に設定すると、関数パスで変更検出がサポートされます。 バインド エンジンは、それらのオブジェクトが変更された場合にバインディングを再評価します。

バインドする関数は次の要件を満たす必要があります。

  • コードとメタデータからアクセスできるため、C# では内部またはプライベートが機能しますが、C++ ではパブリック 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)
    {
        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
        }
    }
}

ヒント

x:Bindの関数を使用して、WPF のコンバーターと MultiBinding でサポートされていたシナリオと同じシナリオを実現します。

関数の引数

複数の関数引数をコンマ (,) で区切って指定します。

  • バインド パス – そのオブジェクトに直接バインドする場合と同じ構文を使用します。
    • モードを OneWay または TwoWay に設定すると、バインディングは変更を検出し、オブジェクトが変更されたときに再評価します。
  • 引用符で囲まれた定数文字列 – 文字列として指定する引用符を含めます。 文字列内の引用符をエスケープするには、ハット (^) を使用します。
  • 定数 - -123.456 など。
  • ブール値 – "x:True" または "x:False" として指定します。

ヒント

TargetNullValue は、バインドされた引数ではなく、関数呼び出しの結果に適用されます。

双方向関数バインド

双方向バインディング シナリオでは、バインディングの逆方向に 2 つ目の関数を指定する必要があります。 この関数には、 BindBack バインド プロパティを使用します。 次の例では、関数は 1 つの引数を受け取ります。これは、モデルにプッシュバックする必要がある値です。

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

こちらも参照ください