Silverlight & ObservableCollection: создание коллекции, измененной в потоке пользовательского интерфейса - PullRequest
0 голосов
/ 06 октября 2010

Мне нужно вызвать событие CollectionChanged для ObservableCollection в потоке пользовательского интерфейса.

Я видел разные подходы, начиная от класса-оболочки и заканчивая пользовательской реализацией соответствующего интерфейса.

Есть ли какой-нибудь простой способ переопределить INotifyCollectionChanged для ObservableCollection, чтобы выполнить это?

Спасибо.

Ответы [ 2 ]

3 голосов
/ 06 октября 2010

Вы можете создать подкласс ObservableCollection и переопределить методы OnCollectionChanged и OnPropertyChanged, чтобы перенаправить событие обратно в поток пользовательского интерфейса с помощью соответствующего диспетчера.

public class DispatcherObservableCollection<T> : ObservableCollection<T>
{
    Dispatcher _dispatcher;
    public DispatcherObservableCollection(Dispatcher dispatcher)
    {
        if (dispatcher == null)
            throw new ArgumentNullException("dispatcher");
        _dispatcher = dispatcher;
    }

    protected override void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (!_dispatcher.CheckAccess())
        {
            _dispatcher.Invoke(
                new Action<PropertyChangedEventArgs>(base.OnPropertyChanged), e);
        }
        else
        {
            base.OnPropertyChanged(e);
        }
    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (!_dispatcher.CheckAccess())
        {
            _dispatcher.Invoke(
                new Action<NotifyCollectionChangedEventArgs>(base.OnCollectionChanged), e);
        }
        else
        {
            base.OnCollectionChanged(e);
        }
    }
}
0 голосов
/ 06 октября 2010

Самый простой способ сделать это - просто добавить / удалить элементы из коллекции в потоке пользовательского интерфейса.Это можно сделать с помощью короткой функции, например:

private void AddItemsToCollection(List<whatever> newItems)
{
    if (this.Dispatcher.CheckAccess()) 
    {
        newItems.ForEach(x => myObservableCollection.Add(x));
    }
    else 
        this.Dispatcher.BeginInvoke(new Action<List<whatever>>(AddItemsToCollection), newItems);
}
...