移动 UIElement 时,相对于 window 的 wpf 平移点会产生偏移

wpf translating point relative to the window results in a offset when moving the UIElement

我目前正在研究使用鼠标拖动 UIElement 的行为 class。我以前做过类似的东西,但我试图做到这一点,以便 UIElement 不依赖于某种类型的父级(除了 window)。

我遇到的问题是当我尝试将鼠标和 UIElement(AssociatedObject) 的坐标相对于 window 进行平移时,这导致了如下所示的偏移量。

尝试将偏移量添加到 "fix" 当前偏移量感觉像是作弊,这会使创建其余的运动行为变得更加复杂。

目前我正在使用内部包含多个元素的网格来测试 dragBehaviorComponentClass。 (我用浅蓝色填充网格作为指示器,尽管它与其他形状略有重叠)

我目前只尝试将 uiElement 的 0,0 位置附加到鼠标点,我尚未处理任何偏移以进一步改进拖动。

代码

public class MouseDragBehaviourComponent : Behavior<UIElement>
    {
        private TranslateTransform transform = new TranslateTransform();

        protected override void OnAttached()
        {
            AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown;
            AssociatedObject.PreviewMouseMove += AssociatedObject_PreviewMouseMove;
            AssociatedObject.MouseMove += AssociatedObject_MouseMove;
            AssociatedObject.MouseLeftButtonUp += AssociatedObject_MouseLeftButtonUp;
        }

        private void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            AssociatedObject.ReleaseMouseCapture();
        }
        private void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

        {
            Point currentPosition = AssociatedObject.TranslatePoint(new Point(0, 0), Window.GetWindow(AssociatedObject));
            AssociatedObject.RenderTransform = transform;
            AssociatedObject.CaptureMouse();
        }

        private void AssociatedObject_MouseMove(object sender, MouseEventArgs e)
        {
            if (AssociatedObject.IsMouseCaptured)
            {
                Point mousePosition = e.GetPosition(Window.GetWindow(AssociatedObject));
                transform.X = mousePosition.X;
                transform.Y = mousePosition.Y;
            }

        }

xaml

<Setter Property="Template">
            <Setter.Value>
                <ControlTemplate  TargetType="{x:Type local:UISet}">
                    <Border >
                        <e:Interaction.Behaviors>
                            <bt:MouseDragBehaviourComponent/>
                        </e:Interaction.Behaviors>
                        <Grid Background="LightBlue">
                            <StackPanel>
                                <Path MouseLeftButtonDown="geometry_MouseLeftButtonDown" Name="geometry" Fill="Blue">
                                <Path.Data>
                                    <CombinedGeometry GeometryCombineMode="Exclude">
                                        <CombinedGeometry.Geometry1>
                                    <RectangleGeometry RadiusX="2" RadiusY="2" Rect="-5,-50,100,50" />
                                        </CombinedGeometry.Geometry1>
                                        <CombinedGeometry.Geometry2>
                                            <RectangleGeometry RadiusX="2" RadiusY="2" Rect="5,-40,90,40" />
                                        </CombinedGeometry.Geometry2>
                                    </CombinedGeometry>
                                </Path.Data>
                            </Path>
                            <Path MouseLeftButtonDown="geometry_MouseLeftButtonDown" Fill="Red">
                                <Path.Data>
                                    <PathGeometry>
                                        <PathFigure StartPoint="0,0">
                                            <LineSegment Point="5,6"/>
                                            <LineSegment Point="10,0"/>
                                            <LineSegment Point="0,0"/>
                                        </PathFigure>
                                    </PathGeometry>
                                </Path.Data>
                            </Path>
                        </StackPanel>
                    </Grid>

您的代码设置方式:

transform.X = mousePosition.X;
transform.Y = mousePosition.Y;

获取鼠标在您移动的物体内部的位置。这会导致变换从鼠标移开,无论该距离是多少。要解决这个问题,您需要获取您正在移动的容器的鼠标位置,这将作为主要点,还需要获取光标在您移动的容器内的鼠标位置。这将作为偏移量。所以总而言之,代码看起来类似于:

Point mouseContainerLocation = Mouse.GetPosition(container);
Point mouseObjectLocation = Mouse.GetPosition(object);
transform.X = mouseContainerLocation.X - mouseObjectLocation.X;
transform.Y = mouseContainerLocation.Y - mouseObjectLocation.Y;

我在我制作的应用程序中做了类似的事情,这对我有用