PropertyChanged 事件不适用于 yield 创建的集合

PropertyChanged event doesn't work with collection created by yield

为什么下面的代码不起作用?

我有这个class:

public class ExportSetting : INotifyPropertyChanged
{
    public Guid Guid { get; set; }
    public string Name { get; set; }
    private bool export;

    public bool Export
    {
        get { return export; }
        set
        {
            export = value;
            NotifyPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged([CallerMemberName]string propertyName = null)
    {
        if (!string.IsNullOrEmpty(propertyName) && PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

然后我使用命令 yield 创建了集合:

public IEnumerable<ExportSetting> SequencesToExport
    {
        get { return sequencesToExport; }
        set { sequencesToExport = value; }
    }

...

    sequencesToExport = FillSequencesSetting(sequences);

    private IEnumerable<ExportSetting> FillSequencesSetting(List<MTFSequence> sequences)
    {
        foreach (var item in sequences)
        {
            yield return new ExportSetting(item.Id, item.Name, true);
        }
    }

当 属性 导出(来自 class ExportSetting)从 UI 更改时应该引发事件 PropertyChanged 但此事件为空。

(XAML 中的 ListBox 具有绑定到 属性 SequenceToExport 的 ItemsSource)

当我像这样修改集合的创建时,一切正常:

private IEnumerable<ExportSetting> FillSequencesSetting(List<MTFSequence> sequences)
    {
        List<ExportSetting> tmp = new List<ExportSetting>();
        foreach (var item in sequences)
        {
            tmp.Add(new ExportSetting(item.Id, item.Name, true));
        }
        return tmp;
    }

为什么命令 yield 导致事件 PropertyChanged 未注册且为空,而当我使用通用列表创建集合时事件正常工作? 感谢您的回答。

您需要具体化枚举。使用您当前的代码,每次枚举可枚举时 foreach 循环都是 运行,每次都会创建新的 ExportSetting 对象。

修复:

sequencesToExport = FillSequencesSetting(sequences).ToArray();

或者:

sequencesToExport = FillSequencesSetting(sequences);

private IEnumerable<ExportSetting> FillSequencesSetting(List<MTFSequence> sequences)
{
    return sequences.Select(x => new ExportSetting(x.Id, x.Name, true)).ToArray();
}

您错过了 SequencesToExport 属性 更改时的通知:

public bool Export
{
    get { return export; }
    set
    {
        export = value;
        NotifyPropertyChanged();
        NotifyPropertyChanged(nameof(SequencesToExport));
    }
}