2012-03-12 45 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(); 
    } 
相关问题