2010-04-01 71 views
6

我试图创建一些图表图像,而没有在屏幕上显示这些图表。我在这里呆了很长一段时间,并尝试了很多不同的东西,但似乎没有任何工作。如果我首先在窗口中显示图表,则该代码完美工作,但如果我没有将其显示在窗口中,则位图仅为白色并带有黑色边框(不知道为什么)。ContentControl + RenderTargetBitmap +空图像

我已经尝试在渲染并给边框添加一个绿色边框之前将图表添加到边框。在位图中,我看到绿色边框画笔,然后是黑色边框和白色背景,但没有图表。该图表并未包含在黑色边框中,所以我不知道这是从哪里来的。

我已经尝试将图表添加到窗口而不调用window.Show(),并且我只是得到黑色寄宿生和白色背景。但是,如果我调用window.Show(),则位图包含图表。

我已经尝试使用drawingVisual解释为here,结果相同。

下面是代码(不包括添加元素到一个边界或窗口):

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中。

无论如何我可以让图表呈现而不先在窗口中显示它?

回答

5

调用element.ApplyTemplate()的窍门。

+1

这不适合我。你在哪里在你的代码中插入了ApplyTemplate? – 2012-04-18 10:34:46

+0

抱歉已经过了两年,因为我回答了这个问题,并且我无法再访问该代码。尝试在UpdateLayout之前添加它 – Kelly 2012-04-20 20:55:33

+0

感谢您发布答案。你救了我很多麻烦! :) – ihake 2014-04-18 00:19:13

1

如果有人有呈现类似的问题RenderTargetBitmap(获得白/空图像)是在StackPanel中,你可以暂时将其移动到电网,然后渲染并把它放回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(); 
+0

感谢您的提示。我发现了一篇关于这个博客文章以及我在另一个SO线程中记录的文章:http://stackoverflow.com/questions/2522380/get-a-bitmap-image-from-a-control-view/28626055#28626055 – 2015-02-20 09:56:07

1

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

+0

我也是。其他建议都没有奏效。 – brianberns 2016-03-30 06:08:39