下面的类(PanImage)是此处Pan & Zoom Image的此线程的ZoomBorder类的改编。由于需要在图像上自定义绘画,因此无法使用边框。当用鼠标左键移动PanImage并仍然按下该按钮时,图像在两个位置之间来回跳跃。为什么这样做,如何解决此问题?
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
class PanImage : Image
{
public PanImage()
{
// add event-handler for changes of the SourceProperty of the Image class
DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(Image.SourceProperty, typeof(Image));
dpd?.AddValueChanged(this, delegate { Initialize(); });
}
private Point _origin;
private Point _start;
private TranslateTransform GetTranslateTransform()
{
return (TranslateTransform)((TransformGroup)RenderTransform)
.Children.First(tr => tr is TranslateTransform);
}
private ScaleTransform GetScaleTransform()
{
return (ScaleTransform)((TransformGroup)RenderTransform)
.Children.First(tr => tr is ScaleTransform);
}
public void Initialize()
{
RenderOptions.SetBitmapScalingMode(this, BitmapScalingMode.NearestNeighbor);
TransformGroup group = new TransformGroup();
ScaleTransform st = new ScaleTransform();
TranslateTransform tt = new TranslateTransform();
group.Children.Add(st);
group.Children.Add(tt);
RenderTransform = group;
RenderTransformOrigin = new Point(0.0, 0.0);
MouseLeftButtonDown += handle_MouseLeftButtonDown;
MouseLeftButtonUp += handle_MouseLeftButtonUp;
MouseMove += handle_MouseMove;
PreviewMouseRightButtonDown += handle_PreviewMouseRightButtonDown;
}
public void Reset()
{
// reset zoom
var st = GetScaleTransform();
st.ScaleX = 1.0;
st.ScaleY = 1.0;
// reset pan
var tt = GetTranslateTransform();
tt.X = 0.0;
tt.Y = 0.0;
}
private void handle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var tt = GetTranslateTransform();
_start = e.GetPosition(this);
_origin = new Point(tt.X, tt.Y);
Cursor = Cursors.Hand;
CaptureMouse();
}
private void handle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
ReleaseMouseCapture();
Cursor = Cursors.Arrow;
}
void handle_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
Reset();
}
private void handle_MouseMove(object sender, MouseEventArgs e)
{
if (IsMouseCaptured)
{
Vector v = _start - e.GetPosition(this);
var tt = GetTranslateTransform();
tt.X = _origin.X - v.X;
tt.Y = _origin.Y - v.Y;
}
}
}
答案 0 :(得分:0)
问题在于获取相对于要移动的元素的鼠标坐标。为了防止这种行为,请从父元素获取该职位:
private void handle_MouseMove(object sender, MouseEventArgs e) {
...
UIElement parentElem = VisualTreeHelper.GetParent(this) as UIElement;
Vector v = _start - e.GetPosition(parentElem);
...
}