[英]WPF: Adding an element to a databound Collection (a Dependency Property)
我有這個DependencyProperty
,它擁有一個實體,該實體的屬性是一個集合( ShoutBox.Entities
):
public static readonly DependencyProperty ShoutBoxProperty = DependencyProperty.Register("ShoutBox",typeof (ShoutBox),typeof (ShoutBoxViewerControl));
public ShoutBox ShoutBox
{
get { return (ShoutBox) GetValue(ShoutBoxProperty); }
set { SetValue(ShoutBoxProperty, value); }
}
它被綁定在xaml
如下所示:
<ItemsControl ItemsSource="{Binding ShoutBox.Entries}">
.
.
</ItemsControl>
第一次綁定它時,它可以按預期工作,但是有時我需要向集合中添加項目(使用同一控件中的方法),例如:
public void AddNewEntry(ShoutBoxEntry newEntry)
{
Dispatcher.Invoke(new Action(() =>{
ShoutBox.Entries.Add(newEntry); //Adding directly the the Dependency property
}));
}
問題是,當我使用上述方法添加新元素時,該項目未顯示在ItemsControl
。
我的問題是, 為什么我要添加的新元素沒有顯示在ItemsControl
?
[編輯]
Entries
( ShoutBox.Entries )的類型為List<ShoutBoxEntry>
參賽作品是什么類型? 它要么是ObservableCollection,要么實現ICollectionChanged。 否則,綁定不知道已添加新項目。
更改Entries的類型確實可以解決問題...如果要避免顯式調用Dispatcher.Invoke,我編寫了一個集合,該集合在創建集合的線程上引發CollectionChanged和PropertyChanged事件:
public class AsyncObservableCollection<T> : ObservableCollection<T>
{
private SynchronizationContext _synchronizationContext = SynchronizationContext.Current;
public AsyncObservableCollection()
{
}
public AsyncObservableCollection(IEnumerable<T> list)
: base(list)
{
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (SynchronizationContext.Current == _synchronizationContext)
{
// Execute the CollectionChanged event on the current thread
RaiseCollectionChanged(e);
}
else
{
// Post the CollectionChanged event on the creator thread
_synchronizationContext.Post(RaiseCollectionChanged, e);
}
}
private void RaiseCollectionChanged(object param)
{
// We are in the creator thread, call the base implementation directly
base.OnCollectionChanged((NotifyCollectionChangedEventArgs)param);
}
protected override void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (SynchronizationContext.Current == _synchronizationContext)
{
// Execute the PropertyChanged event on the current thread
RaisePropertyChanged(e);
}
else
{
// Post the PropertyChanged event on the creator thread
_synchronizationContext.Post(RaisePropertyChanged, e);
}
}
private void RaisePropertyChanged(object param)
{
// We are in the creator thread, call the base implementation directly
base.OnPropertyChanged((PropertyChangedEventArgs)param);
}
}
可以在這里找到更多詳細信息: http : //www.thomaslevesque.com/2009/04/17/wpf-binding-to-an-asynchronous-collection/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.