How to find out when a control (or window) was rendered (drawn) in WPF?

I need to save the contents of a window to an image, save it and close the window. If I close the window on the Loaded event, the image will contain Window, some elements will be drawn ok, some others will only be half stretched or distorted, and others will not be displayed on the image.

If I set a timer and close the window after a certain time (something between 250 ms and 1 second, depending on the complexity of the window), all the images will be in order.

It looks like the window needs some time to fully display itself. Is there any way to know when this rendering was done to avoid using a timer and closing the window when we know that it has finished rendering it?

Thank.

+3
source share
3 answers

I think you are looking for a ContentRendered event

+10
source

I had a similar problem in the application I am working in. I solved it using the following code, try and let me know if this helps.

 using (new HwndSource(new HwndSourceParameters())
                   {
                       RootVisual =
                           (VisualTreeHelper.GetParent(objToBeRendered) == null
                                ? objToBeRendered
                                : null)
                   })
        {
            // Flush the dispatcher queue
            objToBeRendered.Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(() => { }));

            var renderBitmap = new RenderTargetBitmap(requiredWidth, requiredHeight,
                                                      96d*requiredWidth/actualWidth, 96d*requiredHeight/actualHeight,
                                                      PixelFormats.Default);

            renderBitmap.Render(objToBeRendered);
            renderBitmap.Freeze();                

            return renderBitmap;
        }
+2
source

I used the method on SizeChanged.

public partial class MyUserControl: UserControl
{

    public MyUserControl()
    {
        InitializeComponent();
        SizeChanged += UserControl_DoOnce; //register
    }

    private void UserControl_DoOnce(object sender, SizeChangedEventArgs e)
    {
        if (ActualHeight > 0)//Once the object has size, it has been rendered.
        {
              SizeChanged -= UserControl_DoOnce; //Unregister so only done once
        }
    }
}

This is the only method that I have found works reliably from a control without a window reference.

0
source

All Articles