本文介绍了在 WPF 中拖动图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个 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 中拖动图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 13:42