问题描述
我正在尝试创建一个包含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>
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;
}