2010-10-22 15 views

cevap

5

360 maddelik yolunu gerekmez. Bunun yerine, sürüklerken, geçerli açıyı Math.Atan2(Y,X) kullanarak hesaplayın ve ardından dairenin üzerindeki noktayı oluşturun. Yeniden boyutlandırmak ve saklamak için center ve radius hesaplamaları yapmalı veya bunları MouseMove içinde hesaplamanız gerekir.

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); 
    } 
+1

Bu yöntemle işaretçiyi tam daire içinde sürükleyemiyorum (yalnızca dörtte biri). Bir şey mi eksik? – loraderon

+1

Sanırım merkeze göre açıyı hesaplamayı unuttum. Yukarıda güncellendi. – Justin

+0

Teşekkürler, şimdi beklendiği gibi çalışıyor! – loraderon

1

Noktalardan oluşan bir daire oluşturun ve ardından fare hareket ettiğinde (ve sürükleniyoruz) en yakın noktayı hesaplayın ve bu noktaya geçin.

CircularDrag.xaml

<UserControl x:Class="DraggingBoundaries.CircularDrag" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300" 
     SizeChanged="UserControl_SizeChanged" 
     MouseMove="UserControl_MouseMove" 
     MouseLeave="UserControl_MouseLeave" 
     MouseLeftButtonUp="UserControl_MouseLeftButtonUp" 
     > 
    <Grid Background="White"> 
     <Border 
      x:Name="Marker" 
      HorizontalAlignment="Left" 
      VerticalAlignment="Top" 
      Width="14" 
      Height="14" 
      Background="CornflowerBlue" 
      CornerRadius="2" 
      BorderThickness="1" 
      BorderBrush="DarkGray" 
      MouseLeftButtonDown="Marker_MouseLeftButtonDown" 
      /> 
    </Grid> 
</UserControl> 

CircularDrag.xaml.cs

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; 
     } 
    } 
} 
İlgili konular