2015-08-11 2 views
0

Я делаю длинный цикл проверки содержимого папки, разделенной на три части.
p1 - В этой папке содержится более 5000 папок,
p2 - у которых есть ~ 10 папок по одному,
p3 - то неизвестное количество файлов/папок для каждого.Как обновить окна во время длинного цикла

Я сделал индикатор выполнения с максимальным значением = p1.nbFolder в конце каждой p1.folder я увеличиваю прогрессную панель. , но замораживание окна и единственное, что работает для обновления окон в конце каждой папки, - MessageBox.Show ("");

это.UpdateLayout(); не работает
Thread.Sleep (0); ни

for (int inc = 0; inc < postes.Items.Count; inc++) { 
       poste = (TreeViewItem)postes.Items[inc]; 
       poste.IsSelected = true; 
       tranches = (TreeViewItem)tr_tranche.Items[0]; 
       for (int incb = 0; incb < tranches.Items.Count; incb++) { 
        tranche = (TreeViewItem)tranches.Items[incb]; 
        tranche.IsSelected = true; 

        StackPanel SPposte = (StackPanel)poste.Header; 
        Label Lposte = (Label)SPposte.Children[1]; 
        String Sposte = (String)Lposte.Content; 

        StackPanel SPtranche = (StackPanel)tranche.Header; 
        Label Ltranche = (Label)SPtranche.Children[1]; 
        String Stranche = (String)Ltranche.Content; 

        //str.Append("Poste : " + Sposte + " | Tranche : " + Stranche + " | indice : " + incb + " \n"); 

        if (tranche != null) { 
         StackPanel stack = (StackPanel)tranche.Header; 
         Label lbl = (Label)stack.Children[1]; 
         String nom = lbl.Content.ToString(); 

         tr_folio.Items.Clear(); 
         _folio = getDossier(nom, _tranche); 
         //ne filtre rien 
         _folio.getDossiers("a*"); 
         _folio.getFichiers(); 
         tr_folio.Items.Add(Utils.TreeUtils.ContenuDossier(_folio)); 
         lbl_source.Content = _folio.Chemin; 

         TreeViewItem entete = (TreeViewItem)tr_folio.Items[0]; 
         entete.IsExpanded = true; 
        } 
        //MessageBox.Show(incb.ToString()); 
        tranche.IsSelected = false; 
       } 
       poste.IsSelected = false; 
       pgrB.Value++; 
       Thread.Sleep(1); 
       this.UpdateLayout(); 
+3

Вы должны запустить свой код либо в фоновом потоке или в методе асинхронным. Вы блокируете основной поток, и это не очень хорошее решение. –

+0

Разделите задание и используйте 'DispacherTimer', чтобы выполнить задание или поместить задание в' Task' (при вызове пользовательских интерфейсов). – Sinatr

+0

Удалите весь этот код и используйте надлежащие XAML и привязку данных. –

ответ

0

Я нашел этот учебник. ProgressBar control tutorial

Paul> Ваше решение практически идентично, но я не нашел достаточного объяснения для получения рабочего раствора

0

Основной поток пользовательского интерфейса должен быть бесплатным для обработки сообщений Windows. Если вы переместите свою работу в фоновый поток, поток пользовательского интерфейса сможет рисовать окна, отвечать на ввод пользователя (например, кнопки отмены) и т. Д.

Существует много примеров многопоточности с WPF. Например, см. this question за хорошую информацию.

+0

@Sinatr true, но я бы пожаловался больше, что статье 13 лет ... – crashmstr

+0

Возраст-на стоп-потоке! Просто шучу. Изменена ссылка на более релевантный вопрос SO. –

0

Одним из лучших решений для потенциально блокирующего бита кода является использование потока, чтобы он не блокировал пользовательский интерфейс от чего-либо или любого другого кода. Он работает в своем маленьком мире.

Task mytask = Task.Factory.StartNew(myfunc,aparam); 

вы можете даже сделать (по линии, не расфасованные в окно кодирования для проверки синтаксиса)

var mytask = Task.Factory.StartNew(myfunc).ContinueWith(result => its_done_func()); 

Таким образом, вы можете сказать, когда его сделали, вы можете также использовать функцию для обновления с все результаты. Вы можете, конечно, использовать лямбда слишком

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