Appropriate way to force loading of a WPF Visual

.net, c#, printing, wpf

Solution

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.

Problem

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

Original source

Related problems