Mar 282011
 

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.

[sourcecode language="xml"]
<Grid x:Name="LayoutRoot">
<ScrollViewer x:Name="Scroller" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" VerticalContentAlignment="Center" HorizontalContentAlignment="Center">
<layoutToolkit:LayoutTransformer x:Name="zoomTransformer">
<layoutToolkit:LayoutTransformer.Content>
<!– Some content here –>
</layoutToolkit:LayoutTransformer.Content>
<layoutToolkit:LayoutTransformer.LayoutTransform>
<TransformGroup>
<ScaleTransform x:Name="scaleTransform" ScaleX="1" ScaleY="1"/>
</TransformGroup>
</layoutToolkit:LayoutTransformer.LayoutTransform>
</layoutToolkit:LayoutTransformer>
</ScrollViewer>
</Grid>
[/sourcecode]

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:

[sourcecode language="xml" highlight="34,35"]
<UserControl.Resources>
<!– This is from the sample provided at http://dotplusnet.blogspot.com/2010/05/scrollviewer-scroll-change-event-in.html.  It gives us access to an event when the scroll viewer is changed –>
<Style x:Key="svScrollerStyle2" TargetType="ScrollViewer">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="VerticalScrollBarVisibility" Value="Visible"/>
<Setter Property="Padding" Value="4"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AEB9" Offset="0"/>
<GradientStop Color="#FF8399A9" Offset="0.375"/>
<GradientStop Color="#FF718597" Offset="0.375"/>
<GradientStop Color="#FF617584" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2">
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollContentPresenter x:Name="ScrollContentPresenter" Cursor="{TemplateBinding Cursor}" Margin="{TemplateBinding Padding}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
<Rectangle Fill="#FFE9EEF4" Grid.Column="1" Grid.Row="1"/>
<ScrollBar x:Name="VerticalScrollBar" Margin="0,-1,-1,-1" Width="18" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" IsTabStop="False" Grid.Column="1" Grid.Row="0" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Value="{TemplateBinding VerticalOffset}" Orientation="Vertical" ViewportSize="{TemplateBinding ViewportHeight}" Loaded="VerticalScrollBar_Loaded" />
<ScrollBar x:Name="HorizontalScrollBar" Height="18" Margin="-1,0,-1,-1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" IsTabStop="False" Grid.Column="0" Grid.Row="1" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Value="{TemplateBinding HorizontalOffset}" Orientation="Horizontal" ViewportSize="{TemplateBinding ViewportWidth}" Loaded="HorizontalScrollBar_Loaded"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
[/sourcecode]

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:

[sourcecode language="csharp"]
private ScrollBar _horizontalScrollBar;
private ScrollBar _verticalScrollBar;
private double _relScrollX;
private double _relScrollY;

private void HorizontalScrollBar_Loaded(object sender, RoutedEventArgs e)
{
// Register a handler any time a user scrolls horizontally
_horizontalScrollBar = sender as ScrollBar;
_horizontalScrollBar.Scroll += horizontalScrollBar_Scroll;
}

private void VerticalScrollBar_Loaded(object sender, RoutedEventArgs e)
{
// Register a handler any time a user scrolls vertically
_verticalScrollBar = sender as ScrollBar;
_verticalScrollBar.Scroll += verticalScrollBar_Scroll;
}

void horizontalScrollBar_Scroll(object sender, ScrollEventArgs e)
{
SaveScrollerValues();
}

void verticalScrollBar_Scroll(object sender, ScrollEventArgs e)
{
SaveScrollerValues();
}

/// <summary>
/// Save the values of the scroller any time they are changed
/// </summary>
private void SaveScrollerValues()
{
// This concept is modified from the code at http://social.msdn.microsoft.com/Forums/en/wpf/thread/5202aae5-b2cc-4fc3-aa43-4541fcc856fb
if (Scroller.ExtentWidth > 0)
{
_relScrollX = (Scroller.HorizontalOffset + 0.5 * Scroller.ViewportWidth) / Scroller.ExtentWidth;
}
if (Scroller.ExtentHeight > 0)
{
_relScrollY = (Scroller.VerticalOffset + 0.5 * Scroller.ViewportHeight) / Scroller.ExtentHeight;
}
}
[/sourcecode]

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.

