2010-04-01 3 views
6

Im пытается создать некоторые изображения диаграмм, не отображая эти графики на экране. Я долгое время занимался этим и пробовал много разных вещей, но ничего не работает. Код работает отлично, если я сначала показываю диаграмму в окне, но если я не покажу ее в окне, растровое изображение просто белое с черной рамкой (не знаю почему).ContentControl + RenderTargetBitmap + пустое изображение

Я попытался добавить диаграмму к границе перед рендерингом и дать границе зеленой рамкой. В растровом изображении я вижу зеленый borderBrush, затем черную рамку и белый фон, но нет диаграммы. Диаграмма не содержится в черной рамке, поэтому я не знаю, откуда она.

Я попытался добавить диаграмму в окно без вызова window.Show() и снова я просто получить черный границы и белый фон. Однако, если я вызываю window.Show(), битмап содержит диаграмму.

Я попытался использовать чертежVisual, как описано 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

Вызывающий элемент.ApplyTemplate() сделал трюк.

+1

Это не работает для меня. Где вы ввели в свой код ApplyTemplate? –

+0

Простите, прошло уже два года с тех пор, как я ответил на это, и у меня больше нет доступа к этому коду. Попробуйте добавить его перед UpdateLayout – Kelly

+0

Спасибо за сообщение ответа. Ты спас мне много неприятностей! :) – ihake

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 –

1

Для меня, вызывающий элемент.Arrange() был недостающим элементом.

+0

Я тоже. Ни один из других предложений не работал. – brianberns