2010-12-15 6 views
3

У меня есть DataGrid в моем приложении WPF/C#, которое привязано к коллекции Entity Framework. Каждая строка имеет связанные столбцы, которые меняются очень часто - много раз в секунду. Это приводит к тому, что столбец в основном нечитабелен, потому что он изменяется так часто. Как заставить WPF показывать только новое значение каждые 0,5 секунды или 1 секунду, даже если значение меняется каждые 0,1 секунды?Slow Down Частота обновления привязанного DataGrid

например.

dataGrid.MaxRefreshRate = 1000; (value in milliseconds). 
+0

Поскольку этот вопрос отмечен WPF, я предполагаю, что вы имеете в виду DataGrid? DataGridView - это Windows Forms. Кроме того, быстро ли меняются столбцы или коллекция? – 2010-12-25 10:51:41

+0

@Meleak - Да, извините, я имел в виду DataGrid в WPF. Коллекция быстро меняется, что, в свою очередь, означает, что DataGrid слишком часто обновляется из событий INotifyPropertyChanged. Мне просто хотелось бы, чтобы DataGrid игнорировал некоторые измененные события свойства и просто обновлял, скажем, один раз в секунду. – Chad 2010-12-25 12:43:12

+0

Вы не разрешаете пользователю обновлять данные в datagrid? Чтобы подтвердить, что в противном случае проблемы синхронизации должны быть устранены с помощью этого отложенного обновления. – whoisthis 2010-12-28 06:40:33

ответ

2

Я думаю, что вам нужно, чтобы создать слой между вашими данными и DataGrid.

Предположим, что ваши данные относятся к типу List < Record> и на данный момент привязаны к вашему DataGrid.

Нам понадобится класс оболочки для ваших данных (для одной строки в этом случае). Эта оболочка изменяет свойство и регулярно его запускает. Обратите внимание: я написал этот код наизусть без какого-либо тестирования, там могут (и будут) быть ошибки. Он также не является потокобезопасным, вам нужно добавить некоторые блокировки при работе со списком. Но точка должна быть удалена.

public class LazyRecord : INotifyPropertyChanged 
{ 
    private string name; 
    public string Name 
    { 
    get { return name; } 
    set 
    { 
     if (name != value) 
     { 
     name = value; 
     OnPropertyChanged("Name"); 
     } 
    } 

    // other properties 

    // now the important stuff - deffering the update 
    public event PropertyChangedEventHandler PropertyChanged; 

    private void OnPropertyChanged(string propertyName) 
    { 
     if (this.changedProperties.Find(propertyName) == null) 
     this.changedProperties.Add(propertyName); 
    } 

    private readonly List<string> changedProperties = new List<string>(); 

    // and the timer that refreshes the data 
    private readonly Timer timer; 
    private readonly Record record; 

    public LazyRecord(Record record) 
    { 
     this.timer = new Timer(1000, OnTimer); 
     this.record = record; 

     this.record.OnPropertyChanged += (o, a) => this.OnPropertyChanged(a.PropertyName); 
    } 

    public void OnTimer(..some unused args...) 
    { 
     if (this.PropertyChanged != null) 
     { 
     foreach(string propNAme in changedProperties) 
     { 
      PropertyChanged(new PropertyChangedEventArgs(propName)); 
     } 
    } 
} 

После этого, просто создать список < LazyRecord> из вашего списка < Record> и использовать его в качестве источника данных. Очевидно, что просто использовать общее решение, которое гораздо более многоразово. Надеюсь, я немного помог.

1

Просто идея, как она может работать.

  • Имейте теневую копию данных, привязанных к элементу gui вместо привязки исходных данных.
  • Добавить обработчик событий, который обновляет теневую копию с определенной задержкой от исходных данных.

Может быть вы найдете больше и лучшие ответы на аналогичном новый вопрос how-to-do-the-processing-and-keep-gui-refreshed-using-databinding