Question

Hej I am playing around with an app for windows phone 8, using MVVM.

I have a problem with acquiring the center of a pinch zoom and understanding the bounds completely on the viewportcontroller. And finally re-configuring the viewportcontroller to still scroll the entire picture. My xaml code is:

<Grid>
    <StackPanel>
        <ViewportControl Bounds="0,0,1271,1381.5" Height="480" Width="800" CacheMode="BitmapCache" RenderTransformOrigin="{Binding KontaktPunkter}" Canvas.ZIndex="1">
            <ViewportControl.RenderTransform>
                <CompositeTransform x:Name="myTransform" ScaleX="1" ScaleY="1" TranslateX="0" TranslateY="0" />
            </ViewportControl.RenderTransform>

            <View:Picture/>

        </ViewportControl>


    </StackPanel>
    <View:PopUpUC DataContext="{Binding PopUp}"/>
</Grid>

As far as I understand the Bounds is the area I want to be able to scroll, and height and width is the windows size of the control is this correct?

Answer Yes it is correct.

On to the second part :) Getting the center of the pinch zoom motion.

public void ZoomDelta(ManipulationDeltaEventArgs e)
    {

        FrameworkElement Element = (FrameworkElement)e.OriginalSource;
        ViewportControl Picture;
        Grid PictureGrid;
        double MainWidth = Application.Current.RootVisual.RenderSize.Height;
        double MainHeight = Application.Current.RootVisual.RenderSize.Width;

        if (Element is ViewportControl)
        {
            Picture = Element as ViewportControl;
        }
        else
        {
            Picture = FindParentOfType<ViewportControl>(Element);
        }

        if (Element is Grid)
        {
            PictueGrid = Element as Grid;
        }
        else
        {
            PictureGrid = FindParentOfType<Grid>(Element);
        }

        Grid ScreenGrid = FindParentOfType<Grid>(PictureGrid);

        if (e.PinchManipulation != null)
        {

            var newScale = e.PinchManipulation.DeltaScale * Map.previousScale;


            if (!IsZooming)
            {
                Point FingerOne = e.PinchManipulation.Current.PrimaryContact;
                Point FingerTwo = e.PinchManipulation.Current.SecondaryContact;
                Point center = new Point((FingerOne.X + FingerTwo.X) / 2, (FingerOne.Y + FingerTwo.Y) / 2);
                KontaktPunkter = new Point(center.X / Picture.Bounds.Width, center.Y / Picture.Bounds.Height);

                IsZooming = true;
            }


            var newscale = Map.imageScale * newScale;
            var transform = (CompositeTransform)Picture.RenderTransform;

            if (newscale > 1)
            {
                Map.imageScale *= newScale;

                transform.ScaleX = Map.imageScale;
                transform.ScaleY = Map.imageScale;

               }
            else
            {

                transform.ScaleX = transform.ScaleY = 1;
            }


        }

        e.Handled = true;
    }

In the if case if(!isZooming), I try to calculate the center. I have also tried with the different centers that can be found inside the event e. without any success. What am I doing wrong with calculating the center?

Finally after I have zoomed I cannot pan around the entire picture anymore. I therefore need to change some variable but have not been able to pin point it, while debugging or searching the web. Any Idea for this?

Answer The image should be resized, and the bounds of the viewport should be set to the new size of the resized image.

Edit Final problem is finding the center, and the problem is when this situation occurs: enter image description here since the e.PinchManipulation.Current gives relative to lightblue square, and I want it relative to the large square, i.e. the bounds. How to do this?

Was it helpful?

Solution

To overcome this problem I'd do the following. The viewportcontroller, has a scrollviewer inside, and viewport.

The basics are this:

While the image you have is "unzoomed", the scrollviewer has full control and the ViewportControl does nothing. When you start to pinch, lock the scrollviewer by disabling the verticalscrollbar AND setting the viewport.height = scrollviewer.height. This neutralizes the scollviewer. You can do a temporary zoom using the Image ScaleTransform. On pinch finished, resize your actual image so that it takes up real space inside the ViewportControl. Now your viewportControl will let you pan all over the zoomed image with nice bounce-back. When you zoom back out again, re-enable the scrollviewer. (Set the height to the screen height and turn on the scrollbar.) FYI, I completely forget why there is a canvas in there, but I feel like it is important. See below:

While the sample below does not do what you want to do, I based my code on the MediaViewer inside this sample and modified it: Basic Lens Sample

However it should be noted that it is for picture zoom.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top