[sourcecode language="xml" highlight="1"]
<ScrollViewer x:Name="Scroller" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Style="{StaticResource svScrollerStyle2}">
<layoutToolkit:LayoutTransformer x:Name="zoomTransformer">
<layoutToolkit:LayoutTransformer.Content>
<!– Some content here –>
</layoutToolkit:LayoutTransformer.Content>
<layoutToolkit:LayoutTransformer.LayoutTransform>
<TransformGroup>
<ScaleTransform x:Name="scaleTransform" ScaleX="1" ScaleY="1"/>
</TransformGroup>
</layoutToolkit:LayoutTransformer.LayoutTransform>
</layoutToolkit:LayoutTransformer>
</ScrollViewer>
[/sourcecode]

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.

[sourcecode language="csharp" highlight="17,18"]
private void Page_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.X)
{
// Shrink the viewbox.
scaleTransform.ScaleX -= 0.1;
scaleTransform.ScaleY -= 0.1;
}
if (e.Key == Key.Z)
{
// Expand the viewbox.
scaleTransform.ScaleX += 0.1;
scaleTransform.ScaleY += 0.1;
}
zoomTransformer.ApplyLayoutTransform();
MyContent.UpdateLayout();
Scroller.ScrollToHorizontalOffset(Math.Max(_relScrollX * Scroller.ExtentWidth – 0.5 * Scroller.ViewportWidth, 0) == 0 ? 0.5 * Scroller.ScrollableWidth : _relScrollX * Scroller.ExtentWidth – 0.5 * Scroller.ViewportWidth);
Scroller.ScrollToVerticalOffset(Math.Max(_relScrollY * Scroller.ExtentHeight – 0.5 * Scroller.ViewportHeight, 0) == 0 ? 0.5 * Scroller.ScrollableHeight : _relScrollY * Scroller.ExtentHeight – 0.5 * Scroller.ViewportHeight);
}
[/sourcecode]

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.

Mar 242011
 

Silverlight Inspector is an awesome utility to inspect Silverlight XAP files. You’re able to view the visual tree of the application and/or control and view the various assemblies within your Silverlight XAP files. It’s pretty useful for quick debugging purposes, especially with the visual tree.

Mar 242011
 

Internet Explorer 9 is one of the biggest step for Internet Explorer, the widely used browser, offering various improvements to enhance the experience of the web.

Notably:

  • Site-Pinning, Jump-Lists, Aero-snap
  • Enhanced GPU acceleration making amazing graphics possible
  • Tracking Protection and SmartScreen malware protection

Now, you can win some prizes by installing Internet Explorer 9 on your Windows 7 machine and playing, Master Of The Web, a fully graphics accelerated HTML 5 compliant game on your browser without the use of any plugin like Adobe Flash or Microsoft Silverlight.

Dec 062010
 


Get Microsoft Silverlight

Summary of the new features of Silverlight 5:

Premium Media Experiences
  • Hardware video decode: GPU accelerated video decode
  • Trickplay: automatic audio pitch correction
  • Improved power awareness: prevent screensavers from kicking
  • Remote-control support: control media playback with remote control devices (Silverlight TV?)
Application Development
  • Databinding and MVVM
    • Debug data-binding expressions, set breakpoints on bindings, and more easily determine errors
    • Implicit DataTemplates allow templates to be created across an application to support a particular type by default.
    • Ancestor RelativeSource bindings for a DataTemplate to bind to a property on a container control
    • Binding in style setters allows bindings to be used within styles to reference other properties
    • New DataContextChanged event to make handling changes easier
    • Markup extensions are now supported and allows code to be run at XAML parse time for both properties and event handlers, enabling cutting-edge MVVM support
  • WCF and RIA Services
    • WS-Trust support
    • WCF RIA Services improvements include complex type support, better MVVM support, and improved customization of code generation
    • Networking stack supports low-latency network scenarios enabling more responsive application scenarios.
  • Text and Printing
    • Improved text clarity that enables crisper and cleaner text rendering, multi-column text flow and linked text containers, character and leading support, and full OpenType font support
    • New Postscript Vector Printing API that provides programmatic control over what you print, and enables printing richer reports and documents
    • Pivot functionality which enables developers to build amazing information visualization experiences
  • Graphics
    • Immediate mode graphics support enables accelerated 3-D graphics support
    • Enables richer data visualization scenarios
  • Out of Browser
    • OOB can now create and manage child windows
    • Trusted out of browser applications can use P/Invoke capabilities to call unmanaged libraries and Win32 APIs
    • Enhanced group policy support enables enterprises to both lock down and open up security sandbox capabilities
  • Testing Tools
    • Automated UI testing support
  • Performance
    • Faster application startup, and provides 64-bit browser support
    • Integrates with the Hardware Acceleration capabilities of IE9, and enables hardware acceleration in window-less mode
Nov 042010
 

Develop your first applications for Windows Phone 7 using Microsoft XNA and Silverlight—expertly guided by award-winning author Charles Petzold. This book is a gift from the Windows Phone 7 team and Microsoft Press to the programming community.

PDF: Programming Windows Phone 7
CODE: Microsoft_Press_ebook_Programming_Windows_Phone_7_Sample_Code.zip

Feb 112010
 

The first meeting of the Singapore Silverlight User Group at HackerspaceSG went pretty well yesterday.

We had Michael Sync talk about the new features of Silverlight 4.0. We had a bunch of guys who came from Microsoft Singapore to witness the formation of this group. We had about 10 people who turned up just to join the group! After that, we had a great discussion on MEF with Silverlight, F# and C# language features, and various other discussions on the side. I thought it was a great night with a good mix of discussions, random thoughts, Mac vs Windows clashes, and I hope that the community loved it.

Our next meeting will be sometime in March, so look out for the announcements! :)

Take a look at some of the photos.

Jul 022008
 

Flash content is finally searchable by two of the biggest online search engines on the internet, Google and Yahoo.

One of the biggest disadvantage of using Flash content for your dynamic content is simply because it is not searchable, and now with Adobe’s new optimized Adobe Flash Player helping both Google and Yahoo to search and index Flash content, this means that there is no excuse left NOT TO USE FLASH on your web sites.

Note that Microsoft Live Search was not included in this partnership.

Now, for those enthusiastic about writing Silverlight content on the web, might I ask, what is Microsoft going to do about this? Both in its Live Search, making it competitive with Google and Yahoo to search Flash content, and also making Silverlight content searchable too. This is the biggest advantage Adobe Flash has over Silverlight now, and if Microsoft doesn’t do anything about it, the web will not be convinced about Silverlight, regardless of the amount of bribing promoting they can and will do.

Adobe, we love you and thank you.

To those Silverlight enthusiasts, please get your facts right about Adobe Flash before even bashing Adobe Flash technology. You know who you are.

Apr 262008
 

I copied this blog post from Chris Dufour’s blog. Chris copied it from Rob Windsor’s blog. Rob copied it from Julie Lerman’s blog. Julie copied it from Guy Barrette’s blog. I’m sure someone will copy it from me and add their own little flair.

If you live in Toronto and don’t attend DevTeach, Guy Barrette is going to make you code in Clipper for the remainder of your career (BTW – that’s Clipper development with no Multi Edit and no Norton Guides. Ah, there, now you’re shaking).  Seriously, DevTeach has a great lineup of speakers from Toronto and across the globe. Where else can you hear, see, touch, feel, talk to, describe your problems (IT/Dev related or not) and have a beer with these guys/gals?

And that’s only half of them!!!

Need more reasons?

