2011-10-28 32 views
6

tôi đã tìm kiếm các tùy chọn cách in các điều khiển WPF và tìm thấy một số giải pháp. Tôi cần phải phù hợp với điều khiển in của tôi để in trang trong khi vẫn giữ được khẩu phần (điều khiển của tôi là hình vuông; lưới sudoku).In WPF để vừa với trang

Tôi đã tìm thấy giải pháp thay đổi kích thước và đặt lại vị trí kiểm soát để vừa với trang. Điều đó hoạt động tốt, nhưng nó cũng đặt lại vị trí kiểm soát trên cửa sổ của tôi.

đây là đoạn code tôi sử dụng cho in ấn và mở rộng quy mô:

 //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()); 

Tôi đã thử hai aproaches để giải quyết này:

  1. Clone kiểm soát của tôi và sau đó biến đổi nhân bản một, unaffecting gốc. Không hoạt động, vì một lý do nào đó tôi đã kết thúc với ngoại lệ: DependencyObject được cung cấp không phải là ngữ cảnh cho Freezable này, nhưng chỉ trong một số trường hợp.

  2. Hoàn nguyên kích thước và thay đổi vị trí. Tôi đã thử gọi phương thức InvalidateArrange(), có vẻ như hoạt động, nhưng chỉ trong lần gọi đầu tiên của phương thức in. Trong cuộc gọi thứ hai, nó không hoạt động.

Tôi nên làm gì, bất kỳ ý tưởng nào < cảm ơn bạn.

Trả lời

19

Tôi biết câu hỏi này khá cũ nhưng tìm kiếm giải pháp cho vấn đề này. Đây là giải pháp tôi hiện đang sử dụng. Tôi lưu trữ các biến đổi ban đầu đối với phần tử khung và sau đó áp dụng lại nó sau khi in xong.

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; 
     } 
    } 
+1

Bạn sẽ cần thêm tham chiếu vào System.Printing và ReachFramework. – StillLearnin

+0

Nó cũng có vẻ để tham khảo System.Windows.Media và System.Windows.Controls – Jeff

+2

Điều này không đúng cho tôi, LayoutTransform dường như bị bỏ qua bất kể loại Transform tôi ném vào nó. – Lennart

1
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)); 
     } 
    } 

Đó là một câu trả lời cho các câu hỏi đã được bởi user1018711. Lắp một bản in ra trên một trang máy in bằng C# và WPF. Khi bạn muốn in ra một hình ảnh, đó có thể là một điều khiển những gì có thể bao gồm rất nhiều điều khiển (ví dụ như Button, DataGrid, TextBlock, Label, và vv). Ở đây tôi muốn in một DataGrid tên là song2Drid cho máy in nhưng nội dung của nó lớn hơn kích thước trang của máy in (chiều rộng của nó rộng hơn chiều rộng của một tờ giấy) nên nó đã bị cắt ngắn. Tôi không thể nhìn thấy tất cả trong số họ vì vậy tôi đã phải quy mô thị giác nhưng tôi muốn giữ tỷ lệ cũng giống như tỷ lệ cũ.

Tôi cũng đặt lề giấy thành 0,75 inch cho mỗi mặt giấy, bên trái, trên cùng, bên phải và dưới. Tôi cũng tập trung nội dung của visual (song2Grid) trên giấy. Vì vậy, tôi có thể thấy nội dung được in chỉ ở giữa giấy. Nhưng nếu hình ảnh là một cửa sổ như Application.Current.MainWindow hoặc bất kỳ cửa sổ nào được tạo lập trình bởi Window() mới, thì nó sẽ không được thu nhỏ. nó có nghĩa là phương pháp này sẽ không làm việc cho một đối tượng Window.

Ngoài ra, nếu bạn muốn khôi phục giao diện gốc trên màn hình từ màn hình đã thay đổi bằng cách phóng to để in, thì bạn phải có các câu lệnh như sau win.LayoutTransform = oldLayoutTransform; win.Measure (oldSize); win.Arrange (Rect mới (điểm mới (0,0), oldSize));

+4

Vui lòng thêm một số lời giải thích cho câu trả lời của bạn. Chỉ hiển thị mã là rất khó hiểu. –

+0

Vui lòng sử dụng liên kết [chỉnh sửa] (http://stackoverflow.com/posts/36967240/edit) để thêm thông tin này vào câu trả lời của bạn.Bằng cách đó, mọi người không phải đọc qua tất cả các nhận xét này để tìm thông tin họ đang tìm kiếm và cải thiện đáng kể câu trả lời của bạn. –

+0

Cảm ơn. Tôi khá mới ở đây. –

Các vấn đề liên quan