8

我试图创建一些图表图像,但从未在屏幕上显示这些图表。我已经做了很长一段时间了,尝试了很多不同的东西,但似乎没有任何效果。如果我首先在窗口中显示图表,则代码可以完美运行,但是如果我不在窗口中显示它,则位图只是带有黑色边框的白色(不知道为什么)。

我尝试在渲染之前将图表添加到边框并为边框提供绿色边框。在位图中,我看到绿色的borderBrush,然后是黑色边框和白色背景,但没有图表。该图表不包含在黑色边框中,所以我不知道它来自哪里。

我尝试在不调用 window.Show() 的情况下将图表添加到窗口,但我再次得到黑色边框和白色背景。但是,如果我调用 window.Show() 位图包含图表。

我尝试过使用这里所解释的绘图视觉,结果相同。

这是代码(不包括将元素添加到边框或窗口):

private static BitmapSource CreateElementScreenshot(FrameworkElement element, int dpi)
{
    if (!element.IsMeasureValid)
    {
        Size size = new Size(element.Width, element.Height);
        element.Measure(size);
        element.Arrange(new Rect(size));
    }

    element.UpdateLayout();

    var scale = dpi/96.0;

    var renderTargetBitmap = new RenderTargetBitmap
        (
            (int)(scale * element.RenderSize.Width),(int)(scale * element.RenderSize.Height),dpi,dpi,PixelFormats.Default
        );

    // this is waiting for dispatcher to perform measure, arrange and render passes
    element.Dispatcher.Invoke(((Action)(() => renderTargetBitmap.Render(element))), DispatcherPriority.Render);

    return renderTargetBitmap;
}

注意:图表是一个 ContentControl。

无论如何我可以在不先在窗口中显示图表的情况下渲染图表吗?

4

3 回答 3

9

调用 element.ApplyTemplate() 就可以了。

于 2010-05-11T15:18:00.117 回答
2

如果有人在渲染StackPanel 中的RenderTargetBitmap(获取白色/空图像)项目时遇到类似问题,您可以临时将它们移动到Grid,然后渲染并将其放回StackPanel

Grid grid = new System.Windows.Controls.Grid() { Background = Brushes.White, Width = iWidth, Height = iHeight };
Panel panel = plot.Parent as Panel;

if (panel != null)
{
    panel.Children.Remove(plot);
    grid.Children.Add(plot);

    grid.Measure(new Size(iWidth, iHeight));
    grid.Arrange(new Rect(new Size(iWidth, iHeight)));
}
plot.Measure(new Size(iWidth, iHeight));
plot.Arrange(new Rect(new Size(iWidth, iHeight)));

plot.ApplyTemplate();
plot.UpdateLayout();

grid.ApplyTemplate();
grid.UpdateLayout();

RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(
    iWidth,
    iHeight,
    96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(grid);

PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));

MemoryStream memoryStream = new MemoryStream();
encoder.Save(memoryStream);
bitmap = new System.Drawing.Bitmap(memoryStream);

if (panel != null)
{
    grid.Children.Remove(plot);
    panel.Children.Add(plot);
}

plot.Measure(new Size(iWidthBefore, iHeightBefore));
plot.Arrange(new Rect(new Size(iWidthBefore, iHeightBefore)));
plot.UpdateLayout();
于 2014-02-05T12:55:53.590 回答
2

对我来说,调用 element.Arrange() 是缺失的部分。

于 2015-12-02T15:16:41.540 回答