問題情境:
上司對自己的關懷,稱現有的畫圈圈區域不太理想,需要有:
可拖拽移動圓的位置,
滾輪可以控制大小,
邊界也可以通過拖拽調整圓的長軸短軸調整大小。
原理描述:
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); }
