在一页上打印 WPF 窗口 [英] Printing of WPF Window on one page

查看:55
本文介绍了在一页上打印 WPF 窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am able to print the current Window using the following code:

PrintDialog printDialog = new PrintDialog();
if (printDialog.ShowDialog().GetValueOrDefault(false))
{
    printDialog.PrintVisual(this, this.Title); 
}

然而,如果 Window 不适合页面,它会被截断.如何使 Window 适合页面?
我想我需要先制作一个图形元素并检查此图形是否适合页面,但到目前为止我什么也没找到.

However if the Window does not fit the page it get truncated. How do I make the Window fit the Page ?
I guess I need to make a graphics element first and check if this graphics fits the page, but I have found nothing so far.

推荐答案

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

There is one solution out there that lots of people are reposting as their own. It can be found here:

http://www.a2zdotnet.com/View.aspx?id=66

问题在于它确实调整了您的用户界面的大小.因此,下一个链接采用先前的解决方案,并在完成后将其大小调整回原始大小.这确实有效,尽管我不禁想到某个地方可能有更优雅的解决方案:

The problem w/ that is that it does resize your UI. So this next link takes the previous solution and resizes back to the original size when it's done. This does work, although I can't help but to think there's likely a more elegant solution out there somewhere:

http://www.slickthought.net/post/2009/05/26/Visual-Tree-Printing-in-WPF-Applications.aspx

Slickthought.net 域已失效.救援机器.

Slickthought.net domain is defunct. Wayback Machine to the rescue.

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 联系起来.第二件事是命令参数.它正在传递对 ReportPanel 的引用.ReportPanel 只是一个 WPF 网格控件,它包装了标题 TextBlock 和一个包含实际图表的列表框.简化的 XAML 是:

There are two important things to note here. First, I am using a WPF command to start the printing process. You don't have to do it this way, but it lets me tie the presenter to the UI pretty cleanly. The second thing is the CommandParameter. It is passing in a reference to the the ReportPanel. ReportPanel is just a WPF Grid control that wraps the title TextBlock and a Listbox that contains the actual charts. The simplified XAML is:

<Grid x:Name="ReportPanel" > 
    <Grid.RowDefinitions> 
        <RowDefinition Height="Auto" /> 
        <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 
    <TextBlock /> 
    <ListBox/>
</Grid>

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

With that UI established, lets jump to the code. When the user clicks the Print button, the following WPF command is executed:

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

这是非常简单的事情.SimpleCommand 实现了 ICommand 接口,并允许我传入一些 lambda 表达式来定义当这个命令被触发时我想要运行的代码.显然,魔法发生在 PrintCharts(grid) 调用中.下面显示的代码与您在 Pankaj 的文章中找到的代码基本相同,其中有一些修改以红色突出显示.

This is pretty simple stuff. SimpleCommand implements the ICommand interface and lets me pass in some lambda expressions defining the code I want to run when this command is fired. Clearly, the magic happens in the PrintCharts(grid) call. The code shown below is basically the same code you would find in Pankaj’s article with a couple of modification highlighted in red.

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 发生变化.这在您的屏幕上看起来不太好,因此在将网格发送到打印机后,我将其转换回其原始屏幕布局.

All right, what are these modifications? The most obvious is that I am replacing the use of the original this object (which represented the entire application window in the original code) with the Grid control that was passed in as part of the Command. So all of the measurements and transforms are executed using the Grid. The other change is that I have save the original Transform and Size of the Grid as well. The reason is that when you transform the Grid to fit to the printing page, it causes the actual application UI to change as well. This doesn't look so good on your screen, so after sending the Grid to the printer, I transform it back to its original screen layout.

这篇关于在一页上打印 WPF 窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