2009-07-03 9 views
22

Tengo el siguiente código:Fuerza prestación de un control de WPF en la memoria

void Test() 
{ 
    currentImage.Source = GetBitmap(); 
    RenderTargetBitmap rtb = new RenderTargetBitmap(100, 100, 96.0, 96.0, PixelFormats.Default); 
    rtb.Render(currentImage); 
} 

Este código se supone que hacen currentImage, que es un control Image en mi xaml a un RenderTargetBitmap.

No funciona, RTB devuelve una imagen en blanco, el problema es currentImage no rindió en sí todavía y lo que se espera este comportamiento, creo ...

Para solucionar este problema, he escrito este código:

void Test() 
{ 
    currentImage.Source = GetBitmap(); 

    this.Dispatcher.BeginInvoke((Action)delegate() 
    { 
     RenderTargetBitmap rtb = new RenderTargetBitmap(100, 100, 96.0, 96.0, PixelFormats.Default); 
     rtb.Render(currentImage); 
    }, System.Windows.Threading.DispatcherPriority.Render, null); 

} 

Básicamente, espero currentImage que pasarán a ser y luego puede que se pusiera en rindió a mi RenderTargetBitmap.

¿Hay alguna manera de hacerlo funcionar sin usar esta solución? ¿Forzar el control de imagen para renderizar en la memoria?

gracias!

+0

Nota: Si tiene un diseño complejo y está mostrando y ocultando elementos con convertidores, puede terminar con un diseño final incorrecto. Esto es lo que tuve que hacer para solucionarlo: http://stackoverflow.com/questions/41966704/wpf-xaml-control-converted-to-an-image-has-incorrect-layout/41966743#41966743 –

Respuesta

38

uso de un ViewBox para rendir en la memoria

Grid grid = new System.Windows.Controls.Grid() { Background = Brushes.Blue, Width = 200, Height = 200 }; 
Viewbox viewbox = new Viewbox(); 
viewbox.Child = grid; //control to render 
viewbox.Measure(new System.Windows.Size(200, 200)); 
viewbox.Arrange(new Rect(0, 0, 200, 200)); 
viewbox.UpdateLayout(); 
RenderTargetBitmap render = new RenderTargetBitmap(200, 200, 150, 150, PixelFormats.Pbgra32); 
render.Render(viewbox); 
+0

Gracias ¡tanto por esta solución! He estado luchando con esto por un tiempo, pero no sabía sobre el truco de ViewBox para renderizar en la memoria. ¡¡Gracias!! – Kilhoffer

+7

¡Esto debería ser el mercado como la respuesta aceptada! ¡Funciona perfectamente! –

+2

Es posible usar otros "contenedores" (cualquier cosa que se derive del Panel) para lograr el mismo resultado. Un ViewBox escalará el contenido mientras que los paneles no lo harán. –

8

Creo que este es un BETTER answer.
El viewbox no funcionó del todo como se esperaba y resultó ser una sobrecarga innecesaria.

Aquí está una copia de la respuesta (en lugar de sólo enlace)


Es necesario forzar un render del tema, o esperar a que el elemento que se dicte. A continuación, puede utilizar las propiedades ActualHeight y ActualWidth.

para forzar un render:

MenuItem item = new MenuItem(); 
    item.Header = "bling"; 
    item.Icon = someIcon; 
    //Force render 
    item.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); 
    item.Arrange(new Rect(item.DesiredSize)); 

En este ejemplo el MenuItem no se ha dado una altura o anchura explícita. Sin embargo, al forzar el renderizado se tendrá en cuenta el texto y el icono del encabezado suministrados.

+0

sí, este funcionó para mí ... –