ItemsSource 更改时选择器不更新

Gra*_*les 7 observablecollection xamarin.forms

我有一个 Xamarin.Forms (3.2,最新版本)Picker实现为

<Picker x:Name="ClassSelector"
            Title="Select Class"
            ItemsSource="{Binding Classrooms}"
            ItemDisplayBinding="{Binding ClassroomName}"
            SelectedItem="{Binding SelectedClassroom}">
</Picker>
Run Code Online (Sandbox Code Playgroud)

BindingContext 是这个 ViewModel:

public class ClassroomsViewModel : BaseViewModel
{
  public ObservableCollection<Classroom> Classrooms { get; set; }

  public ClassroomsViewModel()
  {
     Classrooms = new ObservableCollection<Classroom>(_ClassroomsRepository.GetAll());
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,当我在 中添加教室时ViewModel,选择器会尽职尽责地将项目添加到其列表中:

 Classrooms.Add(new Classroom() { ClassroomName = "test" });   // this works fine
Run Code Online (Sandbox Code Playgroud)

但是,如果我修改教室,则Picker不会更新其项目列表:

Classrooms[0].ClassroomName = "test";  // this doesn't have an effect,
                                       // although the value is set
                                       // in the ObservableCollection
Run Code Online (Sandbox Code Playgroud)

我也尝试过明确调用:

    OnPropertyChanged();  // nothing
    OnPropertyChanged("Classrooms"); // nope
Run Code Online (Sandbox Code Playgroud)

如果它很重要,Classroom则源自ObservableObject

public class Classroom : ObservableObject
{
   private string classroomName;

   public string ClassroomName { get => classroomName; set => SetProperty(ref classroomName, value); }
}
Run Code Online (Sandbox Code Playgroud)

编辑,我在其中澄清这不是集合替换问题:

请注意,我不会新的 ObservableCollection替换该Classrooms集合 - 正如其他可能与我的问题类似的帖子中发生的情况。我只是修改集合的成员之一。当此集合绑定到不同的控件(例如ListView)时,它的行为与预期完全相同 -ListView更新以反映新的ClassroomName

谁能指出我做错了什么?

Sha*_*raj 6

通常,当我们使用绑定时,我们希望目标(选择器项)与绑定源(在本例中为对象Classroom)保持同步 - 因此,您的代码在设计上是正确的。

然而,在深入研究PickerXF github 中的源代码之后 - 看起来它在从 中提取第一个值后取消了绑定/属性更改的订阅Binding在这里,您可以看到对绑定的显式调用UnApply(),以及随后对选取器项目显示名称的绑定表达式的调用。

从技术上讲,调用OnPropertyChanged("Classrooms");on CustomerViewModel(而不是 on Customer)应该可行。或者,您可以尝试Customer从集合中删除修改的对象,然后在同一索引处重新添加以解决此问题。这两个操作都会触发- ,而 - 又会触发picker-item's display nameResetItems()的刷新。

  • 这次真是万分感谢。在视图模型上使用 `OnPropertyChanged("Classrooms")` 似乎不会触发 `ResetItems()`,但删除/替换项目解决方法可以解决这个问题。 (2认同)