有一种解决方案,很多人都将其作为自己的解决方案重新发布。可以在这里找到:
http://www.a2zdotnet.com/View.aspx?id=66
问题在于它确实会调整您的 UI 大小。因此,下一个链接采用先前的解决方案,并在完成后将大小调整回原始大小。这确实有效,尽管我不禁想到某处可能有更优雅的解决方案:
http://www.slickthought.net/post/2009/05/26/Visual-Tree-Printing-in-WPF-Applications.aspx
Slickthought.net 域已失效。 Wayback Machine 来救援。
https://web.archive.org/web/20130603071346/http://www.slickthought.net/post/2009/05/26/Visual-Tree-Printing-in-WPF-Applications.aspx
<Button Content="Print" Command="{Binding Path=PrintCommand}" CommandParameter="{Binding ElementName=ReportPanel}"></Button>
这里有两件重要的事情需要注意。首先,我使用 WPF 命令来启动打印过程。您不必这样做,但它让我可以非常干净地将演示者与 UI 联系起来。第二件事是CommandParameter。它传入对 ReportPanel 的引用。 ReportPanel 只是一个 WPF 网格控件,它包含标题 TextBlock 和一个包含实际图表的列表框。简化的 XAML 是:
<Grid x:Name="ReportPanel" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock />
<ListBox/>
</Grid>
建立了 UI,让我们跳转到代码。当用户单击打印按钮时,将执行以下 WPF 命令:
this.PrintCommand = new SimpleCommand<Grid>
{
CanExecuteDelegate = execute => true,
ExecuteDelegate = grid =>
{
PrintCharts(grid);
}
};
这是非常简单的东西。 SimpleCommand 实现了 ICommand 接口,并让我传入一些 lambda 表达式,这些表达式定义了在触发此命令时要运行的代码。显然,魔法发生在 PrintCharts(grid) 调用中。下面显示的代码与您在 Pankaj 的文章中找到的代码基本相同,但有一些修改以红色突出显示。
private void PrintCharts(Grid grid)
{
PrintDialog print = new PrintDialog();
if (print.ShowDialog() == true)
{
PrintCapabilities capabilities = print.PrintQueue.GetPrintCapabilities(print.PrintTicket);
double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / grid.ActualWidth,
capabilities.PageImageableArea.ExtentHeight / grid.ActualHeight);
Transform oldTransform = grid.LayoutTransform;
grid.LayoutTransform = new ScaleTransform(scale, scale);
Size oldSize = new Size(grid.ActualWidth, grid.ActualHeight);
Size sz = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
grid.Measure(sz);
((UIElement)grid).Arrange(new Rect(new Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight),
sz));
print.PrintVisual(grid, "Print Results");
grid.LayoutTransform = oldTransform;
grid.Measure(oldSize);
((UIElement)grid).Arrange(new Rect(new Point(0, 0),
oldSize));
}
}
好的,这些修改是什么?最明显的是,我用作为命令的一部分传入的 Grid 控件替换了原始 this 对象(在原始代码中表示整个应用程序窗口)的使用。所以所有的测量和转换都是使用网格执行的。另一个变化是我也保存了网格的原始变换和大小。原因是当您转换 Grid 以适应打印页面时,它会导致实际应用程序 UI 也发生变化。这在您的屏幕上看起来不太好,因此在将网格发送到打印机后,我将其转换回其原始屏幕布局。