Thursday , 27 April 2017
Home » Technology » Development » Centering a ScrollViewer when you Zoom or ScaleTransform in Silverlight

Centering a ScrollViewer when you Zoom or ScaleTransform in Silverlight

A client of mine wanted to center a scrollable region (ScrollViewer) in Silverlight whenever it zooms in or out. Currently, whenever you do a zoom, it will zoom in or out based on the upper left hand corner. There isn’t a lot of information regarding this, and many of which doesn’t fit this situation.

Some solutions use ScaleTransform within a RenderTransform which will zoom, however if within a ScrollViewer, it will not show the scroll simply because the view area is constraint. Another solution was to use a Viewbox and apply the zoom there, but I never did get it working.

The one solution that works was to zoom the canvas itself (or in this case I  wrapped it around a LayoutTransformer from the Silverlight Toolkit) and then move the ScrollViewer‘s scrollbar itself to the position I wanted. That’s the gist of the solution, but it’ll require some explanation. Let’s get started.

The sourcecode above is just a very simple ScrollViewer with a LayoutTransformer in it. I want to get Line 5 to center zoom whenever I zoom in or out. Right now it zooms and stays on the Top Left corner.

First up, I need to get the values of the scrollbar offsets whenever it changes. However, Silverlight 4 doesn’t have ScrollChanged event. You’ll need to simulate this by following this sample code: ScrollViewer Scroll Change Event in Silverlight. In a quick change of the code, you’ll get the following:

The most important parts are Line 34 and 35, where you set the “Loaded” event of each scrollbar. Within both “Loaded” events, you simulate a ScrollBar ScrollChanged like this:

The code above is pretty much self-explanatory. I save the relative scroll values and use them when I’m actually scrolling. In order to get the relative scroll values, I need to get current Offset (i.e. current position of the scroll) and add the mid-section of the ViewportWidth then divide that by the ExtentWidth to get the relative scroll position. There’s some math going on, but I’ll add a bit more explanation if I ever get around drawing it out.

Of course, now we need to attach the new style created above with our ScrollViewer.

Now that we’ve got everything set up, let’s do the zooming! Just attach whatever events you’re attaching it to and start zooming. For me, I attached it to a KeyUp event on the Page itself.

Just a quick explanation what’s going on. Line 3 to Line 14 does the scaling. You can change the scaling factor however you want depending on how much you want to scale. After scaling, you need to apply the layout transform in order for the zooming to be affected.

Line 16 is just to refresh my content within the LayoutTransformer.Content. You have to do this to get the reflected values on the ScrollViewer on Line 17 and 18.

Here’s where the magic begins. Line 17 and 18 essentially figures out where your scroll offsets are and sets them. There’s more math magic going on here. However, I had a problem where _relScrollX and _relScrollY wasn’t set at all if I didn’t move the scrollbar. So what I did was to use half of ScrollableWidth and ScrollableHeight (0.5 * Scroller.ScrollableWidth) whenever the values were 0 so it wouldn’t continue to zoom from the Top Left. This fixed the centering issues I had.

That’s it! Now you have a zoomed content with your ScrollViewer still able to scroll to your other “hidden” segments of your content.

P.S. The solution was gotten from the Silverlight Forums LayoutTransformer, ScaleTransform and RenderTransformOrigin which I simplified and explained what’s going on here.

About Justin Lee

Check Also

Apple WWDC 2014 Videos Podcast RSS Feed Generator using XSLT

I realised there isn’t any podcast subscription link for the Apple WWDC 2014 videos at …

4 comments

  1. Hey Man, can you provide the source?

    Thanks.

    • Apologies, but no. I’ve already highlighted and explained every single detail of how to get it working step by step. Is there anything you do not understand that I can clarify?

  2. Thanks man !!! you really did a great job here.
     

Leave a Reply