Files
aistudio-wpf-diagram/AIStudio.Wpf.ADiagram/Controls/SliderRotation.xaml.cs

140 lines
5.0 KiB
C#
Raw Normal View History

2021-07-23 09:42:22 +08:00
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.ADiagram.Controls
{
/// <summary>
/// SliderRotation.xaml 的交互逻辑
/// </summary>
public partial class SliderRotation : UserControl
{
#region
private Point cen; //中心点
private Point first; //初始状态位置
private Point second; //
private bool flag = false;
#endregion
#region
/// <summary>
/// 获取或设置Value数值
/// </summary>
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<object> valueArg =
new RoutedPropertyChangedEventArgs<object>(arg.OldValue, arg.NewValue, ValueChangedEvent);
sliderRotation.RaiseEvent(valueArg);
}
}
#region
public event RoutedPropertyChangedEventHandler<object> ValueChanged
{
add
{
this.AddHandler(ValueChangedEvent, value);
}
remove
{
this.RemoveHandler(ValueChangedEvent, value);
}
}
public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent(
"ValueChanged",
RoutingStrategy.Bubble,
typeof(RoutedPropertyChangedEventHandler<object>),
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); //计算出旋转角度
}
}
}
}