我有这个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>
答案 0 :(得分:3)
参赛作品的类型是什么?它需要是ObservableCollection或实现ICollectionChanged。否则绑定不知道已添加新项目。
答案 1 :(得分:0)
更改条目类型确实可以解决问题... 如果你想避免显式调用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/