我有一个Xamarin.Forms(3.2,最新版本)Picker
,其实现为
<Picker x:Name="ClassSelector"
Title="Select Class"
ItemsSource="{Binding Classrooms}"
ItemDisplayBinding="{Binding ClassroomName}"
SelectedItem="{Binding SelectedClassroom}">
</Picker>
BindingContext是此ViewModel:
public class ClassroomsViewModel : BaseViewModel
{
public ObservableCollection<Classroom> Classrooms { get; set; }
public ClassroomsViewModel()
{
Classrooms = new ObservableCollection<Classroom>(_ClassroomsRepository.GetAll());
}
}
现在,当我在ViewModel
中添加教室时,Picker会忠实地将该项目添加到其列表中:
Classrooms.Add(new Classroom() { ClassroomName = "test" }); // this works fine
但是,如果我修改一间教室,Picker
不会更新其项目列表:
Classrooms[0].ClassroomName = "test"; // this doesn't have an effect,
// although the value is set
// in the ObservableCollection
我也尝试过显式调用:
OnPropertyChanged(); // nothing
OnPropertyChanged("Classrooms"); // nope
如果重要的话,Classroom
确实来自ObservableObject
:
public class Classroom : ObservableObject
{
private string classroomName;
public string ClassroomName { get => classroomName; set => SetProperty(ref classroomName, value); }
}
请注意,我不是用新的ObservableCollection替换Classrooms
集合,就像其他帖子中出现的那样,类似于我的问题。我只是修改该收藏集的成员之一。当此集合绑定到其他控件(如ListView
)时,它的行为与预期的完全一样-ListView
更新以反映新的ClassroomName
。
有人可以指出我在做什么吗?
答案 0 :(得分:2)
通常,当我们使用绑定时,我们希望目标(一个选择器项)与绑定源(在这种情况下为Classroom
对象)保持同步-因此,您的代码在设计上会是正确的。
但是,在XF github中探究了Picker
源代码之后-从Binding
提取第一个值后,它似乎取消了对绑定/属性更改的预订。 Here you can see the explicit call to UnApply()
到绑定,然后到picker-item显示名称的binding-expression。
在OnPropertyChanged("Classrooms");
上调用CustomerViewModel
(而不是在Customer
上调用)在技术上应该可行。或者,您可以尝试从集合中删除修改后的Customer
对象,然后重新添加相同的索引来解决此问题。这两个操作都将触发ResetItems()
-反过来又应触发picker-item's display name的刷新。
答案 1 :(得分:0)
出于某种原因,将源设置为空然后重置它对我有用:
var items = picker.ItemsSource as List<string>;
items.Add("item");
picker.ItemsSource = null;
picker.ItemsSource = items;