0

所以,我使用这种方法能够拖动图像:

在 WPF 中拖动图像

效果很好,但问题是它取决于画布,但它会在画布外绘制和拖动图像。这是我正在使用的扩展器,是否可以将自身限制为原始画布大小。

我想要做的是能够(在原始画布大小内)拖动图像以查看开始时不可见的部分。

扩展器

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

    }
4

1 回答 1

1

也许我在这里已经完成了,但我认为问题出在 Canvas 的 XAML 中,而不是在 Extender 中。

您是否在 Canvas 上设置了 ClipToBounds="True" 属性,因为它在 Canvas 对象上默认为 false。

<Canvas ClipToBounds="True" />
于 2012-04-04T03:43:07.870 回答