2017-02-04 17 views
1

У меня есть список с элементами, и пользователь может выполнить некоторые действия над элементом, например New/Edit/Delete. Однако это может занять некоторое время, и я хотел бы показать неопределенный прогресс, пока выполняются основные действия.Требуется много времени для работы и Progressbar

Как это сделать в .NET 4.6 & C# 6.0? Согласно this post, я должен использовать Асинхронный шаблон на основе задач (TAP). В потоке есть много возможных решений.

Это еще предпочтительный способ?

ответ

1

Первое, что нужно понять, это выполнить операции New/Edit/Delete фоновый поток, чтобы ваш пользовательский интерфейс реагировал и для ProgressBar мог обновляться в течение времени, необходимого для завершения этих операций.

Предпочтительный и простой способ отключить некоторую работу в фоновом потоке - использовать параллельную библиотеку задач (TPL) и запустить новую задачу. Имейте в виду, что элементы управления WPF имеют сходство потоков, поэтому вы можете обращаться к ним только в потоке, из которого они были созданы, и это поток диспетчера.

Таким образом, вы могли бы осуществить это, установив Visibility свойства объекта ProgressBar в Visible, запустить задачу, которая выполняет фактическую Новый/Редактировать/Удалить операцию, а затем установить Visibility свойства обратно Collapsed снова, как только задача закончена:

C#:

pb.Visibility = Visibility.Visible; 
Task.Run(()=> 
{ 
    //perform your long-running operation here...make sure that you don't access any UI elements 
    Save(); 
}) 
.ContinueWith(task => 
{ 
    //this delegate will be executed back on the UI thread once the task has finished because of the scheduler returned from the TaskScheduler.FromCurrentSynchronizationContext() method... 
    pb.Visibility = Visibility.Collapsed; 
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); 

XAML:

<ProgressBar x:Name="pb" IsIndeterminate="True" Visibility="Collapsed" /> 
+0

Возможно, C#, который вы указали выше, находится в файле xaml.cs? У меня есть функция New/Edit/Delete в моей модели ViewModel, и она «доступна» через «Команды». Я очень новичок в WPF и MVVM, и я просто пытаюсь найти лучшие практики, но я не очень компетентен сам по себе. Кроме того, с удалением, например, я удаляю элемент из списка (очевидно, элемент пользовательского интерфейса), а также из проводника решений (я занят расширением VS), и этот последний занимает пару секунд. Поэтому я не уверен, как мне не нужно обращаться к элементу пользовательского интерфейса, как вы заявили? – Igavshne

+0

Функцию New/Edit/Delete следует реализовать в модели представления. Вместо того, чтобы напрямую установить свойство Visibility для ProgressBar, вы устанавливаете значение свойства source, которое вы привязываете к ProgressBar. Я полагаю, что ваши операции фактически выполняют некоторую работу, которая может занять некоторое время, например, для связи с базой данных или уровнем обслуживания. Если вы просто хотите удалить элемент из списка ListBox или, скорее, ObservableCollection, связанного с ListBox, вам вообще не понадобится ProgressBar. – mm8

+0

Ах да, конечно, я могу установить значение свойства source, связанного с ProgressBar. Да, у меня есть связь с БД. Спасибо, я попробую ответить, а потом вернусь. – Igavshne

0

В C# вы можете использовать инструмент progressBar из панели инструментов, чтобы показать неопределенное время.

Чтобы использовать progressBar, просто перетащите его в свою форму.

Теперь, придя к основной проблеме, вы хотите показать неопределенное время. Чтобы показать прогресс в ProgressBar, используйте таймер и следующий код:

int value = 0; 
private void timer1_Tick(object sender, EventArgs e) 
    { 
     if (value < 100)//value at 100 can be any large integer since indeterminant time 
     { 
      value++; 
      progressBar1.Value = value; 
     } 

    } 

набор timer1.Interval = 100;

Значение переменной - это максимальное значение, установленное для progressBar.

Поскольку вы не знаете времени, установите максимальное значение progressBar на 10000 или любое другое большое значение. Теперь включите таймер при вводе вашей функции (например, New/Edit/Delete) и отключите таймер при выходе из функции.

+0

Я не литий Это решение. Вы просто «обманываете» значение индикатора выполнения. Вместо этого можно использовать свойство неопределенности индикатора выполнения, как указано в ответе на @ mm8. –

+0

Это может быть обман, но это сработает. Теперь главное, что вы не говорите пользователю о том, сколько времени требуется приложению для выполнения этих задач, следовательно, неопределенное время. Поэтому, по моему мнению, вам не нужно показывать индикатор выполнения на 100%, когда задачи выполняются приложением. –

+0

Я не думаю, что это хорошая практика программирования. Тот, кто должен поддерживать код после меня, наверняка потеряет время, пытаясь понять, что происходит. – Igavshne