GraphicalOverlayComponent.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. using System;
  2. using System.ComponentModel;
  3. using System.Drawing;
  4. using System.Windows.Forms;
  5. namespace HZH_Controls.Controls
  6. {
  7. [DefaultEvent("Paint")]
  8. public partial class GraphicalOverlayComponent : Component
  9. {
  10. public event EventHandler<PaintEventArgs> Paint;
  11. public GraphicalOverlayComponent()
  12. {
  13. InitializeComponent();
  14. }
  15. public GraphicalOverlayComponent(IContainer container)
  16. {
  17. container.Add(this);
  18. InitializeComponent();
  19. }
  20. private Control owner;
  21. [Browsable(true), Category("自定义属性"), Description("父控件"), Localizable(true)]
  22. public Control Owner
  23. {
  24. get { return owner; }
  25. set
  26. {
  27. // The owner form cannot be set to null.
  28. if (value == null)
  29. return;
  30. // The owner form can only be set once.
  31. if (owner != null)
  32. return;
  33. // Save the form for future reference.
  34. owner = value;
  35. // Handle the form's Resize event.
  36. owner.Resize += new EventHandler(Form_Resize);
  37. // Handle the Paint event for each of the controls in the form's hierarchy.
  38. ConnectPaintEventHandlers(owner);
  39. }
  40. }
  41. private void Form_Resize(object sender, EventArgs e)
  42. {
  43. owner.Invalidate(true);
  44. }
  45. private void ConnectPaintEventHandlers(Control control)
  46. {
  47. Type type = control.GetType();
  48. System.Reflection.PropertyInfo pi = type.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
  49. pi.SetValue(control, true, null);
  50. control.Paint -= new PaintEventHandler(Control_Paint);
  51. control.Paint += new PaintEventHandler(Control_Paint);
  52. control.ControlAdded -= new ControlEventHandler(Control_ControlAdded);
  53. control.ControlAdded += new ControlEventHandler(Control_ControlAdded);
  54. // Recurse the hierarchy.
  55. foreach (Control child in control.Controls)
  56. ConnectPaintEventHandlers(child);
  57. }
  58. private void Control_ControlAdded(object sender, ControlEventArgs e)
  59. {
  60. // Connect the paint event handler for the new control.
  61. ConnectPaintEventHandlers(e.Control);
  62. }
  63. private void Control_Paint(object sender, PaintEventArgs e)
  64. {
  65. if (e == null) return;
  66. // As each control on the form is repainted, this handler is called.
  67. Control control = sender as Control;
  68. Point location;
  69. // Determine the location of the control's client area relative to the form's client area.
  70. if (control == owner)
  71. // The form's client area is already form-relative.
  72. location = control.Location;
  73. else
  74. {
  75. // The control may be in a hierarchy, so convert to screen coordinates and then back to form coordinates.
  76. location = owner.PointToClient(control.Parent.PointToScreen(control.Location));
  77. // If the control has a border shift the location of the control's client area.
  78. location += new Size((control.Width - control.ClientSize.Width) / 2, (control.Height - control.ClientSize.Height) / 2);
  79. }
  80. // Translate the location so that we can use form-relative coordinates to draw on the control.
  81. if (control != owner)
  82. e.Graphics.TranslateTransform(-location.X, -location.Y);
  83. // Fire a paint event.
  84. OnPaint(sender, e);
  85. }
  86. private void OnPaint(object sender, PaintEventArgs e)
  87. {
  88. // Fire a paint event.
  89. // The paint event will be handled in Form1.graphicalOverlay1_Paint().
  90. if (Paint != null)
  91. Paint(sender, e);
  92. }
  93. }
  94. }
  95. namespace System.Windows.Forms
  96. {
  97. using System.Drawing;
  98. public static class Extensions
  99. {
  100. public static Rectangle Coordinates(this Control control)
  101. {
  102. // Extend System.Windows.Forms.Control to have a Coordinates property.
  103. // The Coordinates property contains the control's form-relative location.
  104. Rectangle coordinates;
  105. Form form = (Form)control.TopLevelControl;
  106. if (control == form)
  107. coordinates = form.ClientRectangle;
  108. else
  109. coordinates = form.RectangleToClient(control.Parent.RectangleToScreen(control.Bounds));
  110. return coordinates;
  111. }
  112. }
  113. }