强制加载 WPF 视觉对象的适当方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16224986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:41:29  来源:igfitidea点击:

Appropriate way to force loading of a WPF Visual

c#.netwpfprinting

提问by vossad01

I have been struggling with printing using the System.Printingnamespace. I have finally figured out that the reason I was getting blank results when using portions of the API was because the Visualobjects I was trying to print were not Loaded/Initialized. If I display the Visualobjects by putting them in an appropriately-sized Windows and calling Show()prior to printing, I then get the expected results.

我一直在努力使用System.Printing命名空间进行打印。我终于发现在使用 API 的某些部分时我得到空白结果的原因是因为Visual我试图打印的对象没有加载/初始化。如果我Visual通过将对象放在适当大小的Windows 中并Show()在打印之前调用来显示对象,那么我就会得到预期的结果。

Thus, the workaround I came up with was to call this method for every Visual

因此,我想出的解决方法是为每个 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 memorybut I am not really wanting to render the Visual to a bitmap which seems to be what that is for. Calling ApplyTemplate()on the Imagethat as described in wpf force to build visual treedid not help.

使用WPF 中描述的 MenuItem - 获取内存中 UIElement 的大小?不起作用。我查看了内存中 WPF 控件的强制渲染,但我并不是真的想将 Visual 渲染为位图,这似乎是它的用途。调用ApplyTemplate()Image是在描述WPF力构建可视树没有帮助。



EDIT:This is the solution that is used instead of ShowVisualfrom above

编辑:这是用来代替ShowVisual上面的解决方案

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

采纳答案by Jammer

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.

您要打印的项目需要添加到 WPF 中的可视化树中,以便在要显示/打印或以其他方式显示的可视化树中的所有元素上调用测量和排列过程。

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.

我已经有一段时间没有这样做了,但您可能会发现将这些项目添加到后台的 ViewPort 然后打印它们可以解决问题。这应该绕过在屏幕上实际显示它们的需要,因此用户可以看到它们,同时也强制执行测量/排列过程。

回答by Eric Ouellet

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.

我有同样的问题。在我的情况下,我只在尝试使用它之前调用:Visual.UpdateLayout()。正如 Jammer 所说,它会自动强制执行 Measure/Arrange 流程。

I did it on window. If you have any problem, you probably should set the Visual Height and Width before call UpdateLayout().

我是在窗户上做的。如果您有任何问题,您可能应该在调用 UpdateLayout() 之前设置视觉高度和宽度。

Eric

埃里克

回答by ITSGuru

I had the same issue. Solved by ApplyTemplate().

我遇到过同样的问题。由ApplyTemplate()解决。

It force to builds visual tree of an Framework element.

它强制构建框架元素的可视化树。