我的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的错误?我错过了什么?
似乎我应该有一个不添加任何成员的构造函数(对于observable集合),以及一个添加数据库成员的函数。然后我可以调用new,添加collectionchanged处理程序,然后填充集合。我希望避免这种程度的重写,但也许这是唯一合理的方式。
答案 0 :(得分:1)
当我遇到这个时,最简单的解决方法就是在开始时手动订阅。
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;
}
然而,更好的解决方案是使用从BindingList<T>
派生的类,而不是使用从ObserveableCollection<T>
派生的类。任何提升其PropertyChanged事件的成员都会导致该集合以ItemChanged
ListChanged
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;
}
答案 1 :(得分:0)
我只是更改了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);
}
}
}
这一切都按预期工作。但是它会被添加到每个项目中。我可能会想到我只是遍历集合并为viewmodel构造函数中的每个项添加propertychanged处理程序。看起来似乎不那么受到影响。