2016-02-15 3 views
-1

Я пытаюсь получить индикатор выполнения, чтобы обновить его в зависимости от того, сколько циклов цикла было выполнено. Цикл работает в своем потоке. У меня такое впечатление, что Dispatcher.BeginInvoke - хороший выбор и реализовал его. Я также прочитал, что диспетчер может обновить графический интерфейс, даже если он работает со своим потоком. Тем не менее, я не могу заставить это работать, пытаясь уведомить об обязательном обновлении, реализуя INotifyPropertyChanged. Я видел некоторые блоги, вопросы и т. Д., Которые предлагают разные магические методы для решения этой проблемы, но поскольку я прочитал, это должно быть обработано диспетчером, я бы хотел этого избежать.Использование INotifyPropertyChanged и Dispatcher для обновления вида

NB! Это не Наблюдаемая коллекция, которую я прочитал, не обрабатывается диспетчером.

Пример кода из ViewModel

Application.Current.Dispatcher.BeginInvoke(() => 
{ 
    this.Progress = 0; 
    for (int i = 0; i < this.nrOfLoops; i++) 
    { 
     // implementation goes here ... 
     if (i % 100 == 0) // Only update every 100 cycle 
     { 
      this.Progress = (double)i/nrOfLoops * 100; 
      this.NotifyPropertyChanged("Progress"); 
     } 
    } 
}, DispatcherPriority.Background); 

XAML

<ProgressBar Value="{Binding Path=Progress}"/> 

ГИП не постоянно обновляется, только заполнен на 100%, когда все сделано. Я пробовал возиться с DispatcherPriority на всякий случай, но без результатов. Я знаю, что привязка - это нормально, если установить значение по умолчанию, а также тот факт, что индикатор выполнения заполняется по завершении.

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

ответ

1

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

Application.Current.Dispatcher.Invoke<Task>(UpdateBar, DispatcherPriority.Background); 

и это метод:

private Task UpdateBar() 
    { 
     return Task.Factory.StartNew(() => 
     { 
      this.Progress = 0; 
      for (int i = 0; i < 100; i++) 
      { 
       this.Progress = (double)i; 
       this.NotifyPropertyChanged("Progress"); 
       Thread.Sleep(30); 
      } 
     }); 
    } 
+0

Спасибо aminexplo, я постараюсь это, когда я вернулся домой с работы. – Anders

+0

К сожалению, это не работает для меня. Он не будет распознавать Invoke как общий метод. Я использую версию Community 2015. Не знаю, так ли это имеет значение? Я использую System.Windows так же, как MSDN. – Anders

+0

Это сейчас работает! Рамка назначения была установлена ​​в 4.0, но я изменил ее на 4.5 и там существовал Invoke . Спасибо за помощь. – Anders

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