2011-08-26 4 views
4

Используя Silverlight 4, можно ли распечатать сетку в ландшафтном режиме и показать все содержимое? Мы создаем «страницу» как Grid и устанавливаем транспонированную высоту/ширину из PrintableArea PrintDocument. Затем мы применяем CompositeTransform для установки Rotation и TranslateX. По сути, он очень похож на solution found here.Настроить альбомную печать из Silverlight?

Это правильно обрабатывает содержимое, и все появляется, чтобы растянуть ширину (ну, высота в этом случае) страницы, но нижняя часть отсекается. Это почти похоже на содержимое, отображаемое на обычную ширину страницы (обычно 8,5 "), хотя она была отображена на высоту страницы (высота 11 дюймов). Таким образом, содержание содержимого в 2,5 дюйма выводится в виде пустого содержимого в нижней части страницы.

Примечание: Мы не вытаскиваем существующий визуальный элемент из пользовательского интерфейса, чтобы помещать его в «страницу». Мы определяем DataTemplates и передаем VM в DataContext. Все содержимое привязано и отображается правильно, насколько это возможно, но рендеринг в печатном документе - это то, что не так.

Есть ли что-то, что мы Мы надеемся избежать необходимости сначала отобразить растровое изображение страницы, но если это то, что мы должны сделать ...

ОБНОВЛЕНИЕ: Основываясь на дальнейшем расследовании (и разговаривая с парнем в команде, которая начала работать над отчетами), код очень сильно основан на Pete Brown's client side printing. Мы немного расширили его для группировки и улучшения функций отчета, но в целом обработка макета - это тот же движок.

Если вы посмотрите на код Пита Брауна, текущая разница мы используем следующая в методе GetNewPage:

... 
    this.CurrentPageNumber++; 

    Grid pagePanel = new Grid(); 
    LayoutTransformer layoutTransformer = new LayoutTransformer 
     { 
      Content = pagePanel, 
      Tag = this.CurrentPageNumber 
     }; 

    if (printableArea.Height > printableArea.Width) 
    { 
     // printable area is in Portrait mode. 
     layoutTransformer.Height = printableArea.Width; 
     layoutTransformer.Width = printableArea.Height; 
     var transform = new CompositeTransform 
     { 
      Rotation = 90, 
      TranslateX = printableArea.Width, 
      ScaleX = 1, 
      ScaleY = 1 
     }; 
     layoutTransformer.LayoutTransform = transform; 
     layoutTransformer.ApplyLayoutTransform(); 
     layoutTransformer.RenderTransform = transform; 
    } 
    else 
    { 
     // printable area is in Landscape mode 
     layoutTransformer.Height = printableArea.Height; 
     layoutTransformer.Width = printableArea.Width; 
    } 

    Size pageSize = new Size(layoutTransformer.Width, layoutTransformer.Height); 
    layoutTransformer.HorizontalAlignment = HorizontalAlignment.Stretch; 
    layoutTransformer.VerticalAlignment = VerticalAlignment.Stretch; 

    RowDefinition headerRow = new RowDefinition { Height = GridLength.Auto }; 
    RowDefinition itemsRow = new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }; 
    RowDefinition footerRow = new RowDefinition { Height = GridLength.Auto }; 

    pagePanel.RowDefinitions.Add(headerRow); 
    pagePanel.RowDefinitions.Add(itemsRow); 
    pagePanel.RowDefinitions.Add(footerRow); 
    ... 

Это прекрасно работает автоматически поворачивать содержимое, но ширина по-прежнему получать рубленые как это покажет ширину страницы, как портрет. Несмотря на то, что я изменил все измерения, которые нужно поменять местами. Кажется, что звонки InvalidateMeasure() и InvalidateArrangement() не имеют значения для изменения вывода. Странно то, что когда я меняю ScaleX на нечто большее, чем 1, он растянет обрезанный контент, чтобы заполнить больше страницы. Таким образом, это почти похоже на то, что родительский контейнер обрезается до преобразования, несмотря на то, что код указывает иначе. В основном это похоже на отсечение, которое Shawn Wildermuth blogged about. Поэтому я все еще ищу идеи/решения ...

ответ

1

Его трудно понять, в чем проблема, без каких-либо взглядов на некоторые основные Xaml. Однако я собираюсь пойти на пунт здесь.

Вы используете RenderTransform, но элемент, на котором применяется преобразование, будет сообщать контейнеру оригинальные нераспознанные измерения. В результате контейнер обрезается на основе этой информации.

Предлагаю решение включить Silverlight Toolkit в ваше приложение, в частности, управление LayoutTransformer. Поместите содержимое страницы внутри этого элемента управления. Затем LayoutTransformer примет ваш CompositeTransform в своем LayoutTransform. Разница здесь в сообщениях LayoutTransformer - это размеры после он применил преобразование. Следовательно, его контейнер не должен зажимать его.

+0

Я дам «LayoutTransformer» выстрел, но я обновил информацию об отчетности в вопросе. Не знаю, изменит ли это ваш ответ вообще. –

0

Я боролся с этой же проблемой, и для меня я нашел ответ. Я прочесываю интернет. Вот ссылка на сообщение в форуме, где я нашел свой ответ - http://forums.silverlight.net/t/237438.aspx/1?how+to+print+landscape+using+SL+print+API+

Автор есть действительно парень с ответом. Секрет, как представляется, называя InvalidateArrange и InvalidateMeasure (о, и настройки вашего контента растягиваться) ...

2

Используйте элемент управления canvas контейнера, и повернуть контролем внутри холста.

После многих часов чистого разочарования я, наконец, решил положить предмет внутрь холста. Вуаля !! Больше не обрезать.

Обратите внимание на следующее тестовое приложение SMALL для демонстрации. Это просто страница с кнопкой печати.

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Media; 
using System.Windows.Printing; 
using System.Windows.Shapes; 

namespace SilverlightApplication1 { 

    public partial class MainPage : UserControl { 

     public MainPage() { 
      InitializeComponent(); 
     } 

     private void Button_Click_1(object sender, RoutedEventArgs e) { 
      PrintDocument PD = new PrintDocument(); 
      PD.PrintPage += PD_PrintPage; 
      PD.Print("Print Test"); 
     } 

     void PD_PrintPage(object sender, PrintPageEventArgs e) { 

      Canvas OuterCanvas = new Canvas(); 

      /* a container for everything that will print */ 
      Border OuterBorder = new Border() { 
       BorderThickness = new Thickness(3), 
       BorderBrush = new SolidColorBrush(Colors.Red), 
       Margin = new Thickness(10) 
      }; 

      double Width = e.PrintableArea.Width - OuterBorder.Margin.Left - OuterBorder.Margin.Right; 
      double Height = e.PrintableArea.Height - OuterBorder.Margin.Top - OuterBorder.Margin.Bottom; 

      /* NOTE: We're trying to force landscape, so swop the width and height */ 
      OuterBorder.Width = Height; 
      OuterBorder.Height = Width; 

      /* on portrait, this line goes down (leave the printer settings, we're trying to force landscape) */ 
      Line Line = new Line() { 
       X1 = OuterBorder.Width/2, 
       Y1 = 0, 
       X2 = OuterBorder.Width/2, 
       Y2 = OuterBorder.Height, 
       Stroke = new SolidColorBrush(Colors.Blue), 
       StrokeThickness = 3 
      }; 

      OuterBorder.Child = Line; 

      OuterCanvas.Children.Add(OuterBorder); 

      /* rotate 90 degrees, and move into place */ 
      var transformGroup = new TransformGroup(); 
      transformGroup.Children.Add(new RotateTransform() { Angle = 90 }); 
      transformGroup.Children.Add(new TranslateTransform() { X = e.PrintableArea.Width }); 
      OuterBorder.RenderTransform = transformGroup; 

      e.PageVisual = OuterCanvas; 

      e.HasMorePages = false; 
     } 
    } 
} 

Если вы удалите внешний холст, это приведет к тому, что страница будет отключена, как если бы она была на портрете.

Смежные вопросы