问题描述
我正在尝试创建一个 WPF 应用程序,我可以在其中拖动图像.
I'm trying to create a WPF application where I can drag an image around.
目前我在窗口中央放置了一个图像,我正在考虑使用三个鼠标事件 MouseDown、MouseMove 和 MouseUp 来计算拖动图像时的新位置.
Currently I have an image placed in the center of the window, and I'm thinking of using the three mouseevents MouseDown, MouseMove and MouseUp to calculate the new position when dragging the image.
关于如何做到这一点,还有其他好的想法吗?我对 WPF 完全陌生,所以我的心态仍然停留在 Windows 窗体世界中.
Are there any other good ideas on how to do this? I'm totally new to WPF so my mindset is still in the Windows Forms world.
据我所知,我需要使用为了有绝对定位可用.
As far as I can see I need to use ain order to have absolute positioning available.
推荐答案
好的,这里有一个附加属性behaviour",您可以使用它使任何位于画布上的元素可拖动:
ok, here's an attached property "behaviour" that you can use to make any element draggable provided it's on a canvas:
public class DraggableExtender : DependencyObject
{
// This is the dependency property we're exposing - we'll
// access this as DraggableExtender.CanDrag="true"/"false"
public static readonly DependencyProperty CanDragProperty =
DependencyProperty.RegisterAttached("CanDrag",
typeof(bool),
typeof(DraggableExtender),
new UIPropertyMetadata(false, OnChangeCanDragProperty));
// The expected static setter
public static void SetCanDrag(UIElement element, bool o)
{
element.SetValue(CanDragProperty, o);
}
// the expected static getter
public static bool GetCanDrag(UIElement element)
{
return (bool) element.GetValue(CanDragProperty);
}
// This is triggered when the CanDrag property is set. We'll
// simply check the element is a UI element and that it is
// within a canvas. If it is, we'll hook into the mouse events
private static void OnChangeCanDragProperty(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
UIElement element = d as UIElement;
if (element == null) return;
if (e.NewValue != e.OldValue)
{
if ((bool)e.NewValue)
{
element.PreviewMouseDown += element_PreviewMouseDown;
element.PreviewMouseUp += element_PreviewMouseUp;
element.PreviewMouseMove += element_PreviewMouseMove;
}
else
{
element.PreviewMouseDown -= element_PreviewMouseDown;
element.PreviewMouseUp -= element_PreviewMouseUp;
element.PreviewMouseMove -= element_PreviewMouseMove;
}
}
}
// Determine if we're presently dragging
private static bool _isDragging = false;
// The offset from the top, left of the item being dragged
// and the original mouse down
private static Point _offset;
// This is triggered when the mouse button is pressed
// on the element being hooked
static void element_PreviewMouseDown(object sender,
System.Windows.Input.MouseButtonEventArgs e)
{
// Ensure it's a framework element as we'll need to
// get access to the visual tree
FrameworkElement element = sender as FrameworkElement;
if (element == null) return;
// start dragging and get the offset of the mouse
// relative to the element
_isDragging = true;
_offset = e.GetPosition(element);
}
// This is triggered when the mouse is moved over the element
private static void element_PreviewMouseMove(object sender,
MouseEventArgs e)
{
// If we're not dragging, don't bother - also validate the element
if (!_isDragging) return;
FrameworkElement element = sender as FrameworkElement;
if (element == null) return;
Canvas canvas = element.Parent as Canvas;
if( canvas == null ) return;
// Get the position of the mouse relative to the canvas
Point mousePoint = e.GetPosition(canvas);
// Offset the mouse position by the original offset position
mousePoint.Offset(-_offset.X, -_offset.Y);
// Move the element on the canvas
element.SetValue(Canvas.LeftProperty, mousePoint.X);
element.SetValue(Canvas.TopProperty, mousePoint.Y);
}
// this is triggered when the mouse is released
private static void element_PreviewMouseUp(object sender,
MouseButtonEventArgs e)
{
_isDragging = false;
}
}
然后,您可以通过导入包含您的类的命名空间(如下所示:)在您的 XAML 中使用它
You can then use this in your XAML by importing the namespace your class is contained in (something like this:)
<Window x:Class="WPFFunWithDragging.Window1"
xmlns:local="clr-namespace:WPFFunWithDragging" .. >
然后你可以在元素上设置 DraggableExtender.CanDrag="true" 来拖动:
And then you can just set DraggableExtender.CanDrag="true" on elements to drag around:
<Canvas>
<Image Source="Garden.jpg"
Width="50"
Canvas.Left="10" Canvas.Top="10"
local:DraggableExtender.CanDrag="true"/>
</Canvas>
希望这有点用:)
这篇关于在 WPF 中拖动图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!