簡體   English   中英

WPF打印以適合頁面

[英]WPF Printing to fit page

我搜索了如何打印WPF控件的選項,並找到了一些解決方案。 我需要將我的打印控件適合打印頁面,同時保留縱橫比(我的控件是方形;數獨網格)。

我找到了一個解決方案,它調整大小並重新定位控件以適應頁面。 這很好,但它也重新定位了我的窗口控制。

這是我用於打印和縮放的代碼:

        //get selected printer capabilities
            System.Printing.PrintCapabilities capabilities = dialog.PrintQueue.GetPrintCapabilities(dialog.PrintTicket);
        //get scale of the print wrt to screen of WPF visual
        double scale = Math.Min(capabilities.PageImageableArea.ExtentWidth / mrizka.ActualWidth, capabilities.PageImageableArea.ExtentHeight / mrizka.ActualHeight);

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

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

        //update the layout of the visual to the printer page size.
        mrizka.Measure(sz);
        mrizka.Arrange(new Rect(new Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));

        dialog.PrintVisual(mrizka, mrizka.getID().ToString());

我嘗試了兩個方法來解決這個問題:

  1. 克隆我的控制,然后轉換克隆的一個,不影響原始。 沒有工作,由於某種原因我以異常結束:提供的DependencyObject不是這個Freezable的上下文,但奇怪的是僅在某些情況下。

  2. 恢復大小和位置更改。 我嘗試調用InvalidateArrange()方法,這似乎有效,但只在第一次調用print方法時才有效。 在第二次通話期間,它沒有工作。

我應該做什么,任何想法<謝謝你。

我知道這個問題很老,但我自己也在尋找解決這個問題的方法。 這是我目前使用的解決方案。 我將原始轉換存儲在框架元素中,然后在打印完成后重新應用它。

    private void Print(Visual v)
    {

        System.Windows.FrameworkElement e = v as System.Windows.FrameworkElement ;
        if (e == null)
            return;

        PrintDialog pd = new PrintDialog();
        if (pd.ShowDialog() == true)
        {
            //store original scale
            Transform originalScale = e.LayoutTransform;
            //get selected printer capabilities
            System.Printing.PrintCapabilities capabilities = pd.PrintQueue.GetPrintCapabilities(pd.PrintTicket);

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

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

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

            //update the layout of the visual to the printer page size.
            e.Measure(sz);
            e.Arrange(new System.Windows.Rect(new System.Windows.Point(capabilities.PageImageableArea.OriginWidth, capabilities.PageImageableArea.OriginHeight), sz));

            //now print the visual to printer to fit on the one page.
            pd.PrintVisual(v, "My Print");

            //apply the original transform.
            e.LayoutTransform = originalScale;
        }
    }
    private void DrawGrap_Click(object sender, RoutedEventArgs e)
    {
        // Visual v = sender as Visual;
        Visual v = song2Grid as Visual;   // the object (it is a DataGrid) that you want to print out, not a window
        PrintDialog prtDlg = new PrintDialog();
        if (prtDlg.ShowDialog() == true)
        {
            // because 96 pixels in an inch for WPF window
            double marginLeft = 96.0 * 0.75; // left margin is 0.75 inches
            double marginTop = 96.0 * 0.75; // top margin is 0.75 inches
            double marginRight = 96.0 * 0.75; // right margin is 0.75 inches
            double marginBottom = 96.0 * 0.75; // bottom margin is 0.75 inches

            // the following steps do not works for a WPF window
            FrameworkElement win = v as FrameworkElement;
            Transform oldLayoutTransform = win.LayoutTransform;
            Size oldSize = new Size(win.ActualWidth, win.ActualHeight);

            System.Printing.PrintCapabilities pCapability = prtDlg.PrintQueue.GetPrintCapabilities(prtDlg.PrintTicket);

            // calculate print area that you want
            double printWidth = (pCapability.PageImageableArea.ExtentWidth - pCapability.PageImageableArea.OriginWidth)
                                - (marginLeft + marginRight);
            double printHeight = (pCapability.PageImageableArea.ExtentHeight - pCapability.PageImageableArea.OriginHeight)
                - (marginTop + marginBottom);

            // calculate the scale
            double scale = Math.Min(printWidth / oldSize.Width , printHeight / oldSize.Height);
            if (scale > 1.0)
            {
                // keep the original size and layout if printable area is greater than the object being printed
                scale = 1.0; 
            }

            // store the original layouttransform
            win.LayoutTransform = new ScaleTransform(scale, scale);

            // new size of the visual
            Size newSize = new Size(oldSize.Width*scale , oldSize.Height*scale);
            win.Measure(newSize);

            // centralize print area
            double xStartPrint = marginLeft + (printWidth - newSize.Width)/2.0;
            double yStartPrint = marginTop + (printHeight - newSize.Height)/2.0;
            win.Arrange(new Rect(new Point(xStartPrint,yStartPrint),newSize));

            // print out the visual
            prtDlg.PrintVisual(win as Visual, "PrintTest");

            // resotre the original layouttransform and size on screen
            win.LayoutTransform = oldLayoutTransform;
            win.Measure(oldSize);
            win.Arrange(new Rect(new Point(0,0),oldSize));
        }
    }

這是user1018711提出的問題的答案。 使用C#和WPF在一個打印機頁面上打印。 當你想要打印出一個可視化的視覺效果時,可能包含許多控件(例如Button,DataGrid,TextBlock,Label等)。 在這里,我想將一個名為song2Drid的DataGrid打印到打印機,但其內容大於打印機的頁面大小(其寬度比紙張的寬度寬),因此它被截斷。 我無法看到所有這些,所以我不得不縮放視覺,但我想保持比例與舊的相同。

我還將紙張邊距設置為0.75英寸,紙張的左側,頂部,右側和底部。 我還將視覺內容(song2Grid)集中在紙上。 所以我可以在紙張的中心看到打印的內容。 但是如果visual是一個類似Application.Current.MainWindow的窗口或者是由新的Window()以編程方式創建的窗口,那么它將不會被縮放。 這意味着此方法不適用於Window對象。

此外,如果要通過縮放打印來恢復屏幕上的原始外觀,則必須將語句設置為以下win.LayoutTransform = oldLayoutTransform; win.Measure(oldSize); win.Arrange(new Rect(new Point(0,0),oldSize));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM