Печать окна WPF на одной странице

Я могу напечатать текущий Window используя следующий код:

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

Однако если Window не умещается на страницу, она усекается. Как мне сделать Window соответствовать странице?
Я думаю, мне нужно сначала сделать графический элемент и проверить, подходит ли эта графика к странице, но я пока ничего не нашел.

1 ответ

Решение

Есть одно решение, которое многие люди публикуют как свои собственные. Это можно найти здесь:

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

Проблема в том, что он изменяет размер вашего интерфейса. Таким образом, эта следующая ссылка берет предыдущее решение и изменяет размер до исходного размера, когда это будет сделано. Это работает, хотя я не могу не думать, что где-то есть более элегантное решение:

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 для запуска процесса печати. Вам не нужно делать это таким образом, но это позволяет мне довольно четко привязать докладчика к пользовательскому интерфейсу. Второе - это CommandParameter. Он передает ссылку на ReportPanel. ReportPanel - это просто элемент управления WPF Grid, который обертывает заголовок TextBlock и список, содержащий фактические диаграммы. Упрощенный XAML это:

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

С установленным интерфейсом давайте перейдем к коду. Когда пользователь нажимает кнопку "Печать", выполняется следующая команда WPF:

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

Это довольно простые вещи. SimpleCommand реализует интерфейс ICommand и позволяет мне передавать некоторые лямбда-выражения, определяющие код, который я хочу запустить при запуске этой команды. Очевидно, что магия происходит в вызове PrintCharts (grid). Код, показанный ниже, в основном тот же код, который вы найдете в статье Панкаджа с парой модификаций, выделенных красным.

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)); 
  } 
}

Хорошо, что это за модификации? Наиболее очевидным является то, что я заменяю использование исходного объекта this (который представлял все окно приложения в исходном коде) на элемент управления Grid, который был передан как часть команды. Таким образом, все измерения и преобразования выполняются с использованием сетки. Другое изменение заключается в том, что я также сохранил исходную трансформацию и размер сетки. Причина в том, что когда вы преобразуете сетку, чтобы она соответствовала печатной странице, это также приводит к изменению фактического пользовательского интерфейса приложения. На вашем экране это выглядит не очень хорошо, поэтому после отправки Grid на принтер я преобразую его обратно в исходное расположение экрана.

Другие вопросы по тегам