Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i handle LayoutUpdated or stop a control rendring in WPF?

Tags:

c#

wpf

rendering

i want to cancel or stop or handle rendering(or drawing) a WPF Element for lower cpu usage(cancel all forever animations and rendering in background or collapsed visibility items for use best performance in my app).

i read all Optimizing WPF Application Performance

void MainWindow_LayoutUpdated(object sender, EventArgs e)
    {
        e.Handled = true;//can i handle an object rendering?
    }
like image 666
Ali Yousefi Avatar asked May 30 '15 12:05

Ali Yousefi


1 Answers

LayoutUpdated is not going to help you at all. It is an event that fires on all UI elements associated with a Dispatcher after a full layout pass has completed, meaning the work is already done.

You have a few options, depending on what your goal is.

Hide the Element

If you don't want the element to be visible or perform any layout, then you can set its Visibility property to Collapsed. It should skip most of its layout logic and all of its rendering logic while it is collapsed.

Remove the Element

Removing the element from the visual tree is a sure way to keep it from doing anything. You can add it back later if you need to. The process for how to do this depends a lot on how your code is currently setup.

Reduce the Performance Cost of the Element

If the element is expensive because it is doing a lot of work, you could look into optimizing it in general, and/or look into disconnecting its event listeners and bindings during the time when you don't want it doing work.

Pause UI Processing

If you want to temporarily pause all UI processing while you perform some operation (to prevent reentrancy), you can use Dispatcher.DisableProcessing. Note that this will disable UI processing for the entire thread, not just the processing of a specific element.

using (Dispatcher.DisableProcessing())
{
    // Do work while the dispatcher processing is disabled.
}

A Static Picture of the Element

If you want to permanently disable all processing of an element, I don't know of a way to do that while still keeping it visible on the screen. However, you could use a RenderTargetBitmap to render the element to an ImageSource and then replace the original element with an Image element that has its Source property set to the bitmap.

RenderTargetBitmap target = new RenderTargetBitmap((int)element.RenderSize.Width, (int)element.RenderSize.Height, 96.0, 96.0, PixelFormats.Default);
target.Render(element);
image.Source = target;

Now you basically have a "picture" of the element in place of where the original element was.

like image 155
Xavier Avatar answered Sep 20 '22 23:09

Xavier