WPF user rendering in memory, not on screen

I have a complex user control that displays an image and overlays certain tags with shadows, etc. I want to display all these things in memory, then make an image of this card, and then use this image in a real user interface. This is the thing at the end.

enter image description here

I do this because the interface has started to move slowly with all of these elements, and I'm trying to simplify it. Am I going the right way?

The problem here is that I create a brainmap, feed it with data, and then try to create imagen and BAM! this cannot be done, because the entire component is not displayed, ActualWith is zero.

This is how I extract the image from the control (the method works fine when the control is displayed on the screen)

/// <summary> /// The controls need actual size, If they are not render an "UpdateLayout()" might be needed. /// </summary> /// <param name="control"></param> /// <param name="Container"></param> public static System.Windows.Controls.Image fromControlToImage(System.Windows.FrameworkElement control) { if (control.ActualWidth == 0) throw new Exception("The control has no size, UpdateLayout is needed"); // Here is where I get fired if the control was not actually rendered in the screen RenderTargetBitmap rtb = new RenderTargetBitmap((int)control.ActualWidth, (int)control.ActualHeight, 96, 96, PixelFormats.Pbgra32); rtb.Render(control); var bitmapImage = new BitmapImage(); var bitmapEncoder = new PngBitmapEncoder(); bitmapEncoder.Frames.Add(BitmapFrame.Create(rtb)); using (var stream = new System.IO.MemoryStream()) { bitmapEncoder.Save(stream); stream.Seek(0, System.IO.SeekOrigin.Begin); bitmapImage.BeginInit(); bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.StreamSource = stream; bitmapImage.EndInit(); } System.Windows.Controls.Image testImage = new System.Windows.Controls.Image(); testImage.Source = bitmapImage; return testImage; } 

If the control was part of the layout at the beginning, adding UpdateLayout really solves the problem (why I added an exception for myself there), but when the control is created from the code and never reached the UpdateLayout page there will be no help at all.

What can I do to ensure that all the elements in memory are rendered and then the image is rendered without page input? (fixed size perceived)

+5
source share
1 answer

In your case, the solution would be something like this:

  public static System.Windows.Controls.Image fromControlToImage(System.Windows.FrameworkElement control) { Size size = new Size(100, 100); // Or what ever size you want... control.Measure(size); control.Arrange(new Rect(size)); control.UpdateLayout(); ... } 

Embracing WPF in memory is pretty often set here in SO:

Memory Drawing Management

Since the control does not have a parent container, you need to call Measure and Arrange to make the correct layout.

WPF get UIElement size in memory

You need to force the rendering of an element or wait for the object to be rendered. You can then use the ActualHeight and ActualWidth properties.

Additional for your purpose:

Providing a WPF Control in Memory

With the ability to use, you can use ViewBox for rendering in memory

+6
source

Source: https://habr.com/ru/post/1242173/


All Articles