WPF:更新控件的可见性而不更新屏幕

时间:2010-03-18 21:37:25

标签: wpf user-interface

我将通过声明我是WPF编程的新手并且可能会出现多个错误来作为序言。我们非常感谢能够提供帮助我提高技能的任何见解。

我正在使用WPF应用程序并循环遍历一个对象列表,这些对象包含描述应该动态构建并自动打印的文档的属性。我试图在界面中显示一个小网格,显示正在打印的文档。这有两个目的:一,它允许用户查看应用程序正在完成的工作。二,它渲染屏幕上的项目,以便我可以实际打印一些东西,因为WPF似乎无法加载图像进行动态打印而不在屏幕上显示。在我的代码中,我在网格中设置各种元素并将可见性设置为可见。但是,UI未更新,并且打印的文档看起来并不像预期的那样,因为图像永远不会出现在屏幕上。

这是我设置的XAML

<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>

这是应该设置元素的代码。

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线程上操作项目,因此看起来这个选项对我来说不起作用。我在这里做错了什么,如何改进代码以便我能够获得我想要实现的行为?

1 个答案:

答案 0 :(得分:0)

我无法谈论打印问题,但是当UI线程执行此代码时,您的UI根本不会得到更新。它不能;它忙着执行这段代码。

如果要在执行长时间运行的任务时动态更新UI,则需要在后台线程上执行任务并定期使用Invoke()更新UI线程上的对象 - 或者,对于更安全,更易于管理,使用BackgroundWorker

可能还会有一些完全不同的问题;我无法确定你发布的内容。但我很确定这是你问题的重要部分。

修改

Jeez,也许我应该阅读你的整个问题,而不仅仅是最初引起我注意的那些问题。

好的,我不知道这种方法在你的情况下有多可行,但是:BackgroundWorker可以在任务运行时引发事件;如果您致电ReportProgress,则会引发ProgressChanged事件。 ProgressChanged事件在UI线程上运行,我相信DoWork方法会阻塞并等待事件处理程序完成。

你的情况有点奇怪的是后台进程并没有真正做任何事情。您的DoWork方法基本上只会一直调用ReportProgress直到完成。

另一种方法是使用计时器。将要更新UI的图像(或加载图像的对象)放入队列,并设置计时器,以便其Tick事件处理程序处理队列中的第一个项目。事件处理程序将停止计时器,处理当前工作项,然后以十分之一秒的间隔再次启动计时器。最终结果是,在处理完每个图像之后,UI将有十分之一秒的时间来处理任何未决的UI事件 - 比如在屏幕上绘制图像。