Files
aistudio-wpf-diagram/AIStudio.Wpf.BaseDiagram/Controls/SliderRotation.xaml.cs
2021-07-29 13:55:18 +08:00

140 lines
5.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.BaseDiagram.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); //计算出旋转角度
}
}
}
}