2016-02-23 62 views
1

我已經設法解決了如何以編程方式更改WPF窗體中的圖像,但我真的很努力解決如何立即執行此操作。我有一個在多個進程的進展報告的GUI,下面的代碼工作,以改變形象:WPF立即更改圖像源

cacheBuilderStatus.Source = new BitmapImage(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox-complete.png")); 

但這並不即時更新的形象,我很茫然如何,我力重繪GUI。我已經試過這兩個但又似乎都不產生任何影響:

 cacheBuilderStatus.InvalidateVisual(); 
     cacheBuilderStatus.UpdateLayout(); 

我甚至想這無濟於事:

 BitmapImage cbImage = new BitmapImage(); //(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox.png")); 
     cbImage.BeginInit(); 
     cbImage.CacheOption = BitmapCacheOption.None; 
     cbImage.UriCachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache); 
     cbImage.CacheOption = BitmapCacheOption.OnLoad; 
     cbImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache; 
     cbImage.UriSource = new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox.png"); 
     cbImage.EndInit(); 

如果有人可以幫助我瞭解如何做到這一點,我會非常感謝。

謝謝。

編輯:有問題的圖像的XAML是:

  <Image x:Name="cacheBuilderStatus" Grid.Row="0" Grid.Column="3" HorizontalAlignment="Center" Width="20" Source="Resources/checkbox.png"/> 

,並在後臺的代碼如下所示:

 // Reset progress images 
    private void resetStatus() 
    { 
     BitmapImage cbImage = new BitmapImage(); //(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox.png")); 
     cbImage.BeginInit(); 
     cbImage.CacheOption = BitmapCacheOption.None; 
     cbImage.UriCachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache); 
     cbImage.CacheOption = BitmapCacheOption.OnLoad; 
     cbImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache; 
     cbImage.UriSource = new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox.png"); 
     cbImage.EndInit(); 

     cacheBuilderStatus.InvalidateVisual(); 
     cacheBuilderStatus.UpdateLayout(); 

     cacheBuilderStatus.Source = cbImage; 
     ciUserStatus.Source = new BitmapImage(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox.png")); 
     accessCiUserStatus.Source = new BitmapImage(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox.png")); 
     configItemStatus.Source = new BitmapImage(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox.png")); 
     enumerationsStatus.Source = new BitmapImage(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox.png")); 
     serviceOfferingStatus.Source = new BitmapImage(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox.png")); 
     workItemStatus.Source = new BitmapImage(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox.png")); 
     websiteStatus.Source = new BitmapImage(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox.png")); 
     appPoolStatus.Source = new BitmapImage(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox.png")); 
    } 


    // Buttons event handlers 
    // Restart portal 
    private void primaryToggleButton_Checked(object sender, RoutedEventArgs e) 
    { 
     // Result variables 
     string serviceRestartResult; 
     bool cIUserResult; 
     bool accessUserWIResult; 
     bool configurationItemsResult; 
     bool enumerationResult; 
     bool serviceOfferingResult; 
     bool workItemResult; 
     string websiteRestartResult; 
     string appPoolRestartResult; 

     // Pull timeout variables from app.config 
     serviceStatusChangeTimeout = Int32.Parse(ConfigurationManager.AppSettings.Get("serviceStatusChangeTimeout")); 
     websiteStatusChangeTimeout = Int32.Parse(ConfigurationManager.AppSettings.Get("websiteStatusChangeTimeout")); 

     // Get current DateTIme for LastModified tests 
     DateTime time = DateTime.Now.ToUniversalTime(); 


     // Reset status images 
     resetStatus(); 
     Thread.Sleep(5000); 

     // Service restart 
     serviceRestartResult = MidTier.ServiceRestart(serviceStatusChangeTimeout); 
     if (serviceRestartResult == "Success") 
     { 
      // If success set service status icon to completed image 
      cacheBuilderStatus.Source = new BitmapImage(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox-complete.png")); 
     } 
     else 
     { 
      // If fail set image to failed red cross, display error text and error text margin to 5 and height to Auto. 
      cacheBuilderStatus.Source = new BitmapImage(new Uri("pack://application:,,,/WpfCustomControlLibrary1;component/Resources/checkbox-error.png")); 
      displayErrorText(serviceRestartResult); 
     } 
+3

「但是,這並不更新圖像瞬間」它應該。你是否可能在UI線程中進行循環或其他阻塞操作? – Clemens

+0

發佈cacheBuilderStatus聲明/ XAML。 – GazTheDestroyer

+0

切換的圖像總是相同的,或者它們是在更改它們時生成的?你如何在Xaml中綁定圖像?也許你只需要將UpdateSourceTrigger設置爲PropertyChanged併爲綁定到圖像的屬性正確地引發屬性已更改的事件。或者如果圖像總是相同的,你可以使用轉換器,而不是改變圖像改變下劃線的值 –

回答

0

您的代碼來改變圖像看起來很好,並應立即更新。我認爲你的問題在於你在UI線程上處理了一些信息,因此它不會更新。

您的處理應該始終移動到後臺線程,否則您將鎖定UI線程直到完成並且無法更新。

例如,如果你這樣做:

private void button_Click(object sender, RoutedEventArgs e) 
{ 
    myImage.Source = new BitmapImage(new Uri(@"e:\icons\transfer1.ico")); 
} 

它會立刻更新。但是,如果你在那裏做處理喜歡所以它不會:

private void button_Click(object sender, RoutedEventArgs e) 
{ 
    myImage.Source = new BitmapImage(new Uri(@"e:\icons\transfer1.ico")); 
    Thread.Sleep(5000); //simulate doing stuff 
} 

因此,而不是做處理在不同的線程像這樣:

private async void button_Click(object sender, RoutedEventArgs e) 
{ 
    myImage.Source = new BitmapImage(new Uri(@"e:\icons\transfer1.ico")); 

    await Task.Run(() => 
     { 
      //Do work here 
      Thread.Sleep(5000); 
     }); 
} 
+0

謝謝!這正是問題所在。 – Exitialis