2012-03-12 2 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에 함께 BusyIndicator을 사용하는 방법에 대해 설명합니다.

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> 

는, 그 컨트롤을 사용할 수되고 BusyIndicator은 그들 위에 나타납니다 그것으로 일부 제어 (들)을 넣습니다.

전체 <Grid Background="LightGray">을 BusyIndicator로 묶고 싶습니다.

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(); 
    } 
관련 문제