在一页上打印WPF窗口

Nil*_*ils 6 printing wpf window

我可以Window使用以下代码打印当前的代码:

PrintDialog printDialog = new PrintDialog();
if (printDialog.ShowDialog().GetValueOrDefault(false))
{
    printDialog.PrintVisual(this, this.Title); 
}
Run Code Online (Sandbox Code Playgroud)

但是,如果Window它不适合页面,则会被截断.如何使Window页面适合?
我想我需要首先制作一个图形元素并检查这些图形是否适合页面,但到目前为止我还没有找到任何结果.

Pau*_*ett 8

有一种解决方案,很多人都将其作为自己的重新发布.在这里能找到它:

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>
Run Code Online (Sandbox Code Playgroud)

这里有两件重要的事情需要注意.首先,我使用WPF命令来启动打印过程.您不必这样做,但它让我可以非常干净地将演示者绑定到UI.第二件事是CommandParameter.它传递了对ReportPanel的引用.ReportPanel只是一个WPF网格控件,它包含标题TextBlock和包含实际图表的Listbox.简化的XAML是:

<Grid x:Name="ReportPanel" > 
    <Grid.RowDefinitions> 
        <RowDefinition Height="Auto" /> 
        <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 
    <TextBlock /> 
    <ListBox/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

建立该UI后,我们跳转到代码.当用户单击"打印"按钮时,将执行以下WPF命令:

this.PrintCommand = new SimpleCommand<Grid> 
{ 
    CanExecuteDelegate = execute => true, 
    ExecuteDelegate = grid => 
        { 
            PrintCharts(grid); 
        } 
};
Run Code Online (Sandbox Code Playgroud)

这很简单.SimpleCommand实现ICommand接口,并允许我传入一些lambda表达式,定义触发此命令时要运行的代码.显然,魔术发生在PrintCharts(网格)调用中.下面显示的代码基本上与您在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)); 
  } 
}
Run Code Online (Sandbox Code Playgroud)

好的,这些修改是什么?最明显的是,我将使用作为Command的一部分传入的Grid控件替换原始此对象(代表原始代码中的整个应用程序窗口)的使用.所以所有的测量和变换都是使用Grid执行的.另一个变化是我也保存了原始的网格变换和大小.原因是当您将网格转换为适合打印页面时,它会导致实际的应用程序UI也发生变化.这在屏幕上看起来不太好,所以在将Grid发送到打印机后,我将其转换回原来的屏幕布局.