有时数据绑定会失败,因为无法解析绑定源,或者因为绑定成功但返回 null 值。 虽然可以使用值转换器或其他附加代码处理这些情况,但是通过定义在绑定过程失败时要使用的回退值,可以使数据绑定更加可靠。 在 .NET Multi-platform App UI (.NET MAUI) 应用中,可以通过在绑定表达式中定义 FallbackValue 和 TargetNullValue 属性来实现此目的。 因为这些属性位于 BindingBase 类中,它们可以与绑定、多绑定、编译绑定和 Binding 标记扩展一起使用。
注意
可以选择利用绑定表达式中的 FallbackValue 和 TargetNullValue 属性。
定义一个回退值
FallbackValue 属性允许定义在无法解析绑定源时使用的回退值。 设置此属性的常见方案是绑定到可能不存在于异类类型的绑定集合中的所有对象上的源属性。
下面的示例演示如何设置 FallbackValue 属性:
<Label Text="{Binding Population, FallbackValue='Population size unknown'}"
... />
Label 上的绑定定义了 FallbackValue 值(由单引号字符分隔),如果无法解析绑定源,将在目标上设置该值。 因此,如果 Population 属性不存在于绑定对象中,则显示 FallbackValue 属性定义的值。
比起内联定义 FallbackValue 属性值,更推荐将它们定义为 ResourceDictionary 中的资源。 这种方法的优点是在一个位置一次性地定义这些值,并且更容易本地化。 然后可以使用 StaticResource 标记扩展检索资源:
<Label Text="{Binding Population, FallbackValue={StaticResource populationUnknown}}"
... />
注意
不能使用绑定表达式设置 FallbackValue 属性。
如果未在绑定表达式中设置 FallbackValue 属性且未解析绑定路径或路径的一部分,则会在目标上设置 BindableProperty.DefaultValue。 但是,当设置了 FallbackValue 属性,且未解析绑定路径或部分路径,则会在目标上设置 FallbackValue 值属性的值:
因此,在本示例中,由于绑定对象缺少 Population 属性,Label 显示“未知总体大小”。
重要
当设置了 FallbackValue 时,则不会执行绑定表达式中的已定义的值转换器。
定义 null 替换值
TargetNullValue 属性允许定义替换值,该值将在解析绑定源时使用,但值为 null。 设置此属性的常见方案是绑定到绑定集合中可能为 null 的源属性。
下面的示例演示如何设置 TargetNullValue 属性:
<ListView ItemsSource="{Binding Monkeys}"
...>
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:Monkey">
<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 上的绑定都定义了 TargetNullValue 值(由单引号字符分隔),如果绑定路径返回 null,则将应用这些值。 因此,将为集合中未定义 ImageUrl 和 Location 属性的任何对象显示由 TargetNullValue 属性定义的值。
比起内联定义 TargetNullValue 属性值,更推荐将它们定义为 ResourceDictionary 中的资源。 这种方法的优点是在一个位置一次性地定义这些值,并且更容易本地化。 然后可以使用 StaticResource 标记扩展检索资源:
<Image Source="{Binding ImageUrl, TargetNullValue={StaticResource fallbackImageUrl}}"
... />
<Label Text="{Binding Location, TargetNullValue={StaticResource locationUnknown}}"
... />
注意
不能使用绑定表达式设置 TargetNullValue 属性。
如果未在绑定表达式中设置 TargetNullValue 属性,则在定义了值转换器时将转换源值 null,如果定义了 StringFormat 则将其格式化,然后在目标上设置结果。 但是,当设置了 TargetNullValue 属性时,如果定义了值转换器,则将转换 null 的源值,如果转换后它仍为 null,则会在目标上设置 TargetNullValue 属性的值:
因此,在本示例中,Image 和 Label 对象在其源对象为 null 时显示其 TargetNullValue。
重要
设置了 TargetNullValue 属性时,将不会在绑定表达式中应用字符串格式设置。
TargetNullValue 和 FallbackValue 比较
TargetNullValue 和 FallbackValue 都用于数据绑定,以处理绑定值为 null 或绑定失败的场景。 了解何时使用每一项有助于确保用户体验的流畅性。
TargetNullValue
使用 TargetNullValue 属性指定一个值,当绑定成功但绑定属性为 null 时显示该值:
<Label Text="{Binding FirstName, TargetNullValue='No name available'}" />
在此示例中,如果 FirstName 是 null,Label 将显示“无可用名称”。
FallbackValue
使用 FallbackValue 属性可在绑定过程完全失败(如路径不正确或绑定上下文丢失)时提供一个值:
<Label Text="{Binding FirstName, FallbackValue='Binding failed'}" />
在此示例中,如果绑定失败,Label 将显示“绑定失败”。
组合使用
TargetNullValue 和 FallbackValue 属性可以在单个绑定表达式中进行组合:
<Label Text="{Binding FirstName, TargetNullValue='No name available', FallbackValue='Binding failed'}" />
浏览示例