在包含选取器的自定义控件中绑定ItemSource属性 在HitPicker.xaml中在HitPicker.xaml.cs

问题描述

我正在尝试创建一个包含Xamarin.Forms选取器的自定义控件。 问题是尝试绑定ItemSource属性时,它永远不会被绑定,当我在移动设备上触摸自定义控件时,它会显示一个空对话框,其中没有绑定的项目。

注意:我尝试了在“ Stack OverFlow”或“ forums.xamarin”上找到的几乎所有解决方案,但没有一个我有用。

这是我的代码

对于自定义控件XAML文件-以“ HitPicker”命名--

   <Picker x:Name="PickerField" 
        HeightRequest="46" 
        TitleColor="{Binding TitleColor}"
        TextColor="{Binding TextColor}" 
        BackgroundColor="{Binding BackgroundColor}"
        Unfocused="Handle_Unfocused" 
        Focused="Handle_Focused"
        SelectedItem="{Binding SelectedItem}"
        ItemsSource="{Binding ItemsSource}">
   </Picker>

对于自定义控件cs文件

public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create("ItemsSource",typeof(List<string>),typeof(HitPicker),default(List<string>),BindingMode.TwoWay,null,OnItemsSourceChanged);

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

public HitPicker()
{
    InitializeComponent();
    BindingContext = this;
}

private static void OnItemsSourceChanged(BindableObject bindable,object oldvalue,object newvalue)
    {
        var picker = (bindable as HitPicker).PickerField;
        picker.Items.Clear();
        var newList = newvalue as List<string>;
        if (newvalue != null)
        {
            foreach (var item in newList)
            {
                picker.Items.Add(item.ToString());
            }
        }
    }

知道从未调用过OnItemsSourceChanged方法,几乎​​所有与我类似的问题都得到了相似的答案,这建议将该方法放入控件类中。

使用此控件的XAML文件

<controls:HitPicker ItemsSource="{Binding MonkeyList}" Title="Select monky" BackgroundColor="Azure"></controls:HitPicker>

这是上述XAML的viewmodel中的猴子列表声明:

 private List<string> _lst = new List<string>{
            "Baboon","Capuchin Monkey","Blue Monkey","Squirrel Monkey","Golden Lion Tamarin","Howler Monkey","Japanese Macaque"
        };

    public List<string> MonkeyList
    {
        get => _lst;
        set
        {
            _lst = value;
            OnPropertyChanged();
        }
    }

MonkeyList getter永远也不会被调用,因为它知道Binding上下文是viewmodel

解决方法

当您在CustomControl中设置绑定上下文时,例如

public HitPicker()
{
    InitializeComponent();
    BindingContext = this;
}

它将破坏自定义控件和ContentPage之间的绑定。

所以您可以像下面那样修改代码

在HitPicker.xaml中

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            //...
             x:Name="pickerView" //set name of page >
   <Picker x:Name="PickerField" 
        HeightRequest="46" 
        TitleColor="{Binding Source={x:Reference pickerView},Path=TitleColor}"
        TextColor="{Binding Source={x:Reference pickerView},Path=TextColor}" 
        BackgroundColor="{Binding Source={x:Reference pickerView},Path=BackgroundColor}"
        Unfocused="Handle_Unfocused" 
        Focused="Handle_Focused"
        SelectedItem="{Binding Source={x:Reference pickerView},Path=SelectedItem}">
   </Picker>

在HitPicker.xaml.cs

public HitPicker()
{
    InitializeComponent();
    //BindingContext = this;
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...