0

コードを変更しましたが、別の問題が発生しました。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

4 に答える 4

1

ここで行っているのは、UIスレッドですべてを実行することです。これは、重いコードの実行中にUIの再描画をブロックしているため、IsBusyがfalseに設定されているメソッドの最後までvalidationProfileが更新されないことを意味します。

あなたがする必要があるのは、重いコードを新しいスレッドに処理することです。それは同時にUIを更新することができます。

ExtendedToolkitの作成者であるBrianLagunasによって書かれたこのブログ投稿を見てください:http: //elegantcode.com/2011/10/07/extended-wpf-toolkitusing-the-busyindicator/

彼は、BackgroundWorkerでBusyIndi​​catorを使用する方法を説明します。

于 2012-03-12T09:35:15.937 に答える
1

XAMLコードのビジーインジケーターにはコンテンツがありません。それにいくつかのコントロールを入れてください:

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

ビジーに変更すると、これらのコントロールは無効になり、BusyIndi​​catorがその上に表示されます。

BusyIndi​​catorで全体をラップしたいと思います<Grid Background="LightGray">

于 2012-03-12T10:11:58.150 に答える
0

バックグラウンド ワーカーまたは新しいスレッドを使用して負荷の高いプロセスを実行し、UI スレッドを解放します。これにより、バックグラウンド プロセスが実行されている場合でも UI を更新できます。

例えば:

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();
    }
}
于 2012-03-12T09:51:51.667 に答える
0

私はついにそれを理解します。worker.DoWork ブロック内で UI オブジェクトを使用することはできません。コードを少し修正したところ、動作するようになりました。

 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();
    }
于 2012-03-13T10:51:07.253 に答える