CollectionViewSource.Source 的调度程序更新在同一线程上引发错误的线程异常



我的模型视图中的代码摘录。

   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 不支持从与调度程序线程不同的线程对其 SourceCollection 进行更改。

我的观点中的代码摘录。

<ListBox x:Name="MessageList" ItemsSource="{Binding MessagesView}">

我已经检查了Application.Current.Dispatcher是否与MessageList.Dispatcher相同,所以现在我不明白为什么我不能添加到我的视图中。我的主要目标是我有一个搜索框,它使用集合视图源筛选器来筛选邮件列表。

得到答案

我发现我的答案错误与下面答案中的#2点相同。我只是将集合的所有创建封装在应用程序调度程序中。

Application.Current.Dispatcher.Invoke(DispatcherPriority.Send,new Action(
      () => { Messages = new ObservableCollection<MessageAbstract>();
              MessageView = new CollectionViewSource { Source = Messages };
                                      ));

WPF:访问绑定的可观察集合失败,但使用 Dispatcher.BeginInvoke

我们先遇到了这个问题。问题是双重的:

1-确保对SourceCollection的任何更改都在主线程上(您已经完成了>那个)。

2-确保CollectionView的创建也在主线程上(如果它是>在不同的线程上创建的,例如响应事件处理程序,则通常不会>这种情况)。CollectionView 期望修改在"它的"线程上,并且"它的">线程是"UI"线程。

我在直接绑定到CollectionViewSource时遇到了相同的线程问题。我通过将列表框绑定到CollectionView对象来解决此问题。

在您的情况下,您只需将列表框声明更改为:

<ListBox x:Name="MessageList" ItemsSource="{Binding MessagesView.View}">

希望这对你有帮助。

最新更新