I have been struggling with printing using the System.Printing
namespace. I have finally figured out that the reason I was getting blank results when using portions of the API was because the Visual
objects I was trying to print were not Loaded/Initialized. If I display the Visual
objects by putting them in an appropriately-sized Window
s and calling Show()
prior to printing, I then get the expected results.
Thus, the workaround I came up with was to call this method for every Visual
public static void ShowVisual(Visual visual)
{
Window window = new Window
{
Content = visual,
SizeToContent = SizeToContent.WidthAndHeight,
Visibility = Visibility.Hidden
};
window.Show();
window.Close();
}
This seems like a hack, especially since the user briefly sees the Window-frame draw. I figure there must be a different way it is supposed to be done. However, I am not turning up any other solutions. Is using a hidden Window really what is supposed to be done here?
Using a MenuItem as described at WPF - Get size of UIElement in Memory? does not work. I looked at Force rendering of a WPF control in memory but I am not really wanting to render the Visual to a bitmap which seems to be what that is for. Calling ApplyTemplate()
on the Image
that as described in wpf force to build visual tree did not help.
EDIT: This is the solution that is used instead of ShowVisual
from above
/// <remarks>
/// This method needs to be called in order for
// the element to print visibly at the correct size.
/// </remarks>
private static void ArrangeElement(UIElement element)
{
var box = new Viewbox {Child = element};
box.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
box.Arrange(new Rect(box.DesiredSize));
}
I had the same issue. Solved by ApplyTemplate().
It force to builds visual tree of an Framework element.
The items you want to print need to be added to the visual tree in WPF in order for the Measure and Arrange processes to be called on all the elements in the visual tree you want to show / print or otherwise display.
I haven't done this for a while but you may find that adding these items to a ViewPort in the background and then printing them solves the issue. This should get around the need for actually displaying them on the screen and thus the user seeing them whilst also forcing the Measure / Arrange processes.
I had the same problem. In my case I only call: Visual.UpdateLayout() before trying to work with it. As said by Jammer, it will automatically force Measure / Arrange processes.
I did it on window. If you have any problem, you probably should set the Visual Height and Width before call UpdateLayout().
Eric
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With