2010-03-18 114 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事件 - 就像在屏幕上绘制图像一样。