wtorek, 15 kwietnia 2014

Asynchroniczne pobieranie danych i uaktualnianie CollectionView w WPF

W WPF klasa CollectionView jest niezwykle przydatna jeśli chcemy w prosty sposób zaimplementować mechanizm sortowania, grupowania lub filtrowania. Używając jej jednak w programowaniu asynchronicznym podczas uaktualniania tej kolekcji z innego wątku, dostaniemy następujący komunikat:

The calling thread cannot access this object because a different thread owns it

Nie dziwota, jest to normalnie zachowanie, które często się zdarza, ponieważ CollectionView nie obsługuje zmian własnej kolekcji z wątku innego niż Dispatcher. Co jednak zrobić aby obejść ten problem? Po pierwsze musimy mieć obiekt dispatcher'a, która w WPF'ie jest klasą zapewniającą usługi do zarządzania wątkami, np. synchronizacji. Jeśli korzystamy ze wzorca MVVM (Model-View-ViewModel), pierwsze co musimy zrobić to przekazać obiekt dispatcher'a do ViewModelu, np w konstruktorze:

private Dispatcher currentDispatcher;

public ViewModel(Dispatcher currentDispatcher)
{
    this.currentDispatcher = currentDispatcher;
}
Następnie aby dodawać obiekty do kolekcji CollectionViewSource, należy wykonać następujący kod:
currentDispatcher.Invoke(new Action(()=>
{
    this.collectionViewSource.Add(someObject);
}));

1 komentarz:

  1. Można od razu tak:

    Application.Current.Dispatcher.BeginInvoke(new Action(() =>
    {
    this.collectionViewSource.Add(someObject);
    }));

    OdpowiedzUsuń