Я могу распечатать ток Window
использование следующего кода:
PrintDialog printDialog = new PrintDialog();
if (printDialog.ShowDialog().GetValueOrDefault(false))
{
printDialog.PrintVisual(this, this.Title);
}
Однако, если Window
не соответствует странице, это становится усеченным. Как я делаю Window
соответствовать Странице?
Я предполагаю, что должен сделать графический элемент сначала и проверку, если эта графика соответствует странице, но я ничего не нашел до сих пор.
Есть одно решение, которое многие люди перепостили как свое собственное. Его можно найти здесь:
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 в помощь.
<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 сетки. Причина в том, что когда вы трансформируете сетку для подгонки к странице печати, это приводит к изменению пользовательского интерфейса приложения. Это не очень хорошо выглядит на экране, поэтому после отправки сетки на принтер я преобразовываю ее обратно в исходный экранный макет.