2014-11-11 5 views
0

У меня сложный внутренний процесс, который работает в течение длительного периода времени. Все жизненные статистики отображаются в виде свойств с событиями INotifyPropertyChanged, поднятыми, когда они установлены.Регулярное обновление привязки Wpf

Я хотел добавить «Истекшее время», которое оказалось гораздо более сложным, чем ожидалось.

Я выставил ProcessStartedAt DateTime и бросил вместе конвертер для вычитания связанного времени с DateTime.Now. Это работает отлично (один раз). После этого, поскольку свойство не изменяется, привязка никогда не обновляется, и конвертер не вызывается снова.

Я не хочу, чтобы у back-end был таймер, посвященный обновлению свойства «Истекшее время». Это нарушает принцип разделения интересов. Я был бы счастливее с таймером в пользовательском интерфейсе, но не уверен, как принудительно привязать к обновлению без обновления значения свойства.

Еще лучше, есть ли способ, с помощью которого я могу установить привязку для обновления через равные промежутки времени?

<TextBlock Text="{Binding Path=ProcessStartedAt, 
          Converter={StaticResource ElapsedTime}}"/> 
+0

Как насчет уведомления о том, что свойство меняется каждый второй? –

+0

Ну, технически, это не так. Результат преобразования меняется каждую секунду ... – Basic

+0

Результат технически изменяется каждые миллисекунды, но вы можете уведомить в любой промежуток времени, который вы хотите ... или, может быть, я не понимаю, что это за свойство. Что представляет собой Истекшее время? –

ответ

1

Я бы выбрал таймер внутри класса ValueConverter и поднять событие, чтобы вызвать метод Convert каждый раз, когда наступает интервал.

Это удерживает ValueConverter от его ответственности.

+0

Это звучит многообещающе. Я могу легко добавить таймер, но какое событие мне нужно поднять, чтобы заставить Wpf обновить привязку? – Basic

+0

Собственно, событие, вероятно, слишком велико. Просто выполняйте цикл while и sleep. После вызова сна вызовите ваш метод конвертации. –

+0

Я бы создал класс, который отвечает за душу, чтобы спать и уведомлять своих подписчиков, когда он просыпается. Внутри конструктора преобразователя я бы подписался на событие timeInterval объекта. Когда конвертер будет уведомлен о событии, он будет вызывать его метод Convert. –

0

«У меня сложный внутренний процесс, который работает в течение длительного периода времени». и «Я не хочу, чтобы у back-end был таймер, посвященный обновлению свойства« Истекшее время ». кажется немного контрпродуктивным.

Попытка не обновлять вида с видом-моделью, кажется, нарушают некоторые принципы MVC. Предположим, что вы нашли способ сделать это, следующий инженер/разработчик не может этого сделать.

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

EDIT

Я думаю, единственный способ установить DispatcherTimer, подписаться на него и вызвать OnPropertyChanged. Не относится к вашему вопросу, но вы также можете поместить Delay на свой Binding, если это необходимо.

+0

Я не пытаюсь блокировать обновления? Я хочу, чтобы визуальное представление, полученное из значения, менялось со временем. Это похоже на то, что связано со мной. У меня нет проблем с обновлением модели просмотра. Как я уже сказал, «я был бы счастливее с таймером в пользовательском интерфейсе», и да, использование таймера для обновления модели имеет такой же смысл, как и обновление привязки, но не существует способа заставить оболочку вызывать конвертер автоматически через определенные промежутки времени? – Basic

+0

Кроме того, можете ли вы объяснить, почему нежелание фокуса беспокоиться о проблемах пользовательского интерфейса является контрпродуктивным? – Basic

+0

Я думал, что вы пытаетесь заблокировать уведомления, потому что ваш back-end процесс был слишком медленным или что-то еще. Я основывал свой ответ на этом предположении. Извините, если я ошибаюсь. Тогда, я думаю, единственный способ - установить «DispatcherTimer», подписаться на него и вызвать «OnPropertyChanged». Не связано с вашим вопросом, но вы также можете поместить «Delay» в свой Binding, если это необходимо. – rodrigogq

1

Нет необходимости в преобразователе, просто уведомить задерживая на поглотителе:

public string RemainingTime 
{ 
    get { 
      Task.Delay(1000). 
      ContinueWith(w => OnPropertyChanged(() => RemainingTime)); 
      return (CurrentServerTime - SelectedDeliveryTime).ToString("mm\\:ss"); 
     } 
} 

Связывание Напомним, из-за OnPropertyChange

Смежные вопросы