2

私のモデルビューからのコードの抜粋。

   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」スレッドであることを想定しています。

4

1 に答える 1

1

に直接バインドしているときに、同じスレッドの問題が発生しましたCollectionViewSourceCollectionView代わりにリストボックスをオブジェクトにバインドすることで問題を解決しました。

あなたの場合、リストボックスの宣言を次のように変更するだけです。

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

これがお役に立てば幸いです。

于 2012-12-26T01:17:00.760 に答える