Lorsque l'on souhaite animer de nombreux objets en appliquant des effets (ombrage par exemple), on peut rapidement tomber sur des problèmes de performance. Un exemple : soit des fiches produits avec une animation à la iTunes. Chaque fiche contient des images, du texte et des boutons. L'une des images a une ombrage. Lorsqu'on anime une quinzaine de fiches en même temps, on a le temps de prendre un café :(

 Une solution peut alors consister à animer une image de l'objet, et non l'objet. Le bout de code suivant montre comment le faire sur un objet image avec un effet ombrage, mais cela marche aussi sur des boutons ou des canvas :

            // un peu de code en dur pour le principe :)

            int width = 88;
            int height = 98;
            int pixelsize = 4;
            int stride = width * pixelsize;

            // Chargement de l'image compilée comme ressource
            BitmapImage ImageFromAssembly = new BitmapImage();
            ImageFromAssembly.BeginInit();
            ImageFromAssembly.UriSource = new Uri("pack://application:,,,/1786538.png");
            ImageFromAssembly.EndInit(); 

            // Création de l'objet image
            Image notebook = new Image();        
            notebook.Source =  ImageFromAssembly;

            // Application de l'ombre
            DropShadowBitmapEffect be = new DropShadowBitmapEffect();
            be.Opacity = 0.8;
            notebook.BitmapEffect = be;

             // On force le rendu en mémoire
            RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
            notebook.Measure(new Size(width, height));
            notebook.Arrange(new Rect(0, 0, width, height));
            notebook.UpdateLayout();
            rtb.Render(notebook);

             // On copie les pixels, on créé une nouvelle source d'image et on l'affecte à l'objet à animer
            Array pixels = new int[width * height * pixelsize];
            rtb.CopyPixels(pixels, stride, 0);
             BitmapSource newBms = BitmapSource.Create((int)width, (int)height, 96, 96, PixelFormats.Pbgra32, null, pixels, stride);
             img.Source = newBms;

Ce faisant, on peut maintenant faire bouger l'image ombrée sans payer le prix de l'effet à chaque recalcul.