移动 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;
我在我制作的应用程序中做了类似的事情,这对我有用
我目前正在研究使用鼠标拖动 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;
我在我制作的应用程序中做了类似的事情,这对我有用