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

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

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

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

6
задан Dave Clemmer 18 September 2011 в 04:10
поделиться

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, в который обернут текстовый блок заголовка и Listbox, содержащий собственно графики. Упрощенный XAML выглядит так:

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

Когда пользовательский интерфейс создан, перейдем к коду. Когда пользователь нажимает кнопку Print, выполняется следующая команда 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, который был передан как часть команды Command. Таким образом, все измерения и преобразования выполняются с помощью Grid. Другое изменение заключается в том, что я сохранил оригинальные Transform и Size сетки. Причина в том, что когда вы трансформируете сетку для подгонки к странице печати, это приводит к изменению пользовательского интерфейса приложения. Это не очень хорошо выглядит на экране, поэтому после отправки сетки на принтер я преобразовываю ее обратно в исходный экранный макет.

8
ответ дан 16 December 2019 в 21:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: