Un'altra delle novità introdotte da Windows Presentation Foundation 4 si chiama cached composition e, in parole molto povere, permette di memorizzare un elemento visuale all'interno di una cache in modo da recuperarlo rapidamente senza doverlo renderizzare graficamente ogni qual volta lo si utilizza. Si definisce un oggetto BitmapCache all'interno delle risorse del contenitore che andrà memorizzato in cache, come nel caso seguente in cui è presente un TextBlock:
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<!-- Stabilisce come deve andare in cache il contenuto
della Grid -->
<Grid.CacheMode>
<!-- In questo caso si usa la cache quando si fa lo
zoom al doppio delle dimensioni -->
<BitmapCache RenderAtScale="2" EnableClearType="False"/>
</Grid.CacheMode>
<!--Il contenuto poi si dichiara normalmente-->
<TextBlock Text="Cached in case you zoom this"
FontSize="20" Grid.Row="0" />
Da notare come il contenitore esponga ora una proprietà CacheMode all'interno della quale si definisce la modalità di applicazione della tecnica. Si utilizza la proprietà RenderAtScale per determinare a quale livello di zoom l'opzione di cache debba essere effettivamente applicata. Si disabilitano i caratteri clear type per migliorare le performance. Nell'esempio sopra esposto, il caching avviene qualora il TextBlock subisca una ScaleTransform che ne raddoppi le dimensioni. Un altro esempio è proprio quello in cui sappiamo a priori che un elemento dell'interfaccia verrà utilizzato più volte e quindi può essere conveniente memorizzarlo in cache. L'esempio seguente mostra come applicare un'immagine allo sfondo di due TextBlock utilizzando la cached composition:
<StackPanel Grid.Row="1">
<StackPanel.Resources>
<Image x:Key="cachedImage" Source="LogoVBTT.gif">
<!-- Poichè so che utilizzerò la stessa image
più volte, la metto in cache così non
verrà ripetutamente renderizzata -->
<Image.CacheMode>
<!-- stavolta il caching avviene alle dimensioni
naturali -->
<BitmapCache RenderAtScale="1" EnableClearType="False"
SnapsToDevicePixels="False"/>
</Image.CacheMode>
</Image>
<!-- Utilizzo un pennello BitmapCacheBrush
come riempimento -->
<BitmapCacheBrush x:Key="cachedBrush"
Target="{StaticResource cachedImage}"/>
</StackPanel.Resources>
<TextBlock Text="Text one..." FontSize="24" Height="60" Foreground="Red"
FontWeight="Bold"
Background="{StaticResource cachedBrush}"/>
<TextBlock Text="Text two..." FontSize="24" Height="60" Foreground="Red"
FontWeight="Bold"
Background="{StaticResource cachedBrush}"/>
</StackPanel>
</Grid>
In maniera differente dal primo esempio, qui la tecnica si applica al singolo elemento (proprietà Image.CacheMode). Per utilizzare un elemento in cache si utilizza un oggetto chiamato BitmapCacheBrush che può essere utilizzato come riempimento di altri elementi, come dimostrato dai due TextBlock. Il risultato, puramente dimostrativo, del codice è il seguente:

Alessandro
posted @ Thursday, December 03, 2009 3:35 PM