ObservableCollection Collection Changed事件未激发



我的ViewModel中有一个可观察的集合,绑定到数据网格。我想实现一些逻辑,根据对集合的更改/对数据库的更新(使用LINQ to SQL)来刷新其他窗口中的数据。

这是我的视图模型代码:

public FTViewModel(int JobID)
{
_windowCloseAction = new DelegateCommand(OnWindowClose);
_oFTrn = new ObservableFilesTransmitted(_dataDc, JobID);
_oFTrn.CollectionChanged += oFTrnCollectionChanged;
}
void oFTrnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (FilesTransmitted f in e.NewItems)
f.PropertyChanged += FilesTransmitted_PropertyChanged;
}
if (e.OldItems != null)
{
foreach (FilesTransmitted f in e.OldItems)
f.PropertyChanged -= FilesTransmitted_PropertyChanged;
}
}
void FilesTransmitted_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "DocumentNumber")
{
_filesTransmittedChange = true;
}
_refreshViews = true;
}

和ObservableCollection构造函数:

class ObservableFilesTransmitted : ViewableCollection<FilesTransmitted>
{
public ObservableFilesTransmitted(DocControlDC dataDc, int ID)
{
foreach (FilesTransmitted ftran in dataDc.FilesTransmitteds.Where(x=>x.JobID==ID).OrderByDescending(x => x.TransmittalName))
{
this.Add(ftran);
}
}
}

调试器未在oFTrnCollectionChanged中停止。我认为这是因为创建可观察集合的调用发生在我添加CollectionChanged事件之前。但令人讨厌的是,我不能切换这两条线。我已经看了关于这方面的各种StackOverflow和CodeProject主题,似乎我所拥有的应该有效。我是否需要添加和删除一个伪项目来调用CollectionChanged hander?我错过了什么?

似乎我应该有一个不添加任何成员的构造函数(用于可观察集合),以及一个从数据库添加成员的函数。然后我可以调用new,添加collectionchanged处理程序,然后填充集合。我希望能避免这种程度的重写,但也许这是唯一合理的方法。

当我遇到这个问题时,解决它的最简单方法就是在开始时手动订阅。

public FTViewModel(int JobID)
{
_windowCloseAction = new DelegateCommand(OnWindowClose);
_oFTrn = new ObservableFilesTransmitted(_dataDc, JobID);
foreach(var item in _oFTrn)
{
item.PropertyChanged += FilesTransmitted_PropertyChanged;
}
_oFTrn.CollectionChanged += oFTrnCollectionChanged;
}

然而,一个更好的解决方案是使用从ObserveableCollection<T>派生的类,而不是使用从BindingList<T>派生的类。任何引发PropertyChanged事件的成员都将导致集合引发更改类型为ItemChangedListChanged

public FTViewModel(int JobID)
{
_windowCloseAction = new DelegateCommand(OnWindowClose);
_oFTrn = new ObservableFilesTransmitted(_dataDc, JobID);
_oFTrn.CollectionChanged += oFTrnListChanged;
}
void oFTrnListChanged(object sender, ListChangedEventArgs e)
{
if (e.ListChangedType == ListChangedType.ItemChanged)
{
if (e.PropertyDescriptor.Name == "DocumentNumber")
{
_filesTransmittedChange = true;
}
}
_refreshViews = true;
}

我只是简单地更改了ObservableCollection构造函数,并添加了一个填充函数:

新视图模型代码:

public FTViewModel(int JobID)
{
_oFTrn = new ObservableFilesTransmitted(_dataDc, JobID);
_oFTrn.CollectionChanged += oFTrnCollectionChanged;
_oFTrn.FillCollection();
}

新的ObservableCollection类:

class ObservableFilesTransmitted : ViewableCollection<FilesTransmitted>
{
DocControlDC _dc = null;
int _jobID = 0;
public ObservableFilesTransmitted(DocControlDC dataDc, int ID)
{
_dc = dataDc;
_jobID = ID;
}
public void FillCollection()
{
foreach (FilesTransmitted ftran in _dc.FilesTransmitteds.Where(x=>x.JobID==_jobID).OrderByDescending(x => x.TransmittalName))
{
this.Add(ftran);
}
}
}

一切都如预期的那样。但每添加一项都会调用它。我可能会考虑这样的想法,即我只需循环遍历集合,并在视图模型构造函数中为每个项添加属性更改的处理程序。这样的话似乎不太受欢迎。

最新更新