问题情境:
上司对自己的关怀,称现有的画圈圈区域不太理想,需要有:
可拖拽移动圆的位置,
滚轮可以控制大小,
边界也可以通过拖拽调整圆的长轴短轴调整大小。
原理描述:
1.画形状容易实现;
2.调整大小通过整个窗体的鼠标move事件。来进行实时刷新显示;
3.拖拽移动位置用mousedown事件和MouseMove事件,可以实时监控光标位置;
4.滚轮控制用MouseWheel事件,MouseEventArgs的Delta属性可控制上下滚;
自己做了个简单demo实例:
public Form1()
{
InitializeComponent();
this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this_MouseWheel);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this_MouseMove);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this_MouseDown);
DrawRect.X = (this.Width - DrawRect.Width) / 2;
DrawRect.Y = (this.Height - DrawRect.Height) / 2;
log("zoom width height");
}
//矩形框坐标
private Rectangle DrawRect = new Rectangle(0, 0, 100, 100);
//鼠标按下时坐标
private Point MouseDownP = new Point();
//放大倍数
private int zoom = 0;
//鼠标移动矩形框次数,如果移动过矩形框则不从中心放大,以移动后的位置放大缩小,缩小为原大小,缩放数为0时,重置此数
private int MoveCount = 0;
private void this_MouseWheel(object sender, MouseEventArgs e)
{
Rectangle tmpRec = DrawRect;
int zmTemp = zoom;
int incTemp = 0;
if (e.Delta > 0)//上滚放大
{
if (zoom < 80)// 最大放大80倍
zoom++;
incTemp = -zoom;
}
else//下滚缩小
{
if (zoom > 0)
incTemp = zoom--;
if (zoom == 0) //放大倍数=0,不放大,鼠标拖动标记归0
MoveCount = 0;
}
//放大原理
//1、先获取放大倍数
//2、根据放大倍数,计算矩形框高度,高度=控件高度-倍数×2;
//3、根据高度,提取矩形宽度,宽度=高度×(控件宽度/控件高度),为保证矩形和原控件纵横比例,所以要乘以比例
//4、根据矩形框大小,和控件大小,计算矩形框在控件中的位置,即X,Y坐标
//1)如果没有拖动过矩形,则按默认中间位置取值,X=(控件宽度-矩形宽度)/2,Y=(控件高度-矩形高度)/2
//2)如果拖动过矩形框,则原X,Y坐标不变化
//5、根据得到的新矩形框的坐标和范围,判断是否超界,判断XY坐标
//滚轮放大事件
//矩形区域高度=控件高度-放大缩小倍数*2
double ratio = Math.Round(DrawRect.Width / (DrawRect.Height * 1.0) , 2);
DrawRect.Height = DrawRect.Height - incTemp * 2;
//按比例计算宽度
DrawRect.Width = (int)(Convert.ToSingle(DrawRect.Height) * ratio);
//if (MoveCount == 0)//没有拖动过,滚动滚轮才按中间放大缩小
//{
// DrawRect.X = (this.Width - DrawRect.Width) / 2;
// DrawRect.Y = (this.Height - DrawRect.Height) / 2;
//}
//===============判断是否超界===============
//如果Right超过控件宽度
if (DrawRect.Right > this.Width)
{
DrawRect = tmpRec;
zoom = zmTemp;
return;
}
//如果Bottom超过控件高度
if (DrawRect.Bottom > this.Height - 20)
{
DrawRect = tmpRec;
zoom = zmTemp;
return;
}
DrawImg();
}
int cursorFlag = 0;
private void this_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
int limitRadius = 5;
if (cursorFlag != 0)
{
switch (cursorFlag)
{
case 1://left
if (DrawRect.Width + DrawRect.X - e.X < limitRadius)
{
return;
}
DrawRect.Width += DrawRect.X - e.X;
DrawRect.X = e.X;
break;
case 2://right
if (e.X - DrawRect.X < limitRadius)
{
return;
}
DrawRect.Width = e.X - DrawRect.X;
break;
case 3://top
if (DrawRect.Height + DrawRect.Y - e.Y < limitRadius)
{
return;
}
DrawRect.Height += DrawRect.Y - e.Y;
DrawRect.Y = e.Y;
break;
case 4://bottom
if (e.Y - DrawRect.Y < limitRadius)
{
return;
}
DrawRect.Height = e.Y - DrawRect.Y;
break;
}
DrawImg();
}
else
{
if (DrawRect.Contains(MouseDownP))//判断鼠标按下的坐标是否在红框中,确定是否拖动的红框
{
//拖动鼠标位置,矩形框新X=矩形框原X+(当前鼠标X-按下时X),原X+偏移量
//Y轴一样变化
DrawRect.X = DrawRect.X + (e.X - MouseDownP.X); //.Location = ClienP;
DrawRect.Y = DrawRect.Y + (e.Y - MouseDownP.Y); // ClienP.Y;
//判断是否超过左上角
if (DrawRect.X < 0)
DrawRect.X = 0;
if (DrawRect.Y < 0)
DrawRect.Y = 0;
//判断是否超过右下角
if (DrawRect.X > (this.Width - DrawRect.Width - 1))
DrawRect.X = this.Width - DrawRect.Width - 1;
if (DrawRect.Y > (this.Height - DrawRect.Height - 1))
DrawRect.Y = this.Height - DrawRect.Height - 1;
//画图
DrawImg();
//计算完坐标系,鼠标按下坐标转换成当前鼠标坐标,以重新计算偏移
MouseDownP.X = e.X;
MouseDownP.Y = e.Y;
//拖动过鼠标,鼠标拖动标记累加
MoveCount++;
}
}
}
else
{
//如果光标在边界上,显示对应的光标形状
int boundary = 3;
if ((e.X <= DrawRect.X - 1 && e.X >= DrawRect.X - boundary)
&& e.Y >= DrawRect.Y && e.Y <= DrawRect.Y + DrawRect.Height)//left
{
cursorFlag = 1;
this.Cursor = Cursors.SizeWE;
}
else if ((e.X >= DrawRect.X + DrawRect.Width + 1 && e.X <= DrawRect.X + DrawRect.Width + boundary)
&& e.Y >= DrawRect.Y && e.Y <= DrawRect.Y + DrawRect.Height)//right
{
cursorFlag = 2;
this.Cursor = Cursors.SizeWE;
}
else if ((e.Y <= DrawRect.Y - 1 && e.Y >= DrawRect.Y - boundary)
&& e.X > DrawRect.X && e.X < DrawRect.X + DrawRect.Width)//top
{
cursorFlag = 3;
this.Cursor = Cursors.SizeNS;
}
else if ((e.Y >= DrawRect.Y + DrawRect.Height + 1 && e.Y <= DrawRect.Y + DrawRect.Height + boundary)
&& e.X > DrawRect.X && e.X < DrawRect.X + DrawRect.Width)//bottom
{
cursorFlag = 4;
this.Cursor = Cursors.SizeNS;
}
else
{
cursorFlag = 0;
this.Cursor = Cursors.Default;
}
}
}
private void this_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
MouseDownP = new Point(e.X, e.Y);
}
void DrawImg()
{
using (Graphics g = this.CreateGraphics())
{
//重绘背景 Ellipse Rectangle
g.FillRectangle(new SolidBrush(Color.LightGray), 0, 0, this.Width, this.Height);//达到去重效果
g.DrawString("滚轮放大,左键拖动矩形框" + zoom, new Font("黑体", 12f), new SolidBrush(Color.Green), 5, 5);
g.DrawString("放大" + zoom, new Font("黑体", 12f), new SolidBrush(Color.Red), 5, 20);
//重绘矩形
g.DrawEllipse(new Pen(Color.Red), DrawRect);
g.DrawRectangle(new Pen(Color.Red), DrawRect);
//日志
log(zoom.ToString("00") + " " + DrawRect.Width + " " + DrawRect.Height);
}
}
private void log(string text)
{
string path = Application.StartupPath + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
StreamWriter sw = File.AppendText(path);
sw.WriteLine(text);
sw.Flush();
sw.Close();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = this.CreateGraphics();
//重绘背景 Ellipse Rectangle
g.FillRectangle(new SolidBrush(Color.LightGray), 0, 0, this.Width, this.Height);//达到去重效果
g.DrawString("滚轮放大,左键拖动矩形框" + zoom, new Font("黑体", 12f), new SolidBrush(Color.Green), 5, 5);
g.DrawString("放大" + zoom, new Font("黑体", 12f), new SolidBrush(Color.Red), 5, 20);
//重绘矩形
DrawRect.X = (this.Width - DrawRect.Width) / 2;
DrawRect.Y = (this.Height - DrawRect.Height) / 2;
g.DrawEllipse(new Pen(Color.Red), DrawRect);
g.DrawRectangle(new Pen(Color.Red), DrawRect);
}