【发布时间】:2012-04-11 19:54:12
【问题描述】:
我的模型视图中的代码摘录。
private ObservableCollection<MessageAbstract> _messages;
/// <summary>
/// Gets the Messages property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public ObservableCollection<MessageAbstract> Messages
{
get
{
return _messages;
}
set
{
if (_messages == value)
{
return;
}
_messages = value;
RaisePropertyChanged(() => Messages);
}
}
private CollectionViewSource _messageView;
public CollectionViewSource MessageView
{
get { return _messageView; }
set
{
if (_messageView == value) return;
_messageView = value;
RaisePropertyChanged(() => MessageView);
}
}
private void MessageArrived(Message message){
Application.Current.Dispatcher.Invoke(DispatcherPriority.Send,
new Action(() =>Messages.Add(message));
}
public ModelView(){
MessageView = new CollectionViewSource{Source = Messages};
}
当我从另一个服务回调时,我仍然在 Messages.Add(message) 上收到此异常。异常消息如下。 “这种类型的 CollectionView 不支持从不同于 Dispatcher 线程的线程更改其 SourceCollection。”
我认为的代码摘录。
<ListBox x:Name="MessageList" ItemsSource="{Binding MessagesView}">
我检查了 Application.Current.Dispatcher 是否与 MessageList.Dispatcher 相同,所以现在我不知道为什么我不能添加到我的视图中。我的主要目标是我有一个使用集合视图源过滤器来过滤消息列表的搜索框。
找到答案
我发现我的答案与下面答案中的第 2 点相同。我只是将我的集合的所有创建封装在 App 调度程序中。
Application.Current.Dispatcher.Invoke(DispatcherPriority.Send,new Action(
() => { Messages = new ObservableCollection<MessageAbstract>();
MessageView = new CollectionViewSource { Source = Messages };
));
WPF: Accessing bound ObservableCollection fails althouth Dispatcher.BeginInvoke is used
我们之前遇到过这个问题。这个问题是双重的:
1- 确保对 SourceCollection 的任何更改都在主线程上(您已经完成了)。
2- 确保 CollectionView 的创建也在主线程上(如果它是在不同的线程上创建的,比如响应事件处理程序,通常不会是这种情况)。 CollectionView 期望修改在“它的”线程上,并且“它的”>线程是“UI”线程。
【问题讨论】:
-
这适用于示例项目,我所做的只是注释掉 RaisePropertyChanged() 调用。但是,删除 Application.Current.Dispatcher.Invoke() 包装器会导致您引用的异常,所以我的预感是错误在其他地方,而不是在调度程序跳跃代码中。
标签: c# mvvm dispatcher collectionviewsource