Задержка обновления свойств до тех пор, пока набор свойств не будет изменен (т.е. заблокировать элемент управления) - PullRequest
3 голосов
/ 04 октября 2011

Я создал элемент управления, свойство которого рассчитывается с использованием нескольких других свойств в качестве входных данных. Когда любое из этих входных свойств изменяется, свойство должно быть обновлено. Я уже сделал это возможным благодаря реализации для них событий, изменяющих свойства, помечая зависимое свойство как обновленное. Изменение 3 свойств означает 3 обновления свойств.

Проблема, с которой я сталкиваюсь, заключается в том, что при изменении более чем одного из этих свойств свойство зависимости обновляется каждый раз, когда изменяется любое из этих свойств. Однако свойство требует некоторого времени для расчета (и / или визуализации). Когда будет изменено более одного свойства, я бы хотел, чтобы оно обновлялось только один раз, после того как я обновил все свойства.

Цель: элемент управления необходимо обновлять только после того, как программа закончит изменять все свойства.

Что я пробовал:

  • Сделать свойство ленивым, обновляя его только по запросу. (Не работает, WPF все равно запрашивает);
  • Кэшировать результат расчета. (Не работает, потому что всегда изменяется 1 вход, что делает кэш недействительным);
  • Создайте метод для одновременной установки нескольких свойств. (Не работает, некоторые свойства наследуются и поступают из другого элемента управления);
  • Сделать управление свернутым, прежде чем манипулировать свойствами. (Не работает, WPF все еще обновляет свойства).

У кого-нибудь есть лучшее решение?

Ответы [ 2 ]

2 голосов
/ 04 октября 2011

Вы можете отложить поднятие свойства измененного события.Или создайте метод, который прекратит распространение этого события (например, StartUpdating), и другой метод, который запустит все события (например, EndUpdating).

private bool _isUpdating;
private List<string> _properties = ...;

private void RaisePropertyChanged(string propertyName)
{
   if(_isUpdating) 
   {
     if(!_properties.Contains(propertyName)) _properties.Add(propertyName);
     return;
   } 

   PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

void StartUpdating() { _isUpdating = true; }

void EndUpdating()
{
  _isUpdating = false;
  foreach(var propertyName in _properties) RaisePropertyChanged(propertyName);
}

и в ваших методах

void LongRunningMethodSync()
{
  try
  {
    StartUpdating(); 
    // do something synchronously
  }
  finally
  {
    EndUpdating();
  }
}

void LongRunningMethodAsync()
{
  StartUpdating(); 
  ExecuteMyAsyncTask(done => EndUpdating());
}
0 голосов
/ 04 октября 2011

Посмотрите на свойство привязки IsAsync .Я полагаю, что он может работать в комбинации с шаблоном debounce .

...