2012-03-12 14 views
0

コードを変更しましたが、もう別の問題があります。 InvalidOperation例外は、ユーザー情報の検証時にifステートメント内で発生します。それは、別のスレッドがそれを所有しているため、呼び出し元のスレッドはこのオブジェクトにアクセスできないと言います。すべてのsugestions?UI内でビジーインジケータコントロールを表示

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; 
    } 

答えて

1

あなたがここでやっていることは、UIスレッドですべてを実行していることです。これは、重いコードが実行されている間、UIを再描画しないようにブロックしているため、メソッドの終わり(IsBusyがfalseに設定されている)までvalidationProfileは更新されません。あなたがする必要がどのような

は同時にUIを更新することができ、新しいスレッド、に重いコードを処理することです。

はブライアンLagunas、拡張ツールキットの作成者によって書かれたこのブログの記事を見てみましょう: http://elegantcode.com/2011/10/07/extended-wpf-toolkitusing-the-busyindicator/

を彼はBackgroundWorkerのでBusyIndi​​catorを使用する方法について説明します。

0

重いプロセスを実行し、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(); 
    } 
} 
1

あなたのXAMLコード内のビジーインジケータは、任意のコンテンツを持っていない:これは、バックグラウンド・プロセスが

例えば実行されても、UIを更新するのに役立ちます。そこにいくつかのコントロール(複数可)を入れて:

<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">をラップするとします。

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(); 
    }