Thursday, March 27, 2008

Dissecting Hard Rock Memorabilia and Silverlight Deep Zoom - Part 3

In Part 2 we saw the code for arranging the images in a nice clean layout. This post will discuss when to call the ArrangeImages() method.

When the page that contains the Silverlight control is first loaded, the MultiScaleImageControl will load the images and render it on the screen. The issue here is that the ArrangeImages method hasn't had a chance to do its magic yet! Hence we have to intercept the MultiScaleImage control somehow before it renders the images. This can be achieved by the following 2 steps:
  1. Set UseSprings to false in the Xaml
  2. <MultiScaleImage x:Name="msi" UseSprings="false"/>
  3. Intercept the MultiScaleImage.Motionfinished Event. Call ArrangeImages in this handler

  4. msi.MotionFinished += delegate(object sender, RoutedEventArgs e)
    // This is required to ensure that ArrangeImages is called only once
    if(msi.UseSprings == false) {
    msi.UseSprings = true;
In addition, the ArrangeImages method can be called on demand - as in a button click or after the dataset is filtered.

Here is a sample image of what the output looks like after ArrangeImages is called on 17 arbitrarily cropped images


Yuvi said...

tried this?

That gives you the Hardrock app's xap, which you can unzip to find the dlls. And then you can use Lutz's .NET Reflector to look at the code...

I looked at the code, but my smaller peanut-sized brain couldn't grok anything out of it. Perhaps you can do better...

Also, if you digg in, you will find a Microsoft.LiveLabs.Seadragon namespace in a dll installed with the Composer, which turns out to be a managed wrapper over unmanaged code. You could explore that as well..

Email: (currently building a 12k image seadragon image)

Deepa said...

Thanks for the great example. It helped me a lot!

We can also call ArrangeImages in ImageOpenSucceeded event of the MultiScaleImage.

In PageLoad attach it like so:
this.msi.ImageOpenSucceeded += new RoutedEventHandler(msi_ImageOpenSucceeded);

and then call like follows:
void msi_ImageOpenSucceeded(object sender, RoutedEventArgs e)

I tried this and it works well too.