私のモデルビューからのコードの抜粋。
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番目のポイントと同じであることがわかりました。コレクションのすべての作成をアプリ ディスパッチャにカプセル化しました。
Application.Current.Dispatcher.Invoke(DispatcherPriority.Send,new Action(
() => { Messages = new ObservableCollection<MessageAbstract>();
MessageView = new CollectionViewSource { Source = Messages };
));
WPF: Dispatcher.BeginInvoke が使用されているにもかかわらず、バインドされた ObservableCollection へのアクセスが失敗する
私たちは以前にもこの問題に遭遇しました。問題は 2 つあります。
1- SourceCollection への変更がメイン スレッド上にあることを確認します (実行済みです)。
2- CollectionView の作成もメイン スレッドで行われたことを確認します (別のスレッドで作成された場合、たとえばイベント ハンドラーへの応答として、通常はそうではありません)。CollectionView は、変更が「その」スレッド上にあること、および「その」スレッドが「UI」スレッドであることを想定しています。