Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force rendering of a WPF control in memory

I have the following code:

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

This code is supposed to render currentImage, which is an Image control in my xaml to a RenderTargetBitmap.

It doesn't work, rtb returns a blank image, the problem is currentImage didn't render itself yet and so this behavior is expected, I think...

To workaround this problem, I wrote this code:

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

}

Basically, I wait for currentImage to be rendered and then I can get it properly rendered to my RenderTargetBitmap.

Is there any way to make it work without using this workaround? Force the Image control to render in memory maybe?

thanks!

like image 987
Schwertz Avatar asked Jul 03 '09 18:07

Schwertz


2 Answers

use a ViewBox to render in memory

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);
like image 114
Daniel Pamich Avatar answered Nov 10 '22 13:11

Daniel Pamich


I think this is a BETTER answer .
The viewbox didn't work completely as expected, and it turned out to be an unnecessary overhead.

Here is a copy of that answer (instead of just link)


You need to force a render of the item, or wait for the item to be rendered. You can then use the ActualHeight and ActualWidth properties.

To force a 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));

In this example the MenuItem has not been given an explicit height or width. However, forcing the render will render it taking the supplied header text and icon into consideration.

like image 35
Martin Lottering Avatar answered Nov 10 '22 15:11

Martin Lottering