views:

772

answers:

1

Hi. I am making a sort of "print preview" control for some documents in my Silverlight 3 application. I have a Canvas (for showing the document) inside of a ScrollViewer, and I have zoom in / zoom out buttons that control the X and Y Scale properties of the ScaleTransform for the Canvas.RenderTransform property. I want the scrollbars of the ScrollViewer to show up when I "zoom in" enough such that the canvas is no longer visible in the ScrollViewer area, but it seems that they only show up depending on the Width/Height of the Canvas itself, regardless of whether it is zoomed in or not.

Can anyone help?

+7  A: 

Yeah, the problem is that there is no LayoutTransform in Silverlight. There are some workarounds to this problem listed here.

The idea here is to provide an intermediate canvas that gets resized and as a result, resizes the scrollable area. For example, if I have the following XAML:

<Grid x:Name="LayoutRoot">
    <Grid.RowDefinitions>
        <RowDefinition Height="200" />
        <RowDefinition Height="25" />
    </Grid.RowDefinitions>
        <ScrollViewer Grid.Row="0" x:Name="sc" VerticalScrollBarVisibility="Auto" 
                      HorizontalScrollBarVisibility="Auto" Width="200" Height="200" >
        <Canvas x:Name="sizer" Width="200" Height="200">
            <Rectangle x:Name="gradientRect" Width="200" Height="200">
            <Rectangle.RenderTransform>
                <ScaleTransform ScaleX="1" ScaleY="1"/>
            </Rectangle.RenderTransform>
                <Rectangle.Fill>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                        <GradientStop Color="Red" Offset="0.1"/>
                        <GradientStop Color="Yellow" Offset="0.5"/>
                        <GradientStop Color="Red" Offset="0.9"/>
                    </LinearGradientBrush>
                </Rectangle.Fill>
            </Rectangle>
        </Canvas>
    </ScrollViewer>
    <Button Grid.Row="1" Content="Multiply by Two" Click="ScaleRect" Width="100" Height="25"></Button>
</Grid>

You'll notice that I put the <Canvas x:Name="sizer"/> between the <ScrollViewer/> and <Rectangle/> and the click event of ScaleRect in the <Button/>.

The ScaleRect sub simply scales the rectangle by 2. That value is then used to change the sizer Width and Height, thus updating the ScrollViewer's scrollbars. Here's the sub for ScaleRect:

Private Sub ScaleRect(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim zoom As Double = 2.0
    Dim scaleX = gradientRect.RenderTransform.GetValue(ScaleTransform.ScaleXProperty)
    Dim scaleY = gradientRect.RenderTransform.GetValue(ScaleTransform.ScaleYProperty)
    gradientRect.RenderTransform.SetValue(ScaleTransform.ScaleXProperty, scaleX * zoom)
    gradientRect.RenderTransform.SetValue(ScaleTransform.ScaleYProperty, scaleY * zoom)
    sizer.Height *= zoom
    sizer.Width *= zoom
End Sub
Otaku
If you want to give a more informative solution (and not just a link), I will award the bounty to you.
skb
Sure, no problem, I'll update with code to show you.
Otaku
Thank you. I still was hoping to see how you can get it to stay centered on the scroll area. I already gave you the bounty. If you can, will you help with this? Thanks!
skb
@skb. the link above has the exact code in C# on how to keep it centered.
Otaku