如何通过拖动来重置模拟时钟的时间';s处理C#
我对C#非常陌生,这里的目标是通过拖动模拟时钟的手柄来编辑它的时间。这个代码激励了我。我有三个简单的函数MouseDown、MouseMove和MouseUp,但我仍然无法使用拖动。有什么建议吗如何通过拖动来重置模拟时钟的时间';s处理C#,c#,C#,我对C#非常陌生,这里的目标是通过拖动模拟时钟的手柄来编辑它的时间。这个代码激励了我。我有三个简单的函数MouseDown、MouseMove和MouseUp,但我仍然无法使用拖动。有什么建议吗 public partial class Form1 : Form { #region Construct the clock public Point Start { get; set; } public Point End { get; set; } public Form1() {
public partial class Form1 : Form
{
#region Construct the clock
public Point Start { get; set; }
public Point End { get; set; }
public Form1()
{
InitializeComponent();
DoubleBuffered = true;
//Create the timer and start it
ClockTimer.Tick += ClockTimer_Tick;
ClockTimer.Enabled = true;
ClockTimer.Interval = 1;
ClockTimer.Start();
Start = p1;
End = p2;
}
#endregion
#region Update the clock
private void ClockTimer_Tick(object sender, EventArgs e)
{
Refresh();
}
private Timer ClockTimer = new Timer();
private Pen circle = new Pen(Color.Black, 2);
private Pen secondHandle = new Pen(Color.Red, 1);
private Pen minHandle = new Pen(Color.Black, 5);
private Pen hrHandle = new Pen(Color.Black, 5);
private Point p1;
private Point p2;
#endregion
#region On paint
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
//Clear the graphics to the back color of the control
pe.Graphics.Clear(BackColor);
//Draw the border of the clock
pe.Graphics.DrawEllipse(circle, 0, 0, 300, 300);
//Find the radius of the control by dividing the width by 2
float radius = (300 / 2);
//Find the origin of the circle by dividing the width and height of the control
PointF origin = new PointF(300 / 2, 300 / 2);
//Draw only if ShowMajorSegments is true;
if (ShowMajorSegments)
{
//Draw the Major segments for the clock
for (float i = 0f; i != 390f; i += 30f)
{
pe.Graphics.DrawLine(Pens.White, PointOnCircle(radius - 1, i, origin), PointOnCircle(radius - 21, i, origin));
}
}
//Draw only if ShowMinorSegments is true
if (ShowMinorSegments)
{
//Draw the minor segments for the control
for (float i = 0f; i != 366f; i += 6f)
{
pe.Graphics.DrawLine(Pens.Black, PointOnCircle(radius, i, origin), PointOnCircle(radius - 10, i, origin));
}
}
//Draw only if ShowSecondHand is true
if (ShowSecondhand)
//Draw the second hand
pe.Graphics.DrawLine(secondHandle, origin, PointOnCircle(radius, DateTime.Now.Second * 6f, origin));
//Draw only if ShowMinuteHand is true
if (ShowMinuteHand)
//Draw the minute hand
pe.Graphics.DrawLine(minHandle, origin, PointOnCircle(radius * 0.75f, DateTime.Now.Minute * 6f, origin));
minHandle.StartCap = LineCap.RoundAnchor;
minHandle.EndCap = LineCap.ArrowAnchor;
pe.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//Draw only if ShowHourHand is true
if (ShowHourHand)
//Draw the hour hand
pe.Graphics.DrawLine(hrHandle, origin, PointOnCircle(radius * 0.50f, DateTime.Now.Hour * 30f, origin));
hrHandle.StartCap = LineCap.RoundAnchor;
hrHandle.EndCap = LineCap.ArrowAnchor;
pe.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
}
#endregion
#region On size changed
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
//Make sure the control is square
if (Size.Height != Size.Width)
Size = new Size(Size.Width, Size.Width);
//Redraw the control
Refresh();
}
#endregion
#region Point on circle
private PointF PointOnCircle(float radius, float angleInDegrees, PointF origin)
{
//Find the x and y using the parametric equation for a circle
float x = (float)(radius * Math.Cos((angleInDegrees - 90f) * Math.PI / 180F)) + origin.X;
float y = (float)(radius * Math.Sin((angleInDegrees - 90f) * Math.PI / 180F)) + origin.Y;
return new PointF(x, y);
}
#endregion
#region Show Minor Segments
private bool showMinorSegments = true;
public bool ShowMinorSegments
{
get
{
return showMinorSegments;
}
set
{
showMinorSegments = value;
Refresh();
}
}
#endregion
#region Show Major Segments
private bool showMajorSegments = true;
public bool ShowMajorSegments
{
get
{
return showMajorSegments;
}
set
{
showMajorSegments = value;
Refresh();
}
}
#endregion
#region Show Second Hand
private bool showSecondHand = false;
public bool ShowSecondhand
{
get
{
return showSecondHand;
}
set
{
showSecondHand = value;
Refresh();
}
}
#endregion
#region Show Minute Hand
private bool showMinuteHand = true;
public bool ShowMinuteHand
{
get
{
return showMinuteHand;
}
set
{
showMinuteHand = value;
Refresh();
}
}
#endregion
#region Show Hour Hand
private bool showHourHand = true;
public bool ShowHourHand
{
get
{
return showHourHand;
}
set
{
showHourHand = value;
Refresh();
}
}
#endregion
public float slope
{
get
{
return (((float)p2.Y - (float)p1.Y) / ((float)p2.X - (float)p1.X));
}
}
public float YIntercept
{
get
{
return p1.Y - slope * p1.X;
}
}
public bool IsPointOnLine(Point p, int cushion)
{
float temp = (slope * p.X + YIntercept);
if (temp >= (p.Y - cushion) && temp <= (p.Y + cushion))
{
return true;
}
else
{
return false;
}
}
Point deltaStart;
Point deltaEnd;
bool dragging = false;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left && IsPointOnLine(e.Location, 5))
{
dragging = true;
deltaStart = new Point(p1.X - e.Location.X, p1.Y - e.Location.Y);
deltaEnd = new Point(p2.X - e.Location.X, p2.Y - e.Location.Y);
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (dragging && deltaStart != null && deltaEnd != null)
{
p1 = new Point(deltaStart.X + e.Location.X, deltaStart.Y + e.Location.Y);
p2 = new Point(deltaEnd.X + e.Location.X, deltaEnd.Y + e.Location.Y);
this.Refresh();
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
dragging = false;
}
公共部分类表单1:表单
{
#区域构造时钟
公共点开始{get;set;}
公共点结束{get;set;}
公共表格1()
{
初始化组件();
双缓冲=真;
//创建计时器并启动它
时钟计时器。滴答声+=时钟计时器滴答声;
ClockTimer.Enabled=true;
时钟计时器。间隔=1;
ClockTimer.Start();
开始=p1;
End=p2;
}
#端区
#区域更新时钟
私有无效时钟计时器(对象发送方,事件参数e)
{
刷新();
}
专用定时器ClockTimer=新定时器();
私人钢笔圈=新钢笔(颜色:黑色,2);
私用钢笔secondHandle=新钢笔(颜色:红色,1);
私人钢笔minHandle=新钢笔(颜色:黑色,5);
私人笔hrHandle=新笔(颜色:黑色,5);
专用点p1;
专用点p2;
#端区
#油漆上的区域
受保护的覆盖无效OnPaint(PaintEventArgs pe)
{
基础漆(pe);
//将图形清除为控件的背景色
pe。图形。清晰(背景色);
//画时钟的边框
pe.图形抽屉(圆形,0,0,300,300);
//通过将宽度除以2来查找控件的半径
浮动半径=(300/2);
//通过划分控件的宽度和高度找到圆的原点
点F原点=新点F(300/2300/2);
//仅当ShowMajorSegments为真时绘制;
如果(显示主要部分)
{
//绘制时钟的主要部分
用于(浮点数i=0f;i!=390f;i+=30f)
{
图形绘制线(钢笔,白色,点圆(半径-1,i,原点),点圆(半径-21,i,原点));
}
}
//仅当ShowMinorSegments为true时绘制
如果(显示片段)
{
//绘制控件的次要分段
用于(浮动i=0f;i!=366f;i+=6f)
{
绘图线(钢笔,黑色,点圆(半径,i,原点),点圆(半径-10,i,原点));
}
}
//仅当ShowSecondHand为真时绘制
如果(二手)
//画龙点睛
pe.Graphics.DrawLine(第二个手柄,原点,圆点(半径,DateTime.Now.Second*6f,原点));
//仅当ShowMinuteHand为真时绘制
if(ShowMinuteHand)
//画分针
pe.Graphics.DrawLine(minHandle,原点,PointOnCircle(半径*0.75f,DateTime.Now.Minute*6f,原点));
minHandle.StartCap=LineCap.RoundAnchor;
minHandle.EndCap=LineCap.arrow锚点;
pe.Graphics.InterpolationMode=System.Drawing.Drawing2D.InterpolationMode.High;
pe.Graphics.SmoothingMode=System.Drawing.Drawing2D.SmoothingMode.High Quality;
//仅当ShowHourHand为true时绘制
if(ShowHourHand)
//划时针
pe.图形.绘图线(hrHandle,原点,PointOnCircle(半径*0.50f,DateTime.Now.Hour*30f,原点));
hrHandle.StartCap=LineCap.RoundAnchor;
hrHandle.EndCap=LineCap.arrow锚点;
pe.Graphics.InterpolationMode=System.Drawing.Drawing2D.InterpolationMode.High;
pe.Graphics.SmoothingMode=System.Drawing.Drawing2D.SmoothingMode.High Quality;
}
#端区
#区域大小已更改
IzeChanged上的受保护覆盖无效(EventArgs e)
{
基地.OnSizeChanged(e);
//确保控件是方形的
if(Size.Height!=Size.Width)
尺寸=新尺寸(尺寸.宽度,尺寸.宽度);
//重新绘制控件
刷新();
}
#端区
#圆上的区域点
专用点F点OnCircle(浮动半径、浮动角度等级、点F原点)
{
//使用圆的参数方程求x和y
浮点数x=(浮点数)(半径*数学坐标((角度坐标-90f)*Math.PI/180F))+原点x;
浮动y=(浮动)(半径*数学Sin((角度基准-90f)*数学PI/180F))+原点y;
返回新的点f(x,y);
}
#端区
#区域显示小段
私有bool showMinorSegments=true;
公共图书馆展览
{
得到
{
归还展品;
}
设置
{
showMinorSegments=值;
刷新();
}
}
#端区
#区域显示主要细分市场
private bool showMajorSegments=真;
公共展览主要部分
{
得到
{
返回主要部分;
}
设置
{
showMajorSegments=值;
刷新();
}
}
#端区
#地区展示二手货
private bool showSecondHand=假;
公共场所展示二手货
{
得到
{
二手货;
}
设置
{
showSecond=价值;
刷新();
}
}
#端区
#区域显示分针
私有bool showMinuteHand=true;
公共场所展示
{
得到
{
返回显示分钟手;
}
设置
{
showMinuteHand=值;
刷新();
}
}
#端区
#区域显示时针
private bool showHourHand=true;
公共布尔ShowHourHand
{
得到
{
返回showHourHand;
}
设置
{
showHourHand=值;
刷新();
}
}
#端区
公众浮标斜坡
{
得到
{
返回(((float)p2.Y-(float)p1.Y)/((float)p2.X-(float)p1.X));
}
}
公共浮点数
{
得到
{
返回p1.Y-斜率*p1.X;
}
}
公共bool iSpoint Online(点p、点)
{
浮子温度=(斜率*p.X+YIntercept);
如果(temp>=(p.Y-缓冲)和&temp我给出了关于将X
,Y
坐标转换为基于圆的角度(度)的部分答案,其中0°
角度位于顶部
(向下滚动可获得紧凑的解决方案)
按照典型GUI坐标的方向,绝对0,0点位于左上角,正X值延伸至
(0;-1)
(-1; 0) (0; 0) (1; 0)
(0; 1)
var len = Math.Sqrt(X * X + Y * Y);
var xNorm = Math.Abs(X) / len;
var yNorm = Math.Abs(Y) / len;
var angleFromX = Math.Asin(xNorm) * 180.0 / Math.PI;
var angleFromY = Math.Asin(yNorm) * 180.0 / Math.PI;
var resultAngle = 0.0;
if (quarter_1)
{
resultAngle = 0 + angleFromX;
// same as
resultAngle = 90 - angleFromY;
}
if (quarter_2)
{
resultAngle = 90 + angleFromY;
// same as
resultAngle = 180 - angleFromX;
}
if (quarter_3)
{
resultAngle = 180 + angleFromX;
// same as
resultAngle = 270 - angleFromY;
}
if (quarter_4)
{
resultAngle = 270 + angleFromY;
// same as
resultAngle = 360 - angleFromX;
}
var angleFromYAxis = Math.Asin(Y / Math.Sqrt(X * X + Y * Y)) * 180.0 / Math.PI;
var resultAngle = 0.0;
if (X >= 0)
{
resultAngle = 90 + angleFromYAxis;
}
else
{
resultAngle = 270 - angleFromYAxis;
}