加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

windows-phone-7.1 – 缩放在列表框中绑定的缩放图像

发布时间:2020-12-14 03:52:01 所属栏目:Windows 来源:网络整理
导读:我正在尝试在我的应用程序中实现压缩缩放.我找到了这篇文章( Correct Pinch-Zoom in Silverlight ),它可以很好地适用于一个图像.但问题是,我的图像在列表框内,如下面的XAML所示: ListBox x:Name="lstImage" Margin="-20,-23,-12,32" Height="709" Width="48
我正在尝试在我的应用程序中实现压缩缩放.我找到了这篇文章( Correct Pinch-Zoom in Silverlight),它可以很好地适用于一个图像.但问题是,我的图像在列表框内,如下面的XAML所示:

<ListBox x:Name="lstImage" Margin="-20,-23,-12,32" Height="709" Width="480">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding Path=ImageSource}" VerticalAlignment="Top" Margin="10,12,10,10" Width="640" Height="800">
            </Image>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

我无法理解如何实施该解决方案.提前致谢.

解决方法

创建一个名为PinchZomBehavior.cs的类,并添加以下代码.

public class PinchZomBehavior : Behavior<Image>
{
    private double _totalImageScale = 1d;
    private Point _imagePosition = new Point(0,0);
    private const double MaxImageZoom = 5;
    private Point _oldFinger1;
    private Point _oldFinger2;
    private double _oldScaleFactor;
    private Image _imgZoom;

    protected override void OnAttached()
    {
        _imgZoom = AssociatedObject;

        _imgZoom.RenderTransform = new CompositeTransform { ScaleX = 1,ScaleY = 1,TranslateX = 0,TranslateY = 0 };
        var listener = GestureService.GetGestureListener(AssociatedObject);
        listener.PinchStarted += OnPinchStarted;
        listener.PinchDelta += OnPinchDelta;
        listener.DragDelta += OnDragDelta;
        listener.DoubleTap += OnDoubleTap;
        base.OnAttached();
    }

    #region Pinch and Zoom Logic


    #region Event handlers

    /// <summary>
    /// Initializes the zooming operation
    /// </summary>
    private void OnPinchStarted(object sender,PinchStartedGestureEventArgs e)
    {
        _oldFinger1 = e.GetPosition(_imgZoom,0);
        _oldFinger2 = e.GetPosition(_imgZoom,1);
        _oldScaleFactor = 1;
    }

    /// <summary>
    /// Computes the scaling and translation to correctly zoom around your fingers.
    /// </summary>
    private void OnPinchDelta(object sender,PinchGestureEventArgs e)
    {
        var scaleFactor = e.DistanceRatio / _oldScaleFactor;
        if (!IsScaleValid(scaleFactor))
            return;

        var currentFinger1 = e.GetPosition(_imgZoom,0);
        var currentFinger2 = e.GetPosition(_imgZoom,1);

        var translationDelta = GetTranslationDelta(
            currentFinger1,currentFinger2,_oldFinger1,_oldFinger2,_imagePosition,scaleFactor);

        _oldFinger1 = currentFinger1;
        _oldFinger2 = currentFinger2;
        _oldScaleFactor = e.DistanceRatio;

        UpdateImageScale(scaleFactor);
        UpdateImagePosition(translationDelta);
    }

    /// <summary>
    /// Moves the image around following your finger.
    /// </summary>
    private void OnDragDelta(object sender,DragDeltaGestureEventArgs e)
    {
        var translationDelta = new Point(e.HorizontalChange,e.VerticalChange);

        if (IsDragValid(1,translationDelta))
            UpdateImagePosition(translationDelta);
    }

    /// <summary>
    /// Resets the image scaling and position
    /// </summary>
    private void OnDoubleTap(object sender,GestureEventArgs e)
    {
        ResetImagePosition();
    }

    #endregion

    #region Utils

    /// <summary>
    /// Computes the translation needed to keep the image centered between your fingers.
    /// </summary>
    private Point GetTranslationDelta(
        Point currentFinger1,Point currentFinger2,Point oldFinger1,Point oldFinger2,Point currentPosition,double scaleFactor)
    {
        var newPos1 = new Point(
         currentFinger1.X + (currentPosition.X - oldFinger1.X) * scaleFactor,currentFinger1.Y + (currentPosition.Y - oldFinger1.Y) * scaleFactor);

        var newPos2 = new Point(
         currentFinger2.X + (currentPosition.X - oldFinger2.X) * scaleFactor,currentFinger2.Y + (currentPosition.Y - oldFinger2.Y) * scaleFactor);

        var newPos = new Point(
            (newPos1.X + newPos2.X) / 2,(newPos1.Y + newPos2.Y) / 2);

        return new Point(
            newPos.X - currentPosition.X,newPos.Y - currentPosition.Y);
    }

    /// <summary>
    /// Updates the scaling factor by multiplying the delta.
    /// </summary>
    private void UpdateImageScale(double scaleFactor)
    {
        _totalImageScale *= scaleFactor;
        ApplyScale();
    }

    /// <summary>
    /// Applies the computed scale to the image control.
    /// </summary>
    private void ApplyScale()
    {
        ((CompositeTransform)_imgZoom.RenderTransform).ScaleX = _totalImageScale;
        ((CompositeTransform)_imgZoom.RenderTransform).ScaleY = _totalImageScale;
    }

    /// <summary>
    /// Updates the image position by applying the delta.
    /// Checks that the image does not leave empty space around its edges.
    /// </summary>
    private void UpdateImagePosition(Point delta)
    {
        var newPosition = new Point(_imagePosition.X + delta.X,_imagePosition.Y + delta.Y);

        if (newPosition.X > 0) newPosition.X = 0;
        if (newPosition.Y > 0) newPosition.Y = 0;

        if ((_imgZoom.ActualWidth * _totalImageScale) + newPosition.X < _imgZoom.ActualWidth)
            newPosition.X = _imgZoom.ActualWidth - (_imgZoom.ActualWidth * _totalImageScale);

        if ((_imgZoom.ActualHeight * _totalImageScale) + newPosition.Y < _imgZoom.ActualHeight)
            newPosition.Y = _imgZoom.ActualHeight - (_imgZoom.ActualHeight * _totalImageScale);

        _imagePosition = newPosition;

        ApplyPosition();
    }

    /// <summary>
    /// Applies the computed position to the image control.
    /// </summary>
    private void ApplyPosition()
    {
        ((CompositeTransform)_imgZoom.RenderTransform).TranslateX = _imagePosition.X;
        ((CompositeTransform)_imgZoom.RenderTransform).TranslateY = _imagePosition.Y;
    }

    /// <summary>
    /// Resets the zoom to its original scale and position
    /// </summary>
    private void ResetImagePosition()
    {
        _totalImageScale = 1;
        _imagePosition = new Point(0,0);
        ApplyScale();
        ApplyPosition();
    }

    /// <summary>
    /// Checks that dragging by the given amount won't result in empty space around the image
    /// </summary>
    private bool IsDragValid(double scaleDelta,Point translateDelta)
    {
        if (_imagePosition.X + translateDelta.X > 0 || _imagePosition.Y + translateDelta.Y > 0)
            return false;

        if ((_imgZoom.ActualWidth * _totalImageScale * scaleDelta) + (_imagePosition.X + translateDelta.X) < _imgZoom.ActualWidth)
            return false;

        if ((_imgZoom.ActualHeight * _totalImageScale * scaleDelta) + (_imagePosition.Y + translateDelta.Y) < _imgZoom.ActualHeight)
            return false;

        return true;
    }

    /// <summary>
    /// Tells if the scaling is inside the desired range
    /// </summary>
    private bool IsScaleValid(double scaleDelta)
    {
        return (_totalImageScale * scaleDelta >= 1) && (_totalImageScale * scaleDelta <= MaxImageZoom);
    }

    #endregion
    #endregion
}

并将行为附加到像这样的图像控件

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

 <Image Stretch="Uniform" Source="{Binding Image}" CacheMode="BitmapCache">
            <i:Interaction.Behaviors>
                <Behaviors:PinchZomBehavior/>
            </i:Interaction.Behaviors>
  </Image>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读