注
{x:Bind} を使用したアプリでのデータ バインディングの使用に関する一般的な情報 (および {x:Bind} と {Binding} の間の詳細な比較) については、「データ バインディングの詳細と {x:Bind} マークアップ拡張」を参照してください。
Windows 10 バージョン 1607 以降、{x:Bind} では、バインド パスのリーフ ステップとして関数を使用できます。 これにより、次のことが可能になります。
- 価値変換を実現するより簡単な方法
- バインドが複数のパラメーターに依存する方法
注
{x:Bind} で関数を使用するには、アプリの最小ターゲット SDK バージョンが 14393 以降である必要があります。 アプリが以前のバージョンの Windows 10 を対象とする場合は、関数を使用できません。 ターゲット バージョンの詳細については、「バージョン アダプティブ コード」を参照してください。
次の例では、項目の背景と前景が関数にバインドされ、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>
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 構文を使用して指定できます。 たとえば、コードビハインド内の静的関数にバインドするには、次の構文を使用します。
<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;
}
}
また、マークアップでシステム関数を直接使用して、日付の書式設定、テキストの書式設定、テキスト連結などの単純なシナリオを実現することもできます。次に例を示します。
<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>
モードが OneWay/TwoWay の場合、関数パスに対して変更検出が実行され、それらのオブジェクトに変更がある場合はバインディングが再評価されます。
バインドされる関数は、次の必要があります。
- コードとメタデータからアクセスできるため、C# では内部/プライベート作業が行われますが、C++/CX にはパブリック 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)
{
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
}
}
}
ヒント
x:Bind の関数を使用すると、WPF のコンバーターや MultiBinding でサポートされていたシナリオと同じシナリオを実現できます。
関数の引数
複数の関数引数をコンマ (,) で区切って指定できます。
- バインド パス – そのオブジェクトに直接バインドする場合と同じ構文。
- モードが OneWay/TwoWay の場合、変更検出が実行され、オブジェクトの変更時にバインディングが再評価されます
- 引用符で囲まれた定数文字列 – 文字列として指定するには引用符が必要です。 Hat (^) を使用して文字列内の引用符をエスケープできます
- 定数番号 - 例: -123.456
- ブール値 – "x:True" または "x:False" として指定
ヒント
TargetNullValue
は、バインドされた引数ではなく、関数呼び出しの結果に適用されます。
双方向関数結合
双方向バインディング シナリオでは、バインディングの逆方向に 2 つ目の関数を指定する必要があります。 バインドバック バインディングプロパティを用いることで行われます。 次の例では、関数は、モデルにプッシュバックする必要がある値である 1 つの引数を受け取る必要があります。
<TextBlock Text="{x:Bind a.MyFunc(b), BindBack=a.MyFunc2, Mode=TwoWay}" />