views:

96

answers:

1

Is there anyone who experienced with the scrollviewer component in WPF? I have a basic selection zoom, and the problem is that it does not scroll to the right place.

Output, trying to zoom the flower: alt text

Actually, the RectangleZoom (see bellow) method scales the picture, but it does not focus it on the specified rectangle, but always in the same position... I believe there is a way to scroll to that position, but till now, any success....

Here is my code: XAML:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <ScrollViewer x:Name="scrollViewer"
                  HorizontalScrollBarVisibility="Auto">
        <Canvas Height="200" Name="mainCanvas" Width="400"
                MouseLeftButtonDown="mainCanvas_MouseLeftButtonDown"
                MouseLeftButtonUp="mainCanvas_MouseLeftButtonUp"
                MouseMove="mainCanvas_MouseMove">
            <Canvas.Background>
                <ImageBrush ImageSource="/WpfApplication3;component/Images/natural-doodle.jpg"/>
            </Canvas.Background>
            <Canvas.LayoutTransform>
                <TransformGroup>
                    <ScaleTransform x:Name="scaleTransform"/>
                </TransformGroup>
            </Canvas.LayoutTransform>
        </Canvas>
    </ScrollViewer>
</Window>

Code behind:

public partial class MainWindow : Window
{
    private Point startPoint;
    private Point endPoint;
    private Shape rubberBand;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void mainCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (!mainCanvas.IsMouseCaptured)
        {
            startPoint = e.GetPosition(mainCanvas);
            Mouse.Capture(mainCanvas);
        }
    }

    private void mainCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        if (mainCanvas.IsMouseCaptured)
        {
            if (rubberBand != null)
            {
                this.RectangleZoom(
                    Canvas.GetLeft(rubberBand),
                    Canvas.GetTop(rubberBand),
                    rubberBand.Width,
                    rubberBand.Height);

                mainCanvas.Children.Remove(rubberBand);
                rubberBand = null;
                mainCanvas.ReleaseMouseCapture();
            }
        }
    }

    private void mainCanvas_MouseMove(object sender, MouseEventArgs e)
    {
        if (mainCanvas.IsMouseCaptured)
        {
            endPoint = e.GetPosition(mainCanvas);
            if (rubberBand == null)
            {
                rubberBand = new Rectangle();
                rubberBand.Stroke = Brushes.Red;
                rubberBand.StrokeDashArray = new DoubleCollection(new double[] { 4, 2 });
                mainCanvas.Children.Add(rubberBand);
            }

            rubberBand.Width = Math.Abs(startPoint.X - endPoint.X);
            rubberBand.Height = Math.Abs(startPoint.Y - endPoint.Y);

            double left = Math.Min(startPoint.X, endPoint.X);
            double top = Math.Min(startPoint.Y, endPoint.Y);

            Canvas.SetLeft(rubberBand, left);
            Canvas.SetTop(rubberBand, top);
        }
    }


    private void RectangleZoom(double x, double y, double width, double height)
    {
        double rWidth = scrollViewer.ViewportWidth / width;
        double rHeight = scrollViewer.ViewportHeight / height;
        double rZoom = 1.0;

        if (rWidth < rHeight)
            rZoom = rWidth;
        else
            rZoom = rHeight;

        scaleTransform.ScaleX = rZoom;
        scaleTransform.ScaleY = rZoom;
    }
}
+1  A: 

You got it all but three lines:

Add these to the bottom of your RetangleZoom method:

    Point newXY = scaleTransform.Transform(new Point(x, y));
    scrollViewer.ScrollToHorizontalOffset(newXY.X);
    scrollViewer.ScrollToVerticalOffset(newXY.Y);
Kelly
oh... my God!... so just a scale transform on the point... really cool thanks! I spent some hours to this... :")
serhio
by the way... is there a possibility to keep the size of the rubberband unscaled when doing this transformations? the rubber band in big scaling became huge!
serhio