Отображение управления индикатором занятости в пользовательском интерфейсе - PullRequest
0 голосов
/ 12 марта 2012

Я изменил код, но теперь у меня есть другая проблема.Исключение InvalidOperation возникает внутри оператора if при проверке информации о пользователе.В нем говорится, что вызывающий поток не может получить доступ к этому объекту, поскольку он принадлежит другому потоку. Любые предложения?

 private void finishConfigButton_Click(object sender, RoutedEventArgs e)
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerSupportsCancellation = true;
        bool validated = false;

        errorLabel.Visibility = System.Windows.Visibility.Collapsed;
        validationProfile.IsBusy = true;
        finishConfigButton.IsEnabled = false;
        backToLoginHyperlink.IsEnabled = false;

        worker.DoWork += (o, ea) =>
        {
            if (newUser.ValidateNewUserInformation(newNameTextBox.Text, newEmailTextBox.Text, newUsernameTextBox.Text, newPasswordPasswordBox.Password, ref errorLabel))
            {
                validated = true;

                string activeDir = Environment.SystemDirectory.Substring(0, 1) + @":\Users\" + Environment.UserName + @"\My Documents\SSK\Users";
                string newPath = System.IO.Path.Combine(activeDir, newUser.Username);
                Directory.CreateDirectory(newPath);

                newUser.SaveUserData(newUser);

                newPath = System.IO.Path.Combine(activeDir, newUser.Username + @"\Settings");
                Directory.CreateDirectory(newPath);

                newUserSettings.SetDefaultValues();
                newUserSettings.SaveSettings(newUser, newUserSettings);
            }
            else
                validated = false;

            if (worker.CancellationPending)
            {
                ea.Cancel = true;
                return;
            }
        };

        worker.RunWorkerCompleted += (o, ea) =>
        {
            validationProfile.IsBusy = false;
            finishConfigButton.IsEnabled = true;
            backToLoginHyperlink.IsEnabled = true;
        };

        worker.RunWorkerAsync(this);

        if (validated)
        {
            IntelliMonitorWindow intelliMonitor = new IntelliMonitorWindow(newUser, newUserSettings);
            intelliMonitor.Show();
            this.Close();
        }
        else
            errorLabel.Visibility = System.Windows.Visibility.Visible;
    }

Ответы [ 4 ]

1 голос
/ 12 марта 2012

В индикаторе занятости в вашем коде XAML нет содержимого. Поместите некоторые элементы управления в него:

<wpfet:BusyIndicator Name="validationProfile" IsBusy="False" BusyContent="Working...Please wait"  DisplayAfter="0" Background="DimGray">
    <Grid>
        ...
    </Grid>
</wpfet:BusyIndicator>

Если вы перейдете в состояние занятости, эти элементы управления будут отключены, а над ними появится BusyIndicator.

Полагаю, вы хотите обернуть все <Grid Background="LightGray"> с помощью BusyIndicator.

1 голос
/ 12 марта 2012

То, что вы делаете здесь, это запуск всего в потоке пользовательского интерфейса. Это означает, что во время выполнения тяжелого кода вы блокируете пользовательский интерфейс от перекрашивания, и, следовательно, validationProfile не обновляется до конца метода, где IsBusy имеет значение false.

Что вам нужно сделать, это обработать тяжелый код в новый поток, который может одновременно обновлять пользовательский интерфейс.

Посмотрите на этот пост, написанный Брайаном Лагунасом, создателем Extended Toolkit: http://elegantcode.com/2011/10/07/extended-wpf-toolkitusing-the-busyindicator/

Он объясняет, как использовать BusyIndicator с BackgroundWorker.

0 голосов
/ 13 марта 2012

Я наконец понял это. Вы не можете использовать объекты пользовательского интерфейса внутри блока worker.DoWork. Я немного изменил код, и теперь он работает.

 private void finishConfigButton_Click(object sender, RoutedEventArgs e)
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerSupportsCancellation = true;

        errorLabel.Visibility = System.Windows.Visibility.Collapsed;
        validationProfile.IsBusy = true;
        finishConfigButton.IsEnabled = false;
        backToLoginHyperlink.IsEnabled = false;

        bool validated = false;
        string newName = newNameTextBox.Text;
        string newEmail = newEmailTextBox.Text;
        string newUsername = newUsernameTextBox.Text;
        string newPassword = newPasswordPasswordBox.Password;
        string errorMessage = "Unknown error.";

        worker.DoWork += (o, ea) =>
        {
            if (newUser.ValidateNewUserInformation(newName, newEmail, newUsername, newPassword, ref errorMessage))
            {
                string activeDir = Environment.SystemDirectory.Substring(0, 1) + @":\Users\" + Environment.UserName + @"\My Documents\SSK\Users";
                string newPath = System.IO.Path.Combine(activeDir, newUser.Username);
                Directory.CreateDirectory(newPath);

                newUser.SaveUserData(newUser);

                newPath = System.IO.Path.Combine(activeDir, newUser.Username + @"\Settings");
                Directory.CreateDirectory(newPath);

                newUserSettings.SetDefaultValues();
                newUserSettings.SaveSettings(newUser, newUserSettings);

                validated = true;
            }
            else
                ea.Cancel = true;
        };

        worker.RunWorkerCompleted += (o, ea) =>
        {
            if (validated)
            {
                IntelliMonitorWindow intelliMonitor = new IntelliMonitorWindow(newUser, newUserSettings);
                intelliMonitor.Show();
                this.Close();
            }

            validationProfile.IsBusy = false;
            finishConfigButton.IsEnabled = true;
            backToLoginHyperlink.IsEnabled = true;
            errorLabel.Visibility = System.Windows.Visibility.Visible;
            errorLabel.Content = errorMessage;
        };

        worker.RunWorkerAsync();
    }
0 голосов
/ 12 марта 2012

Используйте фоновый рабочий или новый поток, чтобы запустить тяжелый процесс и освободить поток пользовательского интерфейса. Это поможет вам обновить пользовательский интерфейс, даже когда фоновый процесс запущен

Например:

public void finishConfigButton_Click()
{
    worker = new BackgroundWorker();

    worker.DoWork += delegate(object s, DoWorkEventArgs args)
    {
        //Do the heavy work here
    };

    worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
    {
        //Things to do after the execution of heavy work
        validationProfile.IsBusy = false;
    };

    validationProfile.IsBusy= true;
    worker.RunWorkerAsync();
    }
}
...