Keynote by Scott Hanselman
Scott is one of the most prolific, renowned and respected bloggers (
http://www.hanselman.com) and podcasters (http://www.hanselminutes.com) in the .NET world. Scott is a hands-on thinker, a renowned speaker and writer. He has written a few books, most recently with Bill Evjen and Devin Rader on Professional ASP.NET. In July 2007, he joined Microsoft as a Senior Program Manager in the Developer Division. In his new role he’ll continue to explore and explain a broad portfolio of technologies, both inside and outside Microsoft. He aims to spread the good word about developing software, most often on the Microsoft stack. Before this he was the Chief Architect at Corillian Corporation, now a part of Checkfree, for 6+ years and before that he was a Principal Consultant at STEP Technology for nearly 7 years.
http://www.devteach.com/keynote.aspx

Silverlight 2.0 Workshop
For the first time an independent conference is having a workshop on Building Business Applications with Silverlight 2.0.  Join Rod Paddock and Jim Duffy as they give you a head start down the road to developing business-oriented Rich Internet Applications (RIA) with Microsoft Silverlight 2.0. Microsoft Silverlight 2.0 is a cross-browser, cross-platform, and cross-device plug-in positioned to revolutionize the way next generation Rich Internet Applications are developed. Microsoft’s commitment to providing an extensive platform for developers and designers to collaborate on creating the next generation of RIAs is very clear and its name is Silverlight 2.0. In this intensive, full-day workshop, Rod and Jim will share their insight and experience building business applications with Silverlight 2.0 including a review of some of the Internet’s more visible Silverlight web applications. This workshop is happening on Friday May 16 at the Hilton Toronto.
http://www.devteach.com/PostConference.as
px#PreSP

Bonus session: .NET Rocks hosts a panel May 14th at 18:00
This year the bonus session (Wednesday May 14 at 18:00) will be a panel of speakers debating the Future of .NET. Where is .NET going? How will new development influence .NET and be influenced by .NET? Join Carl Franklin and Richard Campbell from .NET Rocks as they moderate a discussion on the future directions of .NET. The panellists include individuals who have strong visions of the future of software development and the role that .NET can play in that future. Attend this session and bring your questions to get some insight into the potential future of .NET! This bonus session is free for everyone. Panelists are: Ted Neward,Oren Eini ,Scott Bellware
http://www.devteach.com/BonusSession.aspx

Party with Palermo, DevTeach Toronto Edition
Jeffrey Palermo (MVP) is hosting Monday May 12th in Toronto is acclaimed “Party with Palermo”. This is the official social event  kicking off DevTeach Toronto. The event is not just for the attendees of Toronto it’s  a free event for everyone. It’s a unique chance for the attendees, speakers and locals  to meet and talk with a free beer.   The event will be held at the Menage club  location and you need to RSVP to attend. Get all the details at this link:
http://www.partywithpalermo.com/

DevTeach Toronto is going to be a lot of fun and a great chance to learn from the best minds in the industry.  Register now – you don’t want to miss out.

Nov 202007
 

The Farseer Physics Engine is an easy to use 2D physics engine designed for Microsoft’s XNA and Silverlight platforms. The Farseer Physics Engine focuses on simplicity, useful features, and enabling the creation of fun, dynamic games.

Features

  • General
    • Easy To Use!
    • Support for XNA (XBOX 360 and Windows)
    • Support for Silverlight (1.1 and above)
    • Support for Managed .Net Languages In General
  • Collison
    • Concave and Convex Polygons Supported
    • Multiple Collision Geometries Per Body
    • Collision Categories For Complex Interaction Between Physics Objects
    • Collision Callback Mechanism
  • Dynamics
    • Joints
      • Revolute Joint (body to body or fixed to world)
      • Angle Joint (body to body or fixed to world)
      • Slider (Prismatic) Joint
      • Pin (Distance) Joint
    • Force Controllers
      • Linear Spring
      • Angular Spring
      • Easy To Build Custom Force Controllers (Explosions, Steering Behaviors, etc.)
  • Support and Debugging
    • Samples Framework With Samples Covering Most Major Engine Features. (XNA and Silverlight versions)
    • Debug Viewer To View All Major Physics Objects (part of samples framework)
    • User Manual (in progress)

Interview from InfoQ

Although intended for games, a physics engine can be used for UI effects too. This would generally be very useful to create cool effects, especially on Silverlight applications.