2010-04-01 14 views
6

Sto cercando di creare alcune immagini di grafici senza mai visualizzare quei grafici sullo schermo. Sono stato a questo per un po 'e ho provato un sacco di cose diverse ma niente sembra funzionare. Il codice funziona perfettamente se visualizzo il grafico in una finestra per primo, ma se non lo visualizzo in una finestra, la bitmap è solo bianca con un bordo nero (nessuna idea del perché).ContentControl + RenderTargetBitmap + immagine vuota

Ho provato ad aggiungere il grafico a un bordo prima del rendering e a dare al bordo un bordo verde. Nella bitmap, vedo il borderBrush verde, quindi il bordo nero e lo sfondo bianco ma nessun grafico. Il Chart non è contenuto in un boarder nero quindi non so da dove viene.

Ho provato ad aggiungere il grafico a una finestra senza chiamare window.Show() e di nuovo ho appena ottenuto il boarder nero e lo sfondo bianco. Tuttavia se chiamo window.Show() la bitmap contiene il grafico.

Ho provato a utilizzare un disegnoVisuale come spiegato here, stesso risultato.

Ecco il codice (non inclusa l'aggiunta dell'elemento da un bordo o finestra):

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

Nota: Il grafico è un ContentControl.

Esiste comunque la possibilità di visualizzare il grafico senza visualizzarlo prima in una finestra?

risposta

5

Calling element.ApplyTemplate() ha fatto il trucco.

+1

Non funziona per me. Dove hai inserito nel tuo codice la funzione ApplyTemplate? –

+0

Scusa sono passati due anni da quando ho risposto a questo e non ho più accesso a quel codice. Prova ad aggiungerlo prima di UpdateLayout – Kelly

+0

Grazie per aver postato la risposta. Mi hai salvato un sacco di problemi! :) – ihake

1

Se qualcuno ha problemi simili con il rendering RenderTargetBitmap (ottenendo bianco/immagine vuota) gli elementi che sono in StackPanel è possibile temporanea spostarli in griglia, poi il rendering e rimetterlo in 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

Grazie per il suggerimento. Ho trovato un post su questo blog così come ho documentato in un'altra discussione SO: http://stackoverflow.com/questions/2522380/get-a-mapmap-image-from-a-control-view/28626055#28626055 –

1

Per me, chiamare elemento.Arrangia() era il pezzo mancante.

+0

Anche a me. Nessuno degli altri suggerimenti ha funzionato. – brianberns