绑定的复选框状态不会触发OnPropertyChanged

时间:2015-01-14 09:23:26

标签: c# xml wpf mvvm data-binding

我有一个像这样绑定的复选框列表。

<ListBox ItemsSource="{Binding AllThings}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <CheckBox Content="{Binding Name}"
                IsChecked="{Binding Active,Mode=TwoWay}"
                Checked="ToggleButton_OnChecked"
                Unchecked="ToggleButton_OnUnchecked"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

绑定是单向工作的,因为我可以看到根据我的设置从一开始就选中/取消选中这些框。我期待检查一个框来更新底层视图模型,但它不会发生。 OnPropertyChanged 上设置的断点不会被命中。我怀疑这与我在观察属性中改变内部这一事实有关,但由于无知,我不确定。

class Presenter : INotifyPropertyChanged
{
  private IEnumerable<Something> _allThings;
  public IEnumerable<Something> AllThings
  {
    get { return _allThings; }
    set
    {
      _allThings = value;
      OnPropertyChanged("AllThings");
    }
  }

  public Presenter()
  {
    _allThings = DataAccessor.GetThings();
  }

  public event PropertyChangedEventHandler PropertyChanged;

  [NotifyPropertyChangedInvocator]
  protected virtual void OnPropertyChanged(
    [CallerMemberName] String propertyName = null)
  {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

我可以在这里找到什么?

到目前为止,我可以看到我正在做正好 as this guy suggests。显然我错过了一些东西,但这超出了我的想法...

修改

根据@Clemens的要求,我还在 Soomething 类中实现了接口。

public class Something :INotifyPropertyChanged
{
  public int Id { get; set; }
  public String Name { get; set; }
  public bool Active { get; set; }

  public override String ToString()
  {
    return Name;
  }

  public event PropertyChangedEventHandler PropertyChanged;

  [NotifyPropertyChangedInvocator]
  protected virtual void OnPropertyChanged(
    [CallerMemberName] string propertyName = null)
  {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

1 个答案:

答案 0 :(得分:3)

Something必须实现INotifyPropertyChanged接口。这意味着除了写作

public class Something : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
}

当属性值发生变化时,它还必须实际引发PropertyChanged事件,例如:

private string name;
public string Name
{
    get { return name; }
    set
    {
        name = value;
        OnPropertyChanged();
    }
}