Thursday, January 24, 2008

Update: Zoom multiple controls from the same slider in XAML

I've had a serious learning curve with XAML, and frequently find new and better ways of doing things. A good example of this is zooming multiple controls from the same slider. My previous solution used a DependencyProperty and an IValueConverter and was probably slow as dirt if you wired up more than a few controls to get zoomed. A much more succinct, maintainable, and readable solution would be:
<Page class="ZoomTest.Page1" name="page" xmlns="...">
xmlns:local="clr-namespace:ZoomTest"
local:AttachedProperties.Zoom="0.8">
<Grid>
<Grid.LayoutTransform>
<ScaleTransform ScaleX="{Binding Path=Zoom,
ElementName=page}"
ScaleY="{Binding Path=Zoom,
ElementName=page}" />
</Grid.LayoutTransform>
</Grid>
</Page>
And yes, while I do have two bindings, it actually is very fast. One of the big things I've learned is you can really (ab)use the binding system and strangely enough have a faster UI than one you control! In a GUI application I'm designing in WPF, there are over 5000 data bindings on just one page, and yet it is nearly twice as fast as the version where I practically precompute the whole UI! My only guess as to why this is the case is that UIElement's are much more expensive than data bindings.

Another way to tackle the above problem, if say you're on the same UI without Page's, is actually much simpler:
<Window ...>
<DockPanel x:Name="LayoutRoot"
LastChildFill="True">
<StackPanel DockPanel.Dock="Top">
<Slider x:Name="ZoomSlider"
Minimum="1" Value="5" Maximum="10" />
</StackPanel>
<ScrollViewer>
<Grid x:Name="content">
<Grid.LayoutTransform>
<ScaleTransform ScaleX="{Binding Path=Value,
ElementName=ZoomSlider}"
ScaleY="{Binding Path=Value,
ElementName=ZoomSlider}" />
</Grid.LayoutTransform>
</Grid>
</ScrollViewer>
</DockPanel>
</Window>
Using strategies like this you can use less C# and more XAML. I've been able to take over 7000 lines of presentation code written for Java 1.4 (the C# 2.0 code would be roughly the same size) and turn it into roughly 550 lines of XAML and 100 lines of C# 3.0. Expect more little fun things you can do with WPF soon (like making a ListBox do whatever you please).

No comments: