Know your place in life [Free PlaceImage control makes it easy to add placeholder images to any WPF, Silverlight, or Windows Phone application!]
One of the challenges with referencing online content is that you never know just how long it will take to download... On a good day, images show up immediately and your application has exactly the experience you want. On a bad day, images take a looong time to load - or never load at all! - and your application's interface is full of blank spaces. Applications that make use of remote images need to be prepared for variability like this and should have "placeholder" content to display when the desired image isn't available.
Of course, there are a variety of ways to deal with this; I thought it would be neat to create a reusable, self-contained class and share it here. I envisioned a simple control that "looked" like a standard Image element (i.e., had the same API), but that seamlessly handled the work of displaying placeholder content before an image loaded and getting rid of it afterward. Naturally, I also wanted code that would run on WPF, Silverlight, and Windows Phone!
<delay:PlaceImage PlaceholderSource="PlaceholderPhoto.png" Source="{Binding ImageUri}"/>
The result of this exercise is something I've called PlaceImage
. PlaceImage
has the same API as the framework's Image
and can be dropped in pretty much anywhere an Image
is used. To enable the "placeholder" effect, simply set the PlaceholderSource
property to a suitable image. (Aside: While you could specify another remote image for the placeholder, the most sensible thing to do is to reference an image that's bundled with the application (e.g., as content or a resource).) PlaceImage
immediately shows your placeholder image and waits for the desired image to load - at which point, PlaceImage
swaps it in and gets rid of the placeholder!
I've written a sample application for each of the supported platforms that displays contact cards of imaginary employees. When the sample first runs, none of the remote images have loaded, so each card shows the "?" placeholder image:
After a while, some of the remote images will have loaded:
Eventually, all the remote images load:
Thanks to placekitten for the handy placeholder images!
Making use of online content in an application is easy to do and a great way to enrich an application. However, the unpredictable nature of the network means content might not always be available when it's needed. PlaceImage
makes it easy to add placeholder images to common scenarios and helps keep the user interface free of blank spaces. With easy support for WPF, Silverlight, and Windows Phone, you can add it to pretty much any XAML-based application!
Notes:
-
Just like
Image
,PlaceImage
has properties for Source, Stretch, and StretchDirection (the last being available only on WPF).PlaceImage
's additionalPlaceholderSource
property is used just likeSource
and identifies the placeholder image to be displayed before theSource
image is available. (So set it to a local image!) -
Changes to the
Source
property of a loadedImage
immediately clear its contents. Similarly, changing theSource
of a loadedPlaceImage
immediately switches to its placeholder image while the new remote content loads. You can trigger this behavior in the sample application by clicking any kitten. -
Because the Silverlight version of the demo application references web content, it needs to be run from the
PlaceImageDemoSL.Web
project. (Although runningPlaceImageDemoSL
will show placeholders, the kitten pictures never load.) The MSDN article URL Access Restrictions in Silverlight has more information on Silverlight's "cross-scheme access" limitations. -
Control subclasses typically live in a dedicated assembly and define their default Style/Template in
Generic.xaml
. This is a great, general-purpose model, but I wantedPlaceImage
to be easy to add to existing projects in source code form, so it does everything in a single file. All you need to do is includePlaceImage.cs
in your project, andPlaceImage
will be available in theDelay
namespace. -
The absence of the
StretchDirection
property on Silverlight and Windows Phone isn't the only platform differencePlaceImage
runs into: whereas Silverlight and Windows Phone offer the handy Image.ImageOpened event, WPF has only the (more cumbersome) BitmapSource.DownloadCompleted event. The meaning of these two events isn't quite identical, but for the purposes ofPlaceImage
, they're considered equivalent.