Xamarin.Forms 绑定回退Xamarin.Forms Binding Fallbacks

下载示例 下载示例Download Sample Download the sample

有时数据绑定会失败,因为无法解析绑定源,或者因为绑定成功但返回 null 值。Sometimes data bindings fail, because the binding source can't be resolved, or because the binding succeeds but returns a null value. 虽然可以使用值转换器或其他附加代码处理这些情况,但是通过定义在绑定过程失败时要使用的回退值,可以使数据绑定更加可靠。While these scenarios can be handled with value converters, or other additional code, data bindings can be made more robust by defining fallback values to use if the binding process fails. 这可以通过定义绑定表达式中的 FallbackValueTargetNullValue 属性来实现。This can be accomplished by defining the FallbackValue and TargetNullValue properties in a binding expression. 因为这些属性位于 BindingBase 类中,它们可以与绑定、编译绑定和 Binding 标记扩展一起使用。Because these properties reside in the BindingBase class, they can be used with bindings, compiled bindings, and with the Binding markup extension.

备注

可以选择利用绑定表达式中的 FallbackValueTargetNullValue 属性。Use of the FallbackValue and TargetNullValue properties in a binding expression is optional.

定义一个回退值Defining a fallback value

FallbackValue 属性允许定义在无法解析绑定源时使用的回退值 。The FallbackValue property allows a fallback value to be defined that will be used when the binding source can't be resolved. 设置此属性的常见方案是绑定到可能不存在于异类类型的绑定集合中的所有对象上的源属性。A common scenario for setting this property is when binding to source properties that might not exist on all objects in a bound collection of heterogeneous types.

MonkeyDetail 页说明了设置 FallbackValue 属性的方法 :The MonkeyDetail page illustrates setting the FallbackValue property:

<Label Text="{Binding Population, FallbackValue='Population size unknown'}"
       ... />   

Label 上的绑定定义了 FallbackValue 值,如果无法解析绑定源,将在目标上设置该值。The binding on the Label defines a FallbackValue value that will be set on the target if the binding source can't be resolved. 因此,如果 Population 属性不存在于绑定对象中,则显示 FallbackValue 属性定义的值。Therefore, the value defined by the FallbackValue property will be displayed if the Population property doesn't exist on the bound object. 请注意,此处 FallbackValue 属性值由单引号(撇号)字符分隔。Notice that here the FallbackValue property value is delimited by single-quote (apostrophe) characters.

比起内联定义 FallbackValue 属性值,更推荐将它们定义为 ResourceDictionary 中的资源。Rather than defining FallbackValue property values inline, it's recommended to define them as resources in a ResourceDictionary. 这种方法的优点是在一个位置一次性地定义这些值,并且更容易本地化。The advantage of this approach is that such values are defined once in a single location, and are more easily localizable. 然后可以使用 StaticResource 标记扩展检索资源:The resources can then be retrieved using the StaticResource markup extension:

<Label Text="{Binding Population, FallbackValue={StaticResource populationUnknown}}"
       ... />  

备注

不能使用绑定表达式设置 FallbackValue 属性。It's not possible to set the FallbackValue property with a binding expression.

下面是正在运行的程序:Here's the program running:

FallbackValue 绑定FallbackValue Binding

如果未在绑定表达式中设置 FallbackValue 属性且未解析绑定路径或路径的一部分,则会在目标上设置 BindableProperty.DefaultValueWhen the FallbackValue property isn't set in a binding expression and the binding path or part of the path isn't resolved, BindableProperty.DefaultValue is set on the target. 但是,当设置了 FallbackValue 属性,且未解析绑定路径或部分路径,则会在目标上设置 FallbackValue 值属性的值。However, when the FallbackValue property is set and the binding path or part of the path isn't resolved, the value of the FallbackValue value property is set on the target. 因此,在 MonkeyDetail页面上,Label 显示“人口大小未知”,因为绑定对象缺少 Population 属性。Therefore, on the MonkeyDetail page the Label displays "Population size unknown" because the bound object lacks a Population property.

重要

当设置了 FallbackValue 时,则不会执行绑定表达式中的已定义的值转换器。A defined value converter is not executed in a binding expression when the FallbackValue property is set.

定义 null 替换值Defining a null replacement value

TargetNullValue 属性允许定义替换值,该值将在解析绑定源时使用,但值为 nullThe TargetNullValue property allows a replacement value to be defined that will be used when the binding source is resolved, but the value is null. 设置此属性的常见方案是绑定到绑定集合中可能为 null 的源属性。A common scenario for setting this property is when binding to source properties that might be null in a bound collection.

Monkeys 页说明了设置 TargetNullValue 属性的方法:The Monkeys page illustrates setting the TargetNullValue property:

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

ImageLabel 上的绑定都定义了 TargetNullValue 值,如果绑定路径返回 null 将应用这些值。The bindings on the Image and Label both define TargetNullValue values that will be applied if the binding path returns null. 因此,将为集合中未定义 ImageUrlLocation 属性的任何对象显示由 TargetNullValue 属性定义的值。Therefore, the values defined by the TargetNullValue properties will be displayed for any objects in the collection where the ImageUrl and Location properties are not defined. 请注意,此处 TargetNullValue 属性值由单引号(撇号)字符分隔。Notice that here the TargetNullValue property values are delimited by single-quote (apostrophe) characters.

比起内联定义 TargetNullValue 属性值,更推荐将它们定义为 ResourceDictionary 中的资源。Rather than defining TargetNullValue property values inline, it's recommended to define them as resources in a ResourceDictionary. 这种方法的优点是在一个位置一次性地定义这些值,并且更容易本地化。The advantage of this approach is that such values are defined once in a single location, and are more easily localizable. 然后可以使用 StaticResource 标记扩展检索资源:The resources can then be retrieved using the StaticResource markup extension:

<Image Source="{Binding ImageUrl, TargetNullValue={StaticResource fallbackImageUrl}}"
       ... />
<Label Text="{Binding Location, TargetNullValue={StaticResource locationUnknown}}"
       ... />

备注

不能使用绑定表达式设置 TargetNullValue 属性。It's not possible to set the TargetNullValue property with a binding expression.

下面是正在运行的程序:Here's the program running:

TargetNullValue 绑定TargetNullValue Binding

如果未在绑定表达式中设置 TargetNullValue 属性,则在定义了值转换器时将转换源值 null,如果定义了 StringFormat 则将其格式化,然后在目标上设置结果。When the TargetNullValue property isn't set in a binding expression, a source value of null will be converted if a value converter is defined, formatted if a StringFormat is defined, and the result is then set on the target. 但是,当设置了 TargetNullValue 属性时,如果定义了值转换器,则将转换源值 null,如果转换后它仍为 null,则会在目标上设置 TargetNullValue 属性的值。However, when the TargetNullValue property is set, a source value of null will be converted if a value converter is defined, and if it's still null after the conversion, the value of the TargetNullValue property is set on the target.

重要

设置了 TargetNullValue 属性时,将不会在绑定表达式中应用字符串格式设置。String formatting is not applied in a binding expression when the TargetNullValue property is set.