Search code examples
classxamarinlocal

Xamarin - Local:PinchPanContainer was not found


I'm not able to find what I am doing wrong. I have Picture.xaml page, and the line <local:PinchPanContainer> lines give the error "the type 'local:PinchPanContainer' was not found ..... " both files are in the Views folder.

Picture.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:d="http://xamarin.com/schemas/2014/forms/design"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         mc:Ignorable="d"
         xmlns:local="clr-namespace:GalShare.Views;assembly=GalShare" 
         x:Class="GalShare.Views.Picture">
<ContentPage.ToolbarItems>
    <ToolbarItem Text="Save to gallery" Order="Primary" Clicked="SaveToGal_Clicked"></ToolbarItem>        
</ContentPage.ToolbarItems>
<ContentPage.Content>
    <StackLayout>
        <ActivityIndicator BindingContext="{x:Reference MyImage}" IsRunning="{Binding IsLoading}"/>
        <local:PinchPanContainer>
            <local:PinchPanContainer.Content HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
              <Image x:Name="MyImage"  HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/>
            </local:PinchPanContainer.Content>
        </local:PinchPanContainer>
    </StackLayout>
</ContentPage.Content>

PitchPanContainer.cs:

using System;
using Xamarin.Forms;
using Xamarin.Forms.Internals;

namespace GalShare.Views
{
public class PinchPanContainer : ContentView
{
    double currentScale = 1;
    double startScale = 1;
    double xOffset = 0;
    double yOffset = 0;
    bool blnDisableMove = false;

    public PinchPanContainer()
    {
        var pinchGesture = new PinchGestureRecognizer();
        pinchGesture.PinchUpdated += OnPinchUpdated;
        GestureRecognizers.Add(pinchGesture);

        var panGesture = new PanGestureRecognizer();
        panGesture.PanUpdated += OnPanUpdated;
        GestureRecognizers.Add(panGesture);
    }

    void OnPanUpdated(object sender, PanUpdatedEventArgs e)
    {
        if (Content.Scale == 1)
        {
            return;
        }

        switch (e.StatusType)
        {
            case GestureStatus.Running:

                if (!blnDisableMove)
                {
                    Content.TranslationX = Math.Max(Math.Min(0, xOffset + (e.TotalX * Scale)), -Math.Abs((Content.Width * Content.Scale) - Application.Current.MainPage.Width));
                    Content.TranslationY = Math.Max(Math.Min(0, yOffset + (e.TotalY * Scale)), -Math.Abs((Content.Height * Content.Scale) - Application.Current.MainPage.Height));
                }

                break;

            case GestureStatus.Completed:

                if (blnDisableMove)
                {
                    blnDisableMove = false;
                    return;
                }
                // Store the translation applied during the pan
                xOffset = Content.TranslationX;
                yOffset = Content.TranslationY;
                break;
        }
    }

    void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
    {
        if (e.Status == GestureStatus.Started)
        {
            // Store the current scale factor applied to the wrapped user interface element,
            // and zero the components for the center point of the translate transform.
            startScale = Content.Scale;
            Content.AnchorX = 0;
            Content.AnchorY = 0;
            blnDisableMove = true;
        }
        if (e.Status == GestureStatus.Running)
        {
            // Calculate the scale factor to be applied.
            currentScale += (e.Scale - 1) * startScale;
            currentScale = Math.Max(1, currentScale);

            // The ScaleOrigin is in relative coordinates to the wrapped user interface element,
            // so get the X pixel coordinate.
            double renderedX = Content.X + xOffset;
            double deltaX = renderedX / Width;
            double deltaWidth = Width / (Content.Width * startScale);
            double originX = (e.ScaleOrigin.X - deltaX) * deltaWidth;

            // The ScaleOrigin is in relative coordinates to the wrapped user interface element,
            // so get the Y pixel coordinate.
            double renderedY = Content.Y + yOffset;
            double deltaY = renderedY / Height;
            double deltaHeight = Height / (Content.Height * startScale);
            double originY = (e.ScaleOrigin.Y - deltaY) * deltaHeight;

            // Calculate the transformed element pixel coordinates.
            double targetX = xOffset - (originX * Content.Width) * (currentScale - startScale);
            double targetY = yOffset - (originY * Content.Height) * (currentScale - startScale);

            // Apply translation based on the change in origin.
            Content.TranslationX = targetX.Clamp(-Content.Width * (currentScale - 1), 0);
            Content.TranslationY = targetY.Clamp(-Content.Height * (currentScale - 1), 0);

            // Apply scale factor.
            Content.Scale = currentScale;

            blnDisableMove = true;
        }
        if (e.Status == GestureStatus.Completed)
        {
            // Store the translation delta's of the wrapped user interface element.
            xOffset = Content.TranslationX;
            yOffset = Content.TranslationY;

            blnDisableMove = true;
        }
    }
}
}

What am I doing wrong?


Solution

  • The reason it's not working is that you are using it incorrectly the expansion options should not be on the Content property but the line above it where you declare the layout, below is how your container should look

      <local:PinchPanContainer HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
              <Image x:Name="MyImage"  HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/>
        </local:PinchPanContainer>
    

    Also, note the Content property is a View's default so it will directly consider the children of your View as a value for that property.

    Also, your namespace doesn't need to specify the assembly as you are using it in the same assembly!

       xmlns:local="clr-namespace:GalShare.Views" 
    

    Good luck

    Feel free to get back if you have questions