Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 如何仅允许在循环路径中拖动?_Wpf - Fatal编程技术网

Wpf 如何仅允许在循环路径中拖动?

Wpf 如何仅允许在循环路径中拖动?,wpf,Wpf,拖动时是否可以限制拖动源仅在圆形路径的边界内移动?创建一个点圆,然后当鼠标移动(我们正在拖动)时,计算最近的点并捕捉到该点 CircularDrag.xaml CircularDrag.xaml.cs 使用系统; 使用System.Linq; 使用System.Collections.Generic; 使用System.Windows; 使用System.Windows.Controls; 使用System.Windows.Input; 名称空间拖动边界 { 公共部分类CircularDra

拖动时是否可以限制拖动源仅在圆形路径的边界内移动?

创建一个点圆,然后当鼠标移动(我们正在拖动)时,计算最近的点并捕捉到该点

CircularDrag.xaml


CircularDrag.xaml.cs

使用系统;
使用System.Linq;
使用System.Collections.Generic;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
名称空间拖动边界
{
公共部分类CircularDrag:UserControl
{
列出允许的车轮标记位置;
布尔标记;
公共通告
{
初始化组件();
}
私有void UserControl_SizeChanged(对象发送方,sizechangedventargs e)
{
var center=新点(e.NewSize.Width/2,e.NewSize.Height/2);
变量半径=(中心X
您不需要360点路径。相反,在拖动时,请使用
Math.Atan2(Y,X)
计算当前角度,然后在圆上生成点。您仍然需要在调整和存储它们时计算
中心
半径
,或者在MouseMove中计算它们

    private void UserControl_MouseMove(object sender, MouseEventArgs e)
    {
        if (!isDraggingMarker)
            return;
        var position = e.GetPosition(this);

        double angle = Math.Atan2(position.Y - center.Y, position.X - center.X);
        var closest = new Point(center.X + radius*Math.Cos(angle),
                                center.Y + radius*Math.Sin(angle));

        SetMarkerPosition(closest);
    }

我不能用这种方法将标记拖成一整圈(只有四分之一)。我遗漏了什么吗?我想我忘了计算相对于中心点的角度。以上更新。
using System;
using System.Linq;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace DraggingBoundaries
{
    public partial class CircularDrag : UserControl
    {
        List<Point> allowedWheelMarkerPositions;
        bool isDraggingMarker;

        public CircularDrag()
        {
            InitializeComponent();
        }

        private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            var center = new Point(e.NewSize.Width / 2, e.NewSize.Height / 2);

            var radius = (center.X < center.Y ? center.X : center.Y) - 15;

            allowedWheelMarkerPositions = CreateCirclePath(center, radius);
            SetMarkerPosition(allowedWheelMarkerPositions.First());
        }

        private List<Point> CreateCirclePath(Point center, double radius)
        {
            var result = new List<Point>();
            for (double angle = 0; angle <= 360; angle++)
            {
                double angleR = angle * (Math.PI / 180);
                double x = center.X + Math.Cos(angleR) * radius;
                double y = center.Y - Math.Sin(angleR) * radius;

                result.Add(new Point(x, y));
            }
            return result;
        }

        private void UserControl_MouseMove(object sender, MouseEventArgs e)
        {
            if (!isDraggingMarker)
                return;
            var position = e.GetPosition(this);

            var closest = allowedWheelMarkerPositions
                .OrderBy(p => GetDistance(position, p))
                .First();

            SetMarkerPosition(closest);
        }

        private void SetMarkerPosition(Point closest)
        {
            Marker.Margin = new Thickness(closest.X - Marker.Width / 2, closest.Y - Marker.Height / 2, 0, 0);
        }

        private double GetDistance(Point a, Point b)
        {
            var deltaX = a.X - b.X;
            var deltaY = a.Y - b.Y;

            return Math.Sqrt(Math.Pow(deltaX, 2) + Math.Pow(deltaY, 2));
        }

        private void Marker_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            isDraggingMarker = true;
        }

        private void UserControl_MouseLeave(object sender, MouseEventArgs e)
        {
            isDraggingMarker = false;
        }

        private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            isDraggingMarker = false;
        }
    }
}
    private void UserControl_MouseMove(object sender, MouseEventArgs e)
    {
        if (!isDraggingMarker)
            return;
        var position = e.GetPosition(this);

        double angle = Math.Atan2(position.Y - center.Y, position.X - center.X);
        var closest = new Point(center.X + radius*Math.Cos(angle),
                                center.Y + radius*Math.Sin(angle));

        SetMarkerPosition(closest);
    }