ContentControl + RenderTargetBitmap + пустое изображение

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

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

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

Я пробовал использовать DrawingVisual, как описано здесь , результат тот же.

Вот код (не включая добавление элемента к границе или окну):

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.

Есть ли способ получить диаграмму для рендеринга, не отображая ее сначала в окне?


person Kelly    schedule 01.04.2010    source источник


Ответы (3)


Вызов element.ApplyTemplate () сделал свое дело.

person Kelly    schedule 11.05.2010
comment
У меня не работает. Где вы вставили в код ApplyTemplate? - person Ignacio Soler Garcia; 18.04.2012
comment
Извините, прошло два года с тех пор, как я ответил на этот вопрос, и у меня больше нет доступа к этому коду. Попробуйте добавить его перед UpdateLayout - person Kelly; 21.04.2012
comment
Спасибо за ответ. Вы избавили меня от множества неприятностей! :) - person ihake; 18.04.2014

Если у кого-то похожие проблемы с рендерингом RenderTargetBitmap (получение белого / пустого изображения) элементов, находящихся в StackPanel, вы можете временно переместить их в 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();
person Evalds Urtans    schedule 05.02.2014
comment
Спасибо за подсказку. Я нашел сообщение об этом в блоге, а также задокументировал его в другом потоке SO: stackoverflow.com/questions/2522380/ - person Björn; 20.02.2015

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

person Dan    schedule 02.12.2015