如何在内容视图中为选取器设置 ItemDisplayBinding

How do I set ItemDisplayBinding for a Picker inside a Content View

我有一个 ContentPage,它引用了一个 ContentView。在此内容视图中,我有一个自定义 Picker 控件,我绑定了其他属性,例如ItemsSourceItemSelected 但 ItemDisplayBinding 很痛苦。我可以在 Xamarin Forms Picker class 的代码中看到它不像其他字段那样是一个直接可绑定的 属性 字段。目前,当我单击选择器时出现此错误。我知道特定的显示绑定 属性 因为选择器在我没有初始化的情况下工作正常。

错误

Java.Lang.NullPointerException
  Message=Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference

内容页

<controls:MyPickerView PickerTitle="Select time period"
                                       PickerItemDisplayBinding="{Binding Display}" 
                                       PickerItemsSource="{Binding AppointmentRangeOptions}"/>

MyPickerView.xaml

<ContentView.Content>
        <Frame >
            <Picker Title = "{Binding PickerTitle}"
                                   HorizontalOptions="FillAndExpand"
                                   IsEnabled="{Binding PickerIsEnabled}"
                                   ItemDisplayBinding="{Binding PickerItemDisplayBinding}" 
                                   SelectedItem="{Binding SelectedItem, Mode=TwoWay}" 
                                   ItemsSource="{Binding PickerItemsSource, Mode=OneWay}"/>
        </Frame>
    </ContentView.Content>

MyPickerView.xaml.cs

public partial class MyPickerView : ContentView
{
    public MyPickerView()
    {
        InitializeComponent();
        Content.BindingContext = this;
    }

    public static readonly BindableProperty PickerIsEnabledProperty = BindableProperty.Create(
        nameof(PickerIsEnabled),
        typeof(bool),
        typeof(MyPickerView),
        null);

    public bool PickerIsEnabled
    {
        get => (bool)GetValue(PickerIsEnabledProperty);
        set => SetValue(PickerIsEnabledProperty, value);
    }

    public static readonly BindableProperty SelectedItemProperty = BindableProperty.Create(
        nameof(SelectedItem),
        typeof(object),
        typeof(MyPickerView),
        null);

    public object SelectedItem
    {
        get => GetValue(SelectedItemProperty);
        set => SetValue(SelectedItemProperty, value);
    }

    public static readonly BindableProperty PickerTitleProperty = BindableProperty.Create(
        nameof(PickerTitle),
        typeof(string),
        typeof(MyPickerView),
        null);

    public string PickerTitle
    {
        get => (string)GetValue(PickerTitleProperty);
        set => SetValue(PickerTitleProperty, value);
    }

    public static readonly BindableProperty PickerItemDisplayBindingProperty = BindableProperty.Create(
        nameof(PickerItemDisplayBinding),
        typeof(string),
        typeof(MyPicker)
        );

    public string PickerItemDisplayBinding
    {
        get => (string)GetValue(PickerItemDisplayBindingProperty);
        set => SetValue(PickerItemDisplayBindingProperty, value);
    }

    public static readonly BindableProperty PickerItemsSourceProperty = BindableProperty.Create(
        nameof(PickerItemsSource),
        typeof(IList),
        typeof(MyPickerView));

    public IList PickerItemsSource
    {
        get => (IList)GetValue(PickerItemsSourceProperty);
        set => SetValue(PickerItemsSourceProperty, value);
    }
}

的确,这属性是一种痛苦。 我用一个小技巧解决了它:

MyPickerView.xaml.cs

public BindingBase ItemDisplayBinding
{
    get => MyPicker?.ItemDisplayBinding;
    set => MyPicker.ItemDisplayBinding = value;
} // no need to define BindableProperty

MyPickerView.xaml

<ContentView.Content>
    <Frame>
        <Picker x:Name="MyPicker" />
    </Frame>
</ContentView.Content>

内容页

<controls:MyPickerView 
    PickerTitle="Select time period"
    ItemDisplayBinding="{Binding Display}" 
    PickerItemsSource="{Binding AppointmentRangeOptions}"/>