WPF рабочее состояние - PullRequest
0 голосов
/ 10 января 2011

У меня есть сетка в моем приложении. После того, как пользователь выбирает некоторые файлы в приложении ofdialog, он выполняет некоторые вычисления. Пока приложение выполняет вычисления, похоже, что оно не отвечает. Как отобразить картинку и сделать главное окно черно-белым при расчете? Может быть, сделать какой-нибудь дп в MainWindow в стиле «IsBusy» и привязать к нему всплывающее окно с картинкой?

Как вы реализуете эту логику в своих приложениях?

Ответы [ 2 ]

2 голосов
/ 10 января 2011

Одним из простых способов является использование индикатора занятости из Extended WPF Toolkit :

Загрузите двоичные файлы и добавьте ссылку на проект в WPFToolkit.Extended.dll.

Далее добавьте следующее пространство имен в ваше «главное окно»:

xmlns:ext="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit.Extended"

Затем добавьте индикатор занятости в представление (разместите его так, чтобы при отображении он занимал весь экран). Здесь мое главное окно имеет две строки, и я хочу, чтобы элемент управления охватывал обе строки. Свойство IsBusy элемента управления связано со свойством bool в контексте данных представления.

<ext:BusyIndicator Grid.RowSpan="2" x:Name="busyIndicator" IsBusy="{Binding IsBusy}" />

Долгосрочные вычисления должны обрабатываться в другом потоке, чтобы не блокировать пользовательский интерфейс. Для работы с потоками вы можете использовать BackgroundWorker class .

1 голос
/ 10 января 2011

У вас должны быть длинные задачи в отдельном потоке, чтобы избежать блокировки пользовательского интерфейса. Вот один из способов добиться этого:

Определите фоновую нить, как показано ниже:

//Delegate that you could pass into the worker thread
public delegate void ProgressMonitor(string s);

//Call this to start background work
void StartLongRunningWork(ProgressMonitor mon)
{
    using (BackgroundWorker bgw = new BackgroundWorker())
    {
        bgw.DoWork             += WorkerThread;
        bgw.RunWorkerCompleted += WorkerThreadCompleted;
        bgw.RunWorkerAsync(mon);
    }
}

void WorkerThread(object sender, DoWorkEventArgs e)
{
    ProgressMonitor pm = (ProgressMonitor)e.Argument;
    WorkerActual(pm, <any other parameters>);
}

void WorkerActual(ProgressMonitor pm,<any other parameters>)
{
    ...
    pm("Doing x");
    Do long running task
    pm("Doing y");
    ...
}

//This function is called in case of Exception, Cancellation or successful completion
//of the background worker. Handle each event appropriately
void WorkerThreadCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error != null)
    {
        //Long running task threw an exception
    }
    else
        if (e.Cancelled)
        {
            //Long running task was cancelled
        }
        else
        {
            //Long running task was successfuly completed
        }
}

И назовите это как показано ниже:

private void UpDateProgressLabel(string s)
{
    this.Dispatcher.BeginInvoke((Action)delegate
       {
           NotificationLabel.Content = s;
       });
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    StartLongRunningWork(UpDateProgressLabel);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...