2010-03-18 67 views
1

我將在前言中聲明我是WPF編程的新手,可能會犯多個錯誤。任何可以提供幫助我提高技能的洞察力都將不勝感激。WPF:更新不更新屏幕的控件的可見性

我有一個WPF應用程序的工作和我通過包含描述應建立在動態,並自動打印的文檔屬性的對象列表循環。我試圖在界面上顯示一個小網格,顯示正在打印之前正在構建的文檔。這有兩個目的:一,它允許用戶看到正在由應用程序完成的工作。二,它呈現在屏幕上的項目,以便我可以有實際打印,因爲WPF似乎無法加載圖像進行動態打印,而不顯示在屏幕上。在我的代碼中,我設置了網格中的各種元素,並將可見性設置爲可見。但是,用戶界面並未更新,並且打印的文檔看起來並不像預期的那樣,因爲圖像永遠不會顯示在屏幕上。

這裏是我已經設置了

<Grid x:Name="LayoutRoot" Background="Black"> 
<Grid Name="previewGrid" Grid.Row="1" Grid.Column="1" Background="White" Visibility="Hidden"> 
<Canvas Name="pageCanvas" HorizontalAlignment="Center" VerticalAlignment="Center"> 
<Grid Name="pageGrid" Width="163" Height="211"> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="81.5"></ColumnDefinition> 
        <ColumnDefinition Width="81.5"></ColumnDefinition> 
       </Grid.ColumnDefinitions> 
       <TextBlock Grid.Column="0" Name="copyright" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Bottom"></TextBlock> 
       <Image Name="pageImage" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"></Image> 
      </Grid> 
     </Canvas> 
.....canvas for pages 2-4 not shown but structure is the same as for pageGrid..... 
</Grid> 
</Grid>  
</Window> 

這裏是後面的代碼是應該設置的元素XAML。

Dim bmp as new Bitmapimage 
previewGrid.Visibility = Windows.Visibility.Visible 
pageURI = New Uri(pageCollection(i).iamgeURL, UriKind.Absolute) 
      pageGrid.Visibility = Windows.Visibility.Visible 
      bmp.BeginInit() 
      bmp.UriSource = cardURI 
      bmp.EndInit() 
      pageImage.Source = bmp 
      copyright.Text = copyrightText 
      cardPreviewGrid.UpdateLayout() 
' More code that prints the visual element pageCanvas 
previewGrid.Visibility = Windows.Visibility.Hidden 

代碼隱藏中的代碼會循環多次,具體取決於用戶打印的文檔數量。基本上,它爲頁面構建了一個可視化元素,打印了XPS版本,然後構建下一頁並打印出來,等等。一旦處理了所有頁面,作業實際上就會發送到打印機。此應用程序的唯一目的是讓用戶打印這些文檔,以便在文檔打印時他們可以在應用程序中執行其他任務。我認爲把這個任務放在後臺線程中有助於更新UI,但是由於我試圖直接在UI線程上操作項目,因此看起來這個選項對我不起作用。我在這裏做錯了什麼,以及如何改進代碼,以便我可以獲得我想要實現的行爲?

回答

0

我不能打印的問題發言,但你的UI不是去當UI線程執行該代碼來獲取所有更新。它不能;它正忙於執行此代碼。

如果要在執行長時間運行的任務時動態更新用戶界面,則需要在後臺線程上執行任務,並定期使用Invoke()更新UI線程上的對象 - 或者更簡單一些要管理經驗,請使用BackgroundWorker

可能會出現一些完全不同的問題;我無法真正瞭解你發佈的內容。但我很確定這是你問題的一個重要部分。

編輯

哎呀,也許我應該讀你的整個問題,不只是它最初吸引我的注意的位。

好吧,我不知道這種做法會如何可行的是在您的情況,但是:該BackgroundWorker可以提高事件的任務運行;如果您致電ReportProgress,則會引發ProgressChanged事件。 ProgressChanged事件在UI線程上運行,我相信DoWork方法會阻塞並等待事件處理程序完成。

你的情況有點奇怪,後臺進程並沒有真正做任何事情。你的DoWork方法基本上只會保持呼叫ReportProgress,直到完成。

另一種方法是使用計時器。將要更新UI的圖像(或加載圖像的對象)放入隊列中,並設置一個計時器,以便其Tick事件處理程序處理隊列中的第一個項目。事件處理程序會停止計時器,處理當前的工作項,然後以十分之一秒的間隔再次啓動計時器。最終的結果是,在處理完每個圖像後,UI將有十分之一秒處理任何待處理的UI事件 - 就像在屏幕上繪製圖像一樣。