2013-10-03 25 views
0

這段代碼是用於生成XPS文檔的一些代碼的一部分。 XPS文件生成不是玩笑。如果可能的話,我希望避免粘貼任何XPS代碼。相反,這段代碼重點關注問題的WPF部分。如何識別固定頁面的尺寸

我要求你幫忙的問題就在這裏。我已經硬編碼的尺寸爲測試圖像的工作:

double magicNumber_X = 3.5;//trial and error...3 too small 4 too big 
fixedPage.Arrange(new Rect(new Point(magicNumber_X, 0), size)); 

相反,我怎麼能解決這個代碼來計算的座標?

完整的方法:

private PageContent AddContentFromImage() 
    { 
     var pageContent = new PageContent(); 
     var fixedPage = new FixedPage();    

     var bitmapImage = new BitmapImage(new Uri(hardCodedImageSampleFilePath, UriKind.RelativeOrAbsolute)); 

     var image = new Image(); 
     image.Source = bitmapImage;    
     fixedPage.Children.Add(image); 

     ((IAddChild)pageContent).AddChild(fixedPage); 

     double pageWidth = 96 * 8.5;//XPS documents are 96 units per inch 
     double pageHeight = 96 * 11; 

     fixedPage.Width = pageWidth; 
     fixedPage.Height = pageHeight; 

     var size = new Size(8.5 * 96, 11 * 96); 

     fixedPage.Measure(size); 
     double magicNumber_X = 3.5;//trial and error...3 too small 4 too big 
     double magicNumber_Y = 0; 
     fixedPage.Arrange(new Rect(new Point(magicNumber_X, magicNumber_Y), size)); 
     fixedPage.UpdateLayout(); 

     return pageContent; 
    } 

我有點驚訝FixedPage.Measure(size)本身並不解決問題。我嘗試不通過參數,例如fixedPage.Arrange(new Rect(), size))仍然沒有去。

FWIW,這個計算在我使用PrintDocument的時候工作得很好。

private void pd_PrintPage(object sender, PrintPageEventArgs e) 
    { 
     Graphics g = e.Graphics; 
     RectangleF marginBounds = e.MarginBounds; 
     RectangleF printableArea = e.PageSettings.PrintableArea; 

     int availableWidth = (int)Math.Floor(printDocument.OriginAtMargins ? marginBounds.Width : (e.PageSettings.Landscape ? printableArea.Height : printableArea.Width)); 
     int availableHeight = (int)Math.Floor(printDocument.OriginAtMargins ? marginBounds.Height : (e.PageSettings.Landscape ? printableArea.Width : printableArea.Height)); 

     Rectangle rectangle = new Rectangle(0,0, availableWidth -1, availableHeight - 1);   
     g.DrawImage(_image, rectangle); 
+0

如果您的magicNumber_X爲0,會發生什麼情況?如果它是4呢?您的圖片是否被頁面邊緣剪輯? – Jon

+0

@Jon是的,確切地說...裁剪髮生在實體印刷品上。只有魔術「3.5」沒有剪裁。要清楚XPS文件本身顯示沒有裁剪......只有物理印刷。 –

+0

大多數打印機在頁面邊緣都有一個不可打印的區域。如果您查看PrintCapabilities.PageImageableArea屬性,則應該找到適合您的圖像的偏移和範圍。這確實意味着您在創建XPS文檔之前需要了解您的目標打印機。或者,您可以假定頁面周圍有半英寸的邊距,這應該會覆蓋大多數打印機。 – Jon

回答

0

我鉤入FixedPage.Loaded事件因爲FixedPage.ActualHeight是爲了執行計算所需的,不會被置位,直到該控制已加載。這也意味着使用此機制必須顯示FixedPage才能正確執行自動打印。

void fixedPage_Loaded(object sender, RoutedEventArgs e) 
    { 
     var fixedDocument = sender as FixedPage; 
     CalculateSize(fixedDocument); 
    } 
    private void CalculateSize(FixedPage fixedPage) 
    { 
     PrintQueue printQueue = LocalPrintServer.GetDefaultPrintQueue(); 
     PrintCapabilities capabilities = printQueue.GetPrintCapabilities(); 

     //get scale of the print wrt to screen of WPF visual 
     double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth/fixedPage.ActualWidth, capabilities.PageImageableArea.ExtentHeight/fixedPage.ActualHeight); 

     //Transform the Visual to scale 
     fixedPage.LayoutTransform = new ScaleTransform(scale, scale); 

     //get the size of the printer page 
     var sz = new Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight); 

     //update the layout of the visual to the printer page size. 
     fixedPage.Measure(sz); 
     double x = capabilities.PageImageableArea.OriginWidth; 
     double y = capabilities.PageImageableArea.OriginHeight; 
     fixedPage.Arrange(new Rect(new Point(x, y), sz)); 
     fixedPage.UpdateLayout(); 
    }