using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace AIStudio.Wpf.DiagramDesigner.Additionals.Controls { /// /// SliderRotation.xaml 的交互逻辑 /// public partial class SliderRotation : UserControl { #region 私有属性 private Point cen; //中心点 private Point first; //初始状态位置 private Point second; // private bool flag = false; #endregion #region 公有属性 /// /// 获取或设置Value数值 /// public double Value { get { return (double)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } public static readonly DependencyProperty ValueProperty = DependencyProperty.RegisterAttached( "Value", typeof(double), typeof(SliderRotation), new FrameworkPropertyMetadata((double)0, new PropertyChangedCallback(ValuePropertyChangedCallback))); #endregion public SliderRotation() { InitializeComponent(); } private static void ValuePropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs arg) { if (sender != null && sender is SliderRotation) { SliderRotation sliderRotation = sender as SliderRotation; RoutedPropertyChangedEventArgs valueArg = new RoutedPropertyChangedEventArgs(arg.OldValue, arg.NewValue, ValueChangedEvent); sliderRotation.RaiseEvent(valueArg); } } #region 事件路由 public event RoutedPropertyChangedEventHandler ValueChanged { add { this.AddHandler(ValueChangedEvent, value); } remove { this.RemoveHandler(ValueChangedEvent, value); } } public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent( "ValueChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler), typeof(SliderRotation)); #endregion private double GetAngle(Point point) //获取点到中心的角度 构造平面直角坐标系 计算点在该坐标系与y轴(正方向)的夹角 { const double M_PI = 3.1415926535897; if (point.X >= 0) { double hypotenuse = Math.Sqrt(point.X * point.X + point.Y * point.Y); return Math.Acos(point.Y / hypotenuse) * 180 / M_PI; } else { double hypotenuse = Math.Sqrt(point.X * point.X + point.Y * point.Y); return 360 - Math.Acos(point.Y / hypotenuse) * 180 / M_PI; } } private void ellipseBack_MouseDown(object sender, MouseButtonEventArgs e) { e.Handled = true; flag = true; cen = new Point(ellipseBack.Width / 2, ellipseBack.Height / 2); first = new Point(e.GetPosition(canvas).X - cen.X, cen.Y - e.GetPosition(canvas).Y); } private void ellipseBack_MouseUp(object sender, MouseButtonEventArgs e) { e.Handled = true; flag = false; } private void ellipseBack_MouseLeave(object sender, MouseEventArgs e) { e.Handled = true; flag = false; } private void ellipseBack_MouseMove(object sender, MouseEventArgs e) { e.Handled = true; //停止路由事件向上传递 if (flag) { second = new Point(e.GetPosition(canvas).X - cen.X, cen.Y - e.GetPosition(canvas).Y); //确定鼠标移动的点坐标(相对中心点的位置) if (second == new Point(0, 0)) { return; } double anglePointToPoint = GetAngle(second) - GetAngle(first); //得到鼠标移动之前与鼠标移动之后之间的夹角 first = second; if (Math.Abs(anglePointToPoint) > 90) //夹角如果大于90度忽略(大于90度的夹角有可能是计算错误得出来的) { anglePointToPoint = 0; } var angle = Value + anglePointToPoint; if (angle < 0) { angle += 360; } angle = angle % 360; Value = Math.Round(angle, 0); //计算出旋转角度 } } } }