C# 使用PinchGestureRecognitor时图像在缩放时闪烁

C# 使用PinchGestureRecognitor时图像在缩放时闪烁,c#,xamarin,xamarin.forms,zooming,pinchzoom,C#,Xamarin,Xamarin.forms,Zooming,Pinchzoom,我使用下面的代码放置和以实现缩放功能。 还提供了事件PinchUpdated=“pinchgestrerecognizer\u PinchUpdated”的代码隐藏。 缩放功能可以工作,但在挤压时闪烁过多 XAML: <Image Grid.Column="0" Grid.Row="0" x:Name="pageIte

我使用下面的代码放置
以实现缩放功能。 还提供了事件
PinchUpdated=“pinchgestrerecognizer\u PinchUpdated”
的代码隐藏。 缩放功能可以工作,但在挤压时闪烁过多

XAML:

            <Image 
                Grid.Column="0" 
                Grid.Row="0"
                x:Name="pageIterator"
                Grid.ColumnSpan="3">
                <Image.GestureRecognizers>
                    <PinchGestureRecognizer PinchUpdated="PinchGestureRecognizer_PinchUpdated"></PinchGestureRecognizer>
                </Image.GestureRecognizers>
            </Image>
        private void PinchGestureRecognizer_PinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
        {
            double currentScale = 1;
            double startScale = 1;
            double xOffset = 0;
            double yOffset = 0;

            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;
            }
            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;
            }
            if (e.Status == GestureStatus.Completed)
            {
                // Store the translation delta's of the wrapped user interface element.
                xOffset = Content.TranslationX;
                yOffset = Content.TranslationY;
            }
        }



您应该将下面的行移出
pinchgestrerecognizer\u PinchUpdated
方法,否则每次启动时都会初始化这些值

double currentScale = 1;
double startScale = 1;
double xOffset = 0;
double yOffset = 0;

private void PinchGestureRecognizer_PinchUpdated(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;
        }
        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;
        }
        if (e.Status == GestureStatus.Completed)
        {
            // Store the translation delta's of the wrapped user interface element.
            xOffset = Content.TranslationX;
            yOffset = Content.TranslationY;
        }
    }

您应该将下面的行移出
pinchgestrerecognizer\u PinchUpdated
方法,否则每次启动时都会初始化这些值

double currentScale = 1;
double startScale = 1;
double xOffset = 0;
double yOffset = 0;

private void PinchGestureRecognizer_PinchUpdated(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;
        }
        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;
        }
        if (e.Status == GestureStatus.Completed)
        {
            // Store the translation delta's of the wrapped user interface element.
            xOffset = Content.TranslationX;
            yOffset = Content.TranslationY;
        }
    }

currentScale可能应该是
if(e.Status==GestureStatus.Running)
范围内的一个局部变量。@Liron不,它也应该在方法之外,事实上,每次它激发时,都会先激发
PinchGetureRecognizer\u PinchUpdated
,然后进入
if()
,如果你把它作为局部变量放在方法中,你可以看到它每次仍然以值1开始。你可以做一个测试,把它作为局部变量放在方法中,然后调用
Console.WriteLine(“Current:=”+currentScale)
中如果(e.Status==GestureStatus.Running)
,您每次都会看到它在控制台
1
。@LeoZhu MSFT,我会检查它并在这里更新。我在猜测初始化,但由于我是新来的,我认为必须在一开始就开始。@LeoZhu MSFT它在放大(做大)时起作用。但当缩小时(回到正常大小时),它再次闪烁。这意味着我必须把一些代码移到外面…@LeoZhu MSFT好吧,我正在检查Xamarin的演示程序PinchGesture,希望我能看清楚代码。我将更新.currentScale可能应该是
if(e.Status==GestureStatus.Running)
范围内的一个局部变量。@Liron不,它也应该在方法之外,事实上,每次它启动时,它都会先启动
pinchgestureRecognitizer\u PinchUpdated
,然后进入
if()
,如果你把它作为局部变量放在方法中,你可以看到它每次仍然以值1开始。你可以做一个测试,把它作为局部变量放在方法中,然后调用
Console.WriteLine(“Current:=”+currentScale)
中如果(e.Status==GestureStatus.Running)
,您每次都会看到它在控制台
1
。@LeoZhu MSFT,我会检查它并在这里更新。我在猜测初始化,但由于我是新来的,我认为必须在一开始就开始。@LeoZhu MSFT它在放大(做大)时起作用。但当缩小时(回到正常大小时),它再次闪烁。这意味着我必须把一些代码移到外面…@LeoZhu MSFT好吧,我正在检查Xamarin的演示程序PinchGesture,希望我能看清楚代码。我会更新。