Xamarin.Forms でのバインドのフォールバック
バインディング ソースを解決できないため、またはバインドは成功しても null
値が返されるために、データ バインディングが失敗する場合があります。 これらのシナリオについては、値コンバーターまたは他の追加コードで対処できますが、バインド プロセスが失敗した場合に使用されるフォールバック値を定義することでデータ バインディングをより堅牢にすることができます。 このためには、バインド式で FallbackValue
プロパティと TargetNullValue
プロパティを定義します。 これらのプロパティは、BindingBase
クラス内にあるため、バインド、複数バインド、コンパイル済みのバインド、Binding
マークアップ拡張で使用することができます。
Note
バインド式での FallbackValue
プロパティと TargetNullValue
プロパティの使用は任意です。
フォールバック値の定義
FallbackValue
プロパティを使用すると、バインディング ソースを解決できない場合に使用されるフォールバック値を定義できます。 このプロパティを設定する一般的なシナリオは、バインドされた異種型コレクション内のすべてのオブジェクトに存在しない可能性のあるソース プロパティにバインドする場合です。
次の MonkeyDetail ページは、FallbackValue
プロパティの設定例を示します。
<Label Text="{Binding Population, FallbackValue='Population size unknown'}"
... />
Label
でのバインドは、バインディング ソースを解決できない場合にターゲットで設定される FallbackValue
値を定義します。 このため、FallbackValue
プロパティで定義される値は、バインドされたオブジェクトに Population
プロパティが存在しない場合に表示されます。 ここでは、FallbackValue
プロパティ値が一重引用符 (アポストロフィ) 文字で区切られていることに注意してください。
FallbackValue
プロパティ値をインラインで定義しないで、ResourceDictionary
でリソースとして定義することをお勧めします。 この方法を使用すると、このような値を 1 か所で 1 回定義するだけで済み、ローカライズがより簡単になるという利点があります。 リソースは、StaticResource
マークアップ拡張を使用して取得することができます。
<Label Text="{Binding Population, FallbackValue={StaticResource populationUnknown}}"
... />
Note
バインド式を使用して FallbackValue
を設定することはできません。
実行中のプログラムを次に示します。
バインド式に FallbackValue
プロパティが設定されておらず、バインド パスまたはその一部が解決されない場合、ターゲットでは、BindableProperty.DefaultValue
が設定されます。 一方、バインド式に FallbackValue
プロパティが設定されており、バインド パスまたはその一部が解決されない場合、ターゲットでは、FallbackValue
値プロパティの値が設定されます。 したがって、MonkeyDetail ページでは、バインドされたオブジェクトに Population
プロパティがないため、Label
により、"Population size unknown" (作成サイズが不明) が表示されます。
重要
FallbackValue
プロパティが設定されている場合、バインド式で、定義済みの値コンバーターは実行されません。
null の置換値の定義
TargetNullValue
プロパティを使用すると、バインド ソースは解決できても値が null
である場合に使用される置換値を定義できます。 このプロパティを設定する一般的なシナリオは、値が null
である可能性のある、バインド コレクション内のソース プロパティにバインドする場合です。
次の Monkeys ページは、TargetNullValue
プロパティの設定例を示します。
<ListView ItemsSource="{Binding Monkeys}"
...>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
...
<Image Source="{Binding ImageUrl, TargetNullValue='https://upload.wikimedia.org/wikipedia/commons/2/20/Point_d_interrogation.jpg'}"
... />
...
<Label Text="{Binding Location, TargetNullValue='Location unknown'}"
... />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Image
および Label
でのバインドは両方とも、バインド パスが null
を返す場合に適用される TargetNullValue
値を定義します。 このため、ImageUrl
および Location
が定義されていない場合、コレクション内のオブジェクトに対して TargetNullValue
で定義された値が表示されます。 ここでは、TargetNullValue
プロパティ値が一重引用符 (アポストロフィ) 文字で区切られていることに注意してください。
TargetNullValue
プロパティ値をインラインで定義しないで、ResourceDictionary
でリソースとして定義することをお勧めします。 この方法を使用すると、このような値を 1 か所で 1 回定義するだけで済み、ローカライズがより簡単になるという利点があります。 リソースは、StaticResource
マークアップ拡張を使用して取得することができます。
<Image Source="{Binding ImageUrl, TargetNullValue={StaticResource fallbackImageUrl}}"
... />
<Label Text="{Binding Location, TargetNullValue={StaticResource locationUnknown}}"
... />
Note
バインド式を使用して TargetNullValue
を設定することはできません。
実行中のプログラムを次に示します。
バインド式に TargetNullValue
プロパティが設定されていない場合、ソース値の null
は、変換され (値コンバーターが定義されている場合)、書式設定された (StringFormat
が定義されている場合) 後、その結果がターゲットで設定されます。 一方、TargetNullValue
プロパティが設定されている場合、ソース値 null
は、値コンバーターが定義されていれば変換されます。変換後も null
のままであれば、ターゲットでは TargetNullValue
プロパティの値が設定されます。
重要
TargetNullValue
プロパティが設定されている場合、バインド式で文字列の書式設定は適用されません。