2012-03-12 48 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線程上運行所有東西。這意味着,當繁重的代碼正在運行時,您將阻止用戶界面重新繪製,因此validationProfile不會更新,直到方法結束,IsBusy設置爲false。

你需要做的是將繁重的代碼處理成一個新的線程,它可以同時更新UI。

在由Brian拉古納斯,擴展工具包的創作者寫這篇博客文章請看: http://elegantcode.com/2011/10/07/extended-wpf-toolkitusing-the-busyindicator/

他解釋瞭如何使用BusyIndi​​cator控件與一個BackgroundWorker。

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

在XAML代碼忙碌的指標沒有任何內容。把一些控制(S)到它:

<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 block中使用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(); 
    } 
相關問題