2010-04-01 21 views
6

Próbuję utworzyć obrazy wykresów bez wyświetlania tych wykresów na ekranie. Byłem w tym od dłuższego czasu i próbowałem wielu różnych rzeczy, ale nic nie działa. Kod działa idealnie, jeśli najpierw wyświetlam wykres w oknie, ale jeśli nie wyświetlam go w oknie, bitmapa jest biała z czarną obwódką (nie mam pojęcia dlaczego).ContentControl + RenderTargetBitmap + pusty obraz

Próbowałem dodać wykres do granicy przed renderowaniem i nadanie granicy zielonej granicy. W mapie bitowej widzę zieloną obramowanie, a następnie czarne obramowanie i białe tło, ale bez wykresu. Wykres nie jest zawarty w czarnej granicy, więc nie wiem, skąd to pochodzi.

Próbowałem dodawać wykres do okna bez wywoływania window.Show() i ponownie po prostu uzyskać czarny granicy i białe tło. Jednak jeśli wywołasz window.Show() mapa bitowa zawiera wykres.

Próbowałem przy użyciu rysunkuVisual, jak wyjaśniono here, sam wynik.

Oto kod (nie wliczając dodanie elementu do granicy lub okna):

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

Uwaga: Na wykresie jest ContentControl.

Czy mimo to mogę wydrukować wykres bez wyświetlania go w oknie?

Odpowiedz

5

Wywołanie elementu.ApplyTemplate() załatwiło sprawę.

+1

To nie działa dla mnie. Gdzie wstawiłeś w swoim kodzie ApplyTemplate? –

+0

Niestety minęły dwa lata, odkąd odpowiedziałem na to pytanie i nie mam już dostępu do tego kodu. Spróbuj dodać go przed UpdateLayout – Kelly

+0

Dziękuję za opublikowanie odpowiedzi. Uratowałeś mi wiele kłopotów! :) – ihake

1

Jeśli ktoś ma podobne problemy z renderingu RenderTargetBitmap (coraz biały/pusty obraz) pozycje będące w StackPanel można tymczasowy przenieść je do Siatka, to czynią i umieścić go z powrotem w 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

Dzięki za podpowiedź. Znalazłem wpis na blogu na ten temat, jak również udokumentowałem w innym wątku SO: http://stackoverflow.com/questions/2522380/get-a-bitmap-image-crom-a-control-view/28626055#28626055 –

1

Dla mnie brakowało elementu nazywającego element.Arrange().

+0

Ja też. Żadna z pozostałych sugestii nie zadziałała. – brianberns

Powiązane problemy