New WPF Features: Cached Composition
This is part of a series on New WPF Features
One of the big improvements in 4.0 is the Cached Composition feature in graphics. This feature enables caching a live UIElement as a bitmap, which enables quick rendering of the element as a bitmap. The UIElement is user interactive and hence will respond to keyboard input, mouse clicks,… Also, transforms, effects,.. which operate on top will not cause the cache to regenerated resulting in better performance. Previously, it was common to use RenderTargetBitmap for this purpose. However, this would be at the cost of interactivity.
Lets jump into usage. You have the BitmapCache and the BitmapCacheBrush classes. The former is useful in rendering a complex UIElement while the latter facilitates better reuse of a cached element.
Usage of BitmapCache is shown below. RenderAtScale is helpful for zoom scenarios since it a cache which is multiple of the original bitmap size. Note that changing the UIElement subtree or these properties (EnableClearType\RenderAtScale) will cause the cache to be regenerated.
<Canvas.CacheMode>
<BitmapCache EnableClearType="False" RenderAtScale="2"/>
</Canvas.CacheMode>
<Canvas CacheMode="BitmapCache"/>
BitmapCacheBrush is useful when you need to paint the same content on multiple elements. A sample usage is below.
<Grid.Resources>
<Image x:Key="cachedImage" Source="Xaml.jpg" >
<Image.CacheMode>
<BitmapCache EnableClearType="False" RenderAtScale="1" SnapsToDevicePixels="False" />
</Image.CacheMode>
</Image>
<BitmapCacheBrush x:Key="cachedImageBrush" Target="{StaticResource cachedImage}" />
</Grid.Resources>
<Button Background="{StaticResource cachedImageBrush}" Content="Tile1" Grid.Column="1"/>
<Button Background="{StaticResource cachedImageBrush}" Content="Tile2" Grid.Column="2"/>
...
Got a couple of apps in place to show the usage. The one on the left shows the zoom in action while the second app applies the cacheMode on Viewport2dVisual3D.
The code is attached. Have fun
Comments
Anonymous
November 20, 2009
I tried the cachemode with the webbrowsercontrol. Unfortunately it is not possible to use the bitmapcachebrush in another control's background.Anonymous
November 21, 2009
One of the snippets in the post show how the bitmapcachebrush is used as a background for another control (button)Anonymous
November 22, 2009
I want to cache the browsercontrol and use its content in e.g. canvas by using the bitmapcachebrush. Maybe it doesn't work, since the browser control is a hosted control. I want to do something similar as the htmlbrush in Silverlight.Anonymous
November 23, 2009
this is discussed on the following link http://social.msdn.microsoft.com/forums/en-US/wpf/thread/9e89a10d-8d39-4f36-945b-f8777a6ef422Anonymous
December 27, 2009
Hi! Thank you for the article. I tried using BitmapCache when moving/resizing Controls with some geometric figures but that gave no boost in performance. I also tried your apps and I can't see any difference either. Checking the "Enable Cache Composition" keeps my CPU constantly busy at about 30%. Setting it off doesn't change anything. Why? I thought, this function gave a considerable performance boost.Anonymous
December 27, 2009
L0tR, the samples attached should show improved performance. Please send me a mail using the email link and we can discuss this offline.Anonymous
December 28, 2009
I ran your app several times more and now saw the difference. Excuse me, something must have been wrong with my system...or with my eyes :) Could you tell me, if I have such code, where should I insert "CacheMode = "BitmapCache""? <Canvas> <ContentControl Width="130" MinWidth="50" Height="130" MinHeight="50" Canvas.Top="150" Canvas.Left="470" Template="{StaticResource DesignerItemTemplate}"> //Just some Template <Ellipse Fill="Red"/> </ContentControl> <ContentControl Width="130" MinWidth="50" Height="130" MinHeight="50" Canvas.Top="150" Canvas.Left="150" Template="{StaticResource DesignerItemTemplate}"> <Path Fill="Blue" Data="M 0,5 5,0 10,5 5,10 Z" Stretch="Fill"/> </ContentControl> </Canvas>