You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Forms自定义Picker控件ItemsSource绑定失效求助

Fixing ItemsSource Binding Failure in Custom Xamarin.Forms HitPicker

Let's break down why your HitPicker isn't working as expected—this is a super common pitfall when building custom controls with Xamarin.Forms!

The Root Cause

You set BindingContext = this; in the HitPicker constructor. This overrides the external BindingContext (your ViewModel) that's set when you use the control in your page. So when you bind ItemsSource="{Binding MonkeyList}", the control is looking for a MonkeyList property on the HitPicker itself instead of your ViewModel—hence why the ViewModel's getter never gets called, and OnItemsSourceChanged never triggers.

Step-by-Step Fixes

1. Remove the Hardcoded BindingContext

First, delete this line from your HitPicker constructor—it's the main culprit:

BindingContext = this;

2. Update the Custom Control's XAML to Use RelativeSource Binding

Instead of relying on the control's BindingContext, explicitly bind the internal Picker properties to the HitPicker control itself using RelativeSource:

<Picker x:Name="PickerField" 
        HeightRequest="46"
        TitleColor="{Binding TitleColor, Source={RelativeSource AncestorType={x:Type controls:HitPicker}}}"
        TextColor="{Binding TextColor, Source={RelativeSource AncestorType={x:Type controls:HitPicker}}}"
        BackgroundColor="{Binding BackgroundColor, Source={RelativeSource AncestorType={x:Type controls:HitPicker}}}"
        Unfocused="Handle_Unfocused" 
        Focused="Handle_Focused" 
        SelectedItem="{Binding SelectedItem, Source={RelativeSource AncestorType={x:Type controls:HitPicker}}}"
        ItemsSource="{Binding ItemsSource, Source={RelativeSource AncestorType={x:Type controls:HitPicker}}}">
</Picker>
*(Ensure your XAML has the correct XML namespace for `controls` declared at the top.)*

#### 3. Refine the BindableProperty Definition (Best Practice)
Use `nameof(ItemsSource)` instead of a string literal to avoid typos, and adjust the binding mode since collection properties rarely need TwoWay binding:
```csharp
public static readonly BindableProperty ItemsSourceProperty = 
    BindableProperty.Create(
        nameof(ItemsSource), 
        typeof(List<string>), 
        typeof(HitPicker), 
        default(List<string>), 
        BindingMode.OneWay,
        propertyChanged: OnItemsSourceChanged);

public List<string> ItemsSource 
{ 
    get => (List<string>)GetValue(ItemsSourceProperty); 
    set => SetValue(ItemsSourceProperty, value); 
}

4. Hardened OnItemsSourceChanged Method

Add null checks to prevent unexpected crashes:

private static void OnItemsSourceChanged(BindableObject bindable, object oldvalue, object newvalue)
{
    var hitPicker = bindable as HitPicker;
    var picker = hitPicker?.PickerField;
    if (picker == null) return;

    picker.Items.Clear();
    var newList = newvalue as List<string>;
    if (newList != null)
    {
        foreach (var item in newList)
        {
            picker.Items.Add(item);
        }
    }
}

Verify Your Setup

Your page's XAML usage is already correct, and you confirmed the page's BindingContext points to your ViewModel—perfect. After applying these fixes, the ItemsSource binding will correctly connect to your ViewModel's MonkeyList, OnItemsSourceChanged will trigger when the list loads, and the picker dialog will display your monkey items as expected.

内容的提问来源于stack exchange,提问作者TameemHabash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 16:37:59