Обновление ObservableCollection в WPF вызывает мерцание экрана; Как я могу предотвратить это? - PullRequest
2 голосов
/ 10 августа 2010

У меня есть ObservableCollection, привязанная к WPFToolkit DataGrid в шаблоне MVVM.Каждые 30 секунд у меня есть фоновый поток, который запрашивает службу для некоторых данных.Когда он возвращается, он маршализирует его в поток пользовательского интерфейса и обновляет ObservableCollection, сначала вызывая Clear () для коллекции, а затем вызывая Add () для каждого элемента.Когда это происходит, данные корректно обновляются на экране, однако сетка данных мигает.Как я могу предотвратить это?

Ответы [ 2 ]

2 голосов
/ 10 августа 2010

Я создал простое, но максимально эффективное решение для вашей проблемы:

public class MyCollection<T> : ObservableCollection<T>
{
    private bool _isInEditMode = false;

    public void BeginEdit()
    {
        _isInEditMode = true;
    }

    public void CommitEdit()
    {
        _isInEditMode = false;
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }

    protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (_isInEditMode == false)
        {
            base.OnCollectionChanged(e);
        }
    }
}

Класс my collection предотвращает события, изменяющие коллекцию, пока вы находитесь в режиме редактирования.Запустите «BeginEdit» перед очисткой элементов.Затем добавьте свои новые предметы.Когда вы закончите, используйте «CommitEdit», и представление обновится только один раз.

Если вы проверили его с помощью простого списка, где я добавил 1 000 000 строковых элементов.Попробуйте это.Это забавно:)

 private void Button_Click(object sender, RoutedEventArgs e)
    {
        MyCollection<string> list = testBox.ItemsSource as MyCollection<string>;
        //list.BeginEdit();
        for (int i = 0; i < 1000000; i++)
        {
            list.Add("test " + i);
        }
        list.CommitEdit();

    }

Удалите // из list.BeginEdit () и посмотрите разницу.Его примерно 15 секунд против <1 секунды. </p>

Привет,

Ян

1 голос
/ 10 августа 2010

Похоже, вы просто заменяете все свои данные, если очищаете, а затем добавляете каждый элемент по одному.Вместо того, чтобы повторно использовать ObservableCollection, можете ли вы просто установить для источника данных вашей сетки данных новый ObservableCollection с новыми элементами?

...