最近要做个winform的东西,要在里面集成一个类似Windows自带画图的标尺功能,还要能在图片上画矩形框。在网上找了好久也没找到写好的控件,无奈自己做了一个。
目前还有些bug,这里先做个分享。(Ps:很少做winform的东西,做的不好,轻喷。另外欢迎指点。)
由于最后要做的东西的背景是黑的,标尺就画成白的了,有需要的自己改吧。。
直接上代码
1 using Helper; 2 using System; 3 using System.Collections.Generic; 4 using System.Drawing; 5 using System.Windows.Forms; 6 7 namespace UserCtrl 8 { 9 public partial class RulerControl : UserControl 10 { 11 private double _monitorDPI = 100; 12 /// <summary> 13 /// 用于控制放大倍数 14 /// </summary> 15 private double _multiple = 1; 16 17 /// <summary> 18 /// 每多少个像素1格 19 /// </summary> 20 public double MonitorDPI 21 { 22 get 23 { 24 return _monitorDPI; 25 } 26 set 27 { 28 _monitorDPI = value; 29 } 30 } 31 /// <summary> 32 /// X轴偏移位置 33 /// </summary> 34 private float offSetX=0; 35 36 /// <summary> 37 /// Y轴偏移位置 38 /// </summary> 39 private float offSetY = 0; 40 41 /// <summary> 42 /// 开始位置X 43 /// </summary> 44 public double XStart 45 { 46 get; 47 set; 48 } 49 50 /// <summary> 51 /// 开始位置Y 52 /// </summary> 53 public double YStart 54 { 55 get; 56 set; 57 } 58 59 /// <summary> 60 /// 用户设置的原始图 61 /// </summary> 62 private Image _initImg = null; 63 64 65 66 /// <summary> 67 /// 图片 68 /// </summary> 69 public Image Image 70 { 71 get 72 { 73 return Pic.Image; 74 } 75 set 76 { 77 Pic.Image = value; 78 if (_initImg == null&&value!=null) 79 { 80 _initImg = PicHelper.GetNewPic(value, value.Width , value.Height ); 81 } 82 } 83 } 84 private Font font = new Font("宋体", 9); //刻度值显示字体 85 public RulerControl() 86 { 87 InitializeComponent(); 88 } 89 90 private void Pic_MouseWheel(object sender, MouseEventArgs e) 91 { 92 if (MouseButtons == MouseButtons.Left) 93 { 94 return; 95 } 96 Image img = Pic.Image; 97 if (img != null) 98 { 99 if (e.Delta >= 0) 100 { 101 if (_multiple * 2 > 4) 102 return; 103 _multiple *= 2; 104 } 105 else 106 { 107 if (Pic.Width < this.Width - 50) 108 return; 109 110 _multiple *= 0.5; 111 if (Pic.Width <= (this.Width - 50)) 112 { 113 XStart = 0; 114 YStart = 0; 115 } 116 } 117 DrawRect(); 118 AdapterDpi(); 119 ReDrawX(); 120 ReDrawY(); 121 } 122 } 123 124 private void RulerControl_Paint(object sender, PaintEventArgs e) 125 { 126 P1.Height = 50; 127 P1.Width = this.Width - 50; 128 P2.Height = this.Height - 50; 129 P2.Width = 50; 130 P1.Location = new Point(50, 0); 131 P2.Location = new Point(0, 50); 132 PContainer.Location = new Point(50, 50); 133 } 134 135 private void RulerControl_Resize(object sender, EventArgs e) 136 { 137 P1.Height = 50; 138 P1.Width = this.Width - 50; 139 P2.Height = this.Height - 50; 140 P2.Width = 50; 141 P1.Location = new Point(50, 0); 142 P2.Location = new Point(0, 50); 143 PContainer.Location = new Point(50, 50); 144 } 145 146 /// <summary> 147 /// 重画Y轴 148 /// </summary> 149 private void ReDrawY() 150 { 151 if (P2.BackgroundImage != null) 152 { 153 P2.BackgroundImage.Dispose(); 154 } 155 Bitmap bmpY = new Bitmap(P2.Width, P2.Height); 156 using (Graphics g = Graphics.FromImage(bmpY)) 157 { 158 int originLocation = bmpY.Width - 1; 159 int startY = (int)Math.Ceiling(YStart); 160 offSetY = (float)(MonitorDPI * _multiple * (startY - YStart)); 161 for (int i = startY; i <= Math.Ceiling(P2.Height / (MonitorDPI * _multiple) + YStart); i++) 162 { 163 float y = (float)(MonitorDPI * _multiple * (i - YStart)) + offSetY; 164 if (y >= 0) 165 { 166 PointF start = new PointF(originLocation, y); 167 PointF end = new PointF(originLocation - 3, y); 168 if (i % 5 == 0) 169 { 170 end = new PointF(originLocation - 6, y); 171 } 172 if (i % 10 == 0 && i != 0) 173 { 174 end = new PointF(originLocation - 12, y); 175 g.DrawString((i*MonitorDPI).ToString(), font, Brushes.White, new PointF(originLocation - 30, y - 5)); 176 } 177 g.DrawLine(Pens.White, start, end); 178 } 179 } 180 g.DrawLine(Pens.White, new PointF(originLocation, 0), new PointF(originLocation, bmpY.Height)); 181 P2.BackgroundImage = bmpY; 182 } 183 } 184 185 /// <summary> 186 /// 重画X轴 187 /// </summary> 188 private void ReDrawX() 189 { 190 if (P1.BackgroundImage != null) 191 { 192 P1.BackgroundImage.Dispose(); 193 } 194 Bitmap bmpX = new Bitmap(P1.Width, P1.Height); 195 using (Graphics g = Graphics.FromImage(bmpX)) 196 { 197 int originLocation = bmpX.Height - 1; 198 int startX = (int)Math.Ceiling(XStart); 199 offSetX = (float)(MonitorDPI * _multiple * (startX - XStart)); 200 for (int i = startX; i <= Math.Ceiling(P1.Width / (MonitorDPI * _multiple) + XStart); i++) 201 { 202 float x = (float)(MonitorDPI * _multiple * (i - XStart)) + offSetX; 203 if (x >= 0) 204 { 205 PointF start = new PointF(x, originLocation); 206 PointF end = new PointF(x, originLocation - 3); 207 if (i % 5 == 0) 208 { 209 end = new PointF(x, originLocation - 6); 210 } 211 if (i % 10 == 0 && i != 0) 212 { 213 end = new PointF(x, originLocation - 12); 214 g.DrawString((i*MonitorDPI).ToString(), font, Brushes.White, new PointF(x - 5, originLocation - 30)); 215 } 216 g.DrawLine(Pens.White, start, end); 217 } 218 } 219 g.DrawLine(Pens.White, new PointF(0, originLocation), new PointF(bmpX.Width, originLocation)); 220 P1.BackgroundImage = bmpX; 221 } 222 } 223 224 private void RulerControl_Load(object sender, EventArgs e) 225 { 226 P1.Height = 50; 227 P1.Width = this.Width - 50; 228 P2.Height = this.Height - 50; 229 P2.Width = 50; 230 P1.Location = new Point(50, 0); 231 P2.Location = new Point(0, 50); 232 PContainer.Location = new Point(50, 50); 233 ReDrawX(); 234 ReDrawY(); 235 Pic.MouseWheel += new MouseEventHandler(Pic_MouseWheel); 236 } 237 238 private void Pic_MouseEnter(object sender, EventArgs e) 239 { 240 Pic.Focus(); 241 } 242 243 private void PContainer_Scroll(object sender, ScrollEventArgs e) 244 { 245 if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll) 246 { 247 XStart = e.NewValue / (MonitorDPI * _multiple); 248 ReDrawX(); 249 } 250 else if (e.ScrollOrientation == ScrollOrientation.VerticalScroll) 251 { 252 YStart = e.NewValue / (MonitorDPI * _multiple); 253 ReDrawY(); 254 } 255 } 256 257 258 #region 画图片选定区域 259 bool MouseIsDown = false; 260 Rectangle MouseRect = Rectangle.Empty; 261 262 private void Pic_MouseDown(object sender, MouseEventArgs e) 263 { 264 MouseIsDown = true; 265 MouseRect = new Rectangle(e.X, e.Y, 0, 0); 266 Rectangle rec = new Rectangle(0, 0, 267 Math.Min(PContainer.ClientRectangle.Width, Pic.ClientRectangle.Width), 268 Math.Min(PContainer.ClientRectangle.Height, Pic.ClientRectangle.Height)); 269 Cursor.Clip = PContainer.RectangleToScreen(rec); 270 } 271 272 private void Pic_MouseMove(object sender, MouseEventArgs e) 273 { 274 if (MouseIsDown) 275 { 276 MouseRect.Width = e.X - MouseRect.Left; 277 MouseRect.Height = e.Y - MouseRect.Top; 278 if (MouseRect.Width > 0 && MouseRect.Height > 0) 279 { 280 Rectangle rect = Pic.RectangleToScreen(MouseRect); 281 ControlPaint.DrawReversibleFrame(rect, Color.White, FrameStyle.Dashed); 282 } 283 Pic.Refresh(); 284 } 285 286 } 287 288 private void Pic_MouseUp(object sender, MouseEventArgs e) 289 { 290 if (MouseIsDown) 291 { 292 MouseRect.Width = e.X - MouseRect.Left; 293 MouseRect.Height = e.Y - MouseRect.Top; 294 using (Graphics g = Graphics.FromImage(Pic.Image)) 295 { 296 g.DrawRectangle(new Pen(Color.Red), MouseRect); 297 } 298 Pic.Refresh(); 299 MouseIsDown = false; 300 if ((int)(MouseRect.Width * _multiple) > 0 && (int)(MouseRect.Height * _multiple) > 0) 301 { 302 list.Add(new Rectangle((int)(MouseRect.X / _multiple), 303 (int)(MouseRect.Y / _multiple), 304 (int)(MouseRect.Width / _multiple), 305 (int)(MouseRect.Height / _multiple) 306 )); 307 } 308 MouseRect = Rectangle.Empty; 309 Cursor.Clip = Rectangle.Empty; 310 } 311 } 312 #endregion 313 public List<Rectangle> list = new List<Rectangle>(); 314 315 private void Pic_DoubleClick(object sender, EventArgs e) 316 { 317 MouseEventArgs ev = e as MouseEventArgs; 318 List<Rectangle> temp = new List<Rectangle>(); 319 foreach (Rectangle item in list) 320 { 321 if (ev.X > item.X * _multiple && ev.X < item.X * _multiple + item.Width * _multiple && 322 ev.Y > item.Y * _multiple && ev.Y < item.Y * _multiple + item.Height * _multiple) 323 { 324 temp.Add(item); 325 } 326 } 327 foreach (Rectangle item in temp) 328 { 329 list.Remove(item); 330 } 331 332 DrawRect(); 333 } 334 335 /// <summary> 336 /// 把list中的框画到图片中 337 /// </summary> 338 private void DrawRect() 339 { 340 if (Pic.Image != _initImg) 341 Pic.Image.Dispose(); 342 Pic.Image = PicHelper.GetNewPic(_initImg, (int)(_initImg.Width * _multiple), (int)(_initImg.Height * _multiple)); 343 using (Graphics g = Graphics.FromImage(Image)) 344 { 345 foreach (Rectangle item in list) 346 { 347 g.DrawRectangle(new Pen(Color.Red), new Rectangle((int)(item.X * _multiple), 348 (int)(item.Y * _multiple), 349 (int)(item.Width * _multiple), 350 (int)(item.Height * _multiple) 351 )); 352 } 353 } 354 Pic.Refresh(); 355 } 356 357 private void AdapterDpi() 358 { 359 if (MonitorDPI * _multiple < 10) 360 { 361 MonitorDPI *= 2; 362 } 363 if (MonitorDPI * _multiple > 20) 364 { 365 MonitorDPI /= 2; 366 } 367 } 368 369 370 371 } 372 }
下载链接:http://download.csdn.net/download/p690075426/10142184