gpt4 book ai didi

windows-phone-7.1 - 捏缩放列表框中绑定(bind)的图像

转载 作者:行者123 更新时间:2023-12-03 23:40:02 25 4
gpt4 key购买 nike

我正在尝试在我的应用程序中实现捏缩放。我找到了这篇文章 (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>

关于windows-phone-7.1 - 捏缩放列表框中绑定(bind)的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9316302/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com