What’s Central Region (my new territory) on Silverlight?

Continuing my thoughts from when Dan Hounshell asked me what’s my territory in response to my announcement about taking on the RIA Architect Evangelist Roll. I started thinking about the Virtual Earth map overlay and thinking it’s really not rich enough. So I thought I’d spend 15 minutes or so and slap together a Silverlight visualization of the Central Region…

Much of the map I cribbed from the Silverlight Airlines application because it was easy… 🙂 I did spend some time cleaning up that XAML to have actual state names instead of some bizarre path name. I’m keeping that XAML for a lot of future fun.

*Key
Blue == Heartland District
Green == MidWest District
Orange == North Central District
Red == South Central District

I thought about just coloring the states but then that would be boring so I wrote a little bit of JavaScript to create the animation on the fly, attach it to the root and starting the animation. That’s how I got the glowing style effect on the states.

ShowState: function(control, stateName, colorName)
{
    var xaml =”<Storyboard x:Name=\”highlightState”+stateName +”\” xmlns:x=\”http://schemas.microsoft.com/winfx/2006/xaml\”>” +
       “<ColorAnimationUsingKeyFrames RepeatBehavior=\”Forever\” BeginTime=\”00:00:00\” Storyboard.TargetName=\””+stateName+
            “\” Storyboard.TargetProperty=\”(Shape.Fill).(SolidColorBrush.Color)\”>” +
            “<LinearColorKeyFrame KeyTime=\”00:00:00.0000000\” Value=\”” + colorName + “\”/>” +
            “<LinearColorKeyFrame KeyTime=\”00:00:01.0000000\” Value=\”Dark” + colorName + “\”/>” +
            “<LinearColorKeyFrame KeyTime=\”00:00:02.0000000\” Value=\”” + colorName + “\”/>” +
        “</ColorAnimationUsingKeyFrames>” +
    “</Storyboard>”

    var animation = control.content.createFromXaml(xaml);
    var root = control.content.findName(“Page”);  
    root.Resources.Add(animation);

    animation.begin();
},

The other relevant code is the resizing code.

In the load, we create and add the transform to the root element that does a ScaleTransform (read resizing transformation). The other useful thing that this function does is that it wires up the resize event handler.

    handleLoad: function(control, userContext, rootElement)
    {
        this.control = control;

        _silverlightControl = control;

        var rootCanvas = rootElement.findName(“Page”);
        if (rootCanvas) {
            _originalWidth = rootCanvas.width;
            _originalHeight = rootCanvas.height;

            rootCanvas.renderTransform = _silverlightControl.content.createFromXaml(‘<TransformGroup><ScaleTransform Name=”rootScaleTransform” ScaleX=”1″ ScaleY=”1″ /><TranslateTransform Name=”rootTranslateTransform” X=”0″ Y=”0″ /></TransformGroup>’);
            _rootScaleTransform = _silverlightControl.content.findName(“rootScaleTransform”);
            _rootTranslateTransform = _silverlightControl.content.findName(“rootTranslateTransform”);
        }

       //Wire up onResize EventHandler
        _silverlightControl.content.onResize = this.handleResize;
        this.handleResize();
        this.ShowStates(control, rootElement);
    },

After that, we listen for the resize and do the appropriate math to scale the transformation to the right size. This is cool because as we resize the root element, it will automatically take care of it’s children for us.

handleResize: function(sender, eventArgs)
{
    // Capture the current width/height
    var currentWidth = _silverlightControl.content.ActualWidth;
    var currentHeight = _silverlightControl.content.ActualHeight;

    if (_rootScaleTransform && _rootTranslateTransform && _originalWidth && _originalHeight) {
        // Scale the root Canvas to fit within the current control size
        var uniformScaleAmount = Math.min((currentWidth / _originalWidth), (currentHeight / _originalHeight));
        _rootScaleTransform.scaleX = uniformScaleAmount;
        _rootScaleTransform.scaleY = uniformScaleAmount;

        // Translate the root Canvas to center horizontally
        var scaledWidth = _originalWidth * uniformScaleAmount;
        _rootTranslateTransform.x = (currentWidth – scaledWidth) / 2;
        // var scaledHeight = _originalHeight * uniformScaleAmount;
        // _rootTranslateTransform.y = (currentHeight – scaledHeight) / 2;
    }
}

So, understand the central region’s boundaries now?

Leave a Reply

Your email address will not be published. Required fields are marked *