1

I have a WPF Form ,I need to print it ,i use DocumentViewer to print. but when I want to Print it or Preview , I only See the first page while i have more than one page

private void Print(object sender, RoutedEventArgs e)
{
PrintSettings printSettings = PrintSettings.Default;
UIElement container = this.Content as UIElement;
ScrollViewer containerPanel = Helper.FindVisualChildren<ScrollViewer>(container).FirstOrDefault();
var origParentDirection = containerPanel.FlowDirection;
var origDirection = (containerPanel.Content as FrameworkElement).FlowDirection;
if (containerPanel != null && containerPanel.FlowDirection == FlowDirection.RightToLeft)
{
containerPanel.FlowDirection = FlowDirection.LeftToRight;
(containerPanel.Content as FrameworkElement).FlowDirection = FlowDirection.RightToLeft;
}
var window = new Window();
string tempFileName = System.IO.Path.GetTempFileName();
System.IO.File.Delete(tempFileName);
using (XpsDocument xpsDocument = new XpsDocument(tempFileName, FileAccess.ReadWrite, System.IO.Packaging.CompressionOption.Fast))
{
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
(containerPanel.Content as FrameworkElement).Margin = new Thickness(20);
writer.Write((containerPanel.Content as FrameworkElement), printSettings.PrintTicket);
var doc = xpsDocument.GetFixedDocumentSequence();
doc.PrintTicket = printSettings.PrintTicket;       
window.FlowDirection = System.Windows.FlowDirection.RightToLeft;
window.Content = new DocumentViewer { Document = doc };
window.Margin = new Thickness(10);
window.ShowDialog();
}
(containerPanel.Content as FrameworkElement).FlowDirection = origDirection;
containerPanel.FlowDirection = origParentDirection;
}
user1780436
  • 9
  • 1
  • 5

1 Answers1

0

user1780436, I am currently looking for a similar answer. You are trying to print a panel, correct?

I am finding that scaling the element is the biggest problem. Which brings another issue with scaling what you want to print and not the actual visible element. You will have to copy the element to a new element.

public class Copy<T>
{
    public static T DeepCopy<T>(T element)
    {
        string xaml = XamlWriter.Save(element);
        StringReader xamlString = new StringReader(xaml);
        XmlTextReader xmlTextReader = new XmlTextReader(xamlString);
        var DeepCopyobject = (T)XamlReader.Load(xmlTextReader);
        return DeepCopyobject;
    }

}

or

myNewElement = XamlReader.Parse(XamlWriter.Save(myOldElement.DataContext)) as ElementType

I have found this answer repeatedly on multiple sites to copy/clone an element, but I have had issues with string xaml = XamlWriter.Save(element); causing stackoverflows.

I am currently using.

myNewElement = new ElementType() { DataContext = myOldElement.DataContext }

Either one you use there becomes the issue of changing the size of the Element. This is what I am looking for.

I tried a rendering pass, but that just pointed out that in my situation to use a copied/cloned element. Although while writing this I did get some of it to work, but gives me a black image, note I am trying to scale a Chart.

myNewElement.Width = newWidth;
myNewElement.Height = newHeight;

myNewElement.Measure(new System.Windows.Size(newWidth, newHeight));
myNewElement.Arrange(new Rect(0, 0, newWidth, newHeight));

I tried a layout pass, and didn't get it.

I am going to keep working on mine and I will post anything new I find. Please do the same if you find the answer.

Edit - Here is what I did. My problem and solution

Community
  • 1
  • 1
Bluto
  • 166
  • 1
  • 15