2010-11-19 2 views
0

У меня есть следующий код:Обновление пользовательского интерфейса при выполнении задачи

 progressBar1.Minimum = 0; 
     progressBar1.Maximum = Results.Count; 

     foreach (MyClass cls in Results) 
     {     
       progressBar1.Value += 1; 

       // Go to DB and get large quantity of data 
       cls.GetHistoryData(); 

     } 

То, что я хотел бы сделать, это перенести обработку на другой поток, так что progressBar1 обновляет правильно. Я нашел article, что подразумевает, что я должен использовать метод Invoke на индикаторе выполнения, но, похоже, он не существует.

ответ

2

Если связать ProgressBar к свойству данных, вам не нужно переключать контекст потока вручную. Механизм привязки WPF сделает это автоматически для вас.

<ProgressBar Value={Binding Progress} /> 

И тогда в вашей теме:

foreach (MyClass cls in Results) 
{     
     // databinding will automatically marshal to UI thread 
     this.Progress++; 
     cls.GetHistoryData(); 
} 

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

+0

Это похоже на идеальное решение. К сожалению, это не работает. Я делаю предположение, что Progress должен быть настроен как переменная уровня класса (иначе он не распознает его), есть ли что-нибудь еще, что мне нужно сделать? –

+0

Это зависит от вас от вашей установки. Вы можете добавить свойство в свой UserControl/Window и привязать его так же, как в этом сообщении: http://goo.gl/ZMcnp Или, в идеале, если вы идете с MVVM (что делает многое намного проще!), Вы будет иметь DataTemplate для вашего класса ProgressDialogViewModel, у которого есть свойство CurrentProgress и другие вещи, такие как свойство Message и Tiltle. В DataTemplate вы привязываетесь к этим свойствам. – bitbonk

+0

+1 - Лучшее решение. Однако вместо реализации свойства зависимостей для «Прогресс» я бы использовал INotifyPropertyChanged. –

2

Вы должны проверить класс BackgroundWorker. Он поддерживает прогресс и правильно обрабатывает связь между потоками.

0

Вы бы начать новую нить, как например:

Thread t1 = new Thread(methodnametocall); 
    t1.start(); 

void methodnametocall() 
{ 
    this.Invoke((MethodInvoker)delegate 
    { 

     control to update; 
    } 
}); 
0

попробовать этот

progressBar1.Minimum = 0; 
progressBar1.Maximum = Results.Count; 

foreach (MyClass cls in Results) 
{ 
    ThreadPool.QueueUserWorkItem((o) => 
      { 
       progressBar1.Dispatcher.BeginInvoke(
        (Action) (() => progressBar1.Value += 1)); 
       cls.GetHistoryData(); 
      }); 
} 
0

Статья, на которую вы ссылаетесь, является примером winforms, но yo u делают приложение WPF. В вашем случае вы должны изучить вместо этого класс Dispatcher, который вы получите через свойство Dispatcher элемента управления.

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