C# WPF:将元素添加到数据绑定集合(依赖项属性)
我有一个C# WPF:将元素添加到数据绑定集合(依赖项属性),c#,wpf,data-binding,xaml,dependency-properties,C#,Wpf,Data Binding,Xaml,Dependency Properties,我有一个dependencProperty,它包含一个实体,该实体的属性是集合(ShoutBox.Entities): 它被绑定在xaml中,如下所示: <ItemsControl ItemsSource="{Binding ShoutBox.Entries}"> . . </ItemsControl> public void AddNewEntry(ShoutBoxEntry newEntry) { Dispatcher.Invoke(new Action((
dependencProperty
,它包含一个实体,该实体的属性是集合(ShoutBox.Entities
):
它被绑定在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
中
[编辑]
条目
(ShoutBox.Entries)的类型为列表
条目的类型是什么?它要么需要是ObservableCollection,要么实现ICollectionChanged。否则,绑定不知道添加了新项。更改条目类型确实可以解决问题。。。
如果要避免显式调用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);
}
}
公共类AsyncObservableCollection:ObservableCollection
{
私有同步上下文_SynchronizationContext=SynchronizationContext.Current;
公共AsyncObservableCollection()
{
}
公共AsyncObservableCollection(IEnumerable列表)
:基本(列表)
{
}
CollectionChanged上的受保护覆盖无效(NotifyCollectionChangedEventArgs e)
{
if(SynchronizationContext.Current==\u SynchronizationContext)
{
//在当前线程上执行CollectionChanged事件
RaiseCollectionChanged(e);
}
其他的
{
//在创建者线程上发布CollectionChanged事件
_synchronizationContext.Post(RaiseCollectionChanged,e);
}
}
私有void RaiseCollectionChanged(对象参数)
{
//我们在creator线程中,直接调用基本实现
base.OnCollectionChanged((NotifyCollectionChangedEventArgs)参数);
}
受保护的重写无效OnPropertyChanged(PropertyChangedEventArgs e)
{
if(SynchronizationContext.Current==\u SynchronizationContext)
{
//在当前线程上执行PropertyChanged事件
RaisePropertyChanged(e);
}
其他的
{
//在创建者线程上发布PropertyChanged事件
_synchronizationContext.Post(RaisePropertyChanged,e);
}
}
私有void RaisePropertyChanged(对象参数)
{
//我们在creator线程中,直接调用基本实现
base.OnPropertyChanged((PropertyChangedEventArgs)参数);
}
}
更多详细信息可在此处找到:
这就是问题所在。将列表更改为ObservableCollection,它应该可以工作。为了选择添加和删除项,集合需要实现ICollectionChanged,而不是INotifyPropertyChanged。
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);
}
}