更新
看来,在.net 4.5 下有这个所需的功能。请参阅 HighCore 的答案。对于那些没有 4.5 的人,我将解决方法留在这里,也许它可以帮助某人:
class DetachableNotifyCollectionChangedWrapper : IEnumerable, INotifyCollectionChanged {
IEnumerable m_source;
public event NotifyCollectionChangedEventHandler CollectionChanged;
public DetachableNotifyCollectionChangedWrapper(IEnumerable enumerable) {
if (null == enumerable) throw new ArgumentNullException("enumerable"); ;
m_source = enumerable;
var ncc = m_source as INotifyCollectionChanged;
if (null != ncc) ncc.CollectionChanged += SourceCollectionChanged;
}
void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
if (null != CollectionChanged) CollectionChanged(this,e);
}
public IEnumerator GetEnumerator() {
return m_source.GetEnumerator();
}
public void Detach() {
var ncc = m_source as INotifyCollectionChanged;
if (null != ncc) ncc.CollectionChanged -= SourceCollectionChanged;
}
}
要使用它,请将 Wrapper 设置为ItemsSource
ItemsControl 的。在将 设置ItemsSource
为 null 之前,在包装器上调用 Detach 以取消注册更改的事件。如下所示:
var wrapper = m_lstLog.ItemsSource as DetachableNotifyCollectionChangedWrapper;
if (null != wrapper) wrapper.Detach();
m_lstLog.ItemsSource = null;
包装器也可以在 ViewModel 中使用。