Dragging an image in WPF

I'm trying to create a WPF application where I can drag an image around.

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.

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 a in order to have absolute positioning available.


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;
    }

}

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" .. >

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>

Hope this is of some use :)

链接地址: http://www.djcxy.com/p/43632.html

上一篇: Silverlight的? WPF? 或Windows窗体?

下一篇: 在WPF中拖动图像