Click here to Skip to main content
15,886,110 members
Articles / Desktop Programming / Windows Forms

Draw Over WinForms Controls

Rate me:
Please Sign up or sign in to vote.
4.86/5 (27 votes)
26 Aug 2010CPOL4 min read 198.1K   12.1K   83   49
Use the Graphics object to draw almost anything on top of your form's controls
Form1

GraphicalOverlayDemo1.PNG GraphicalOverlayDemo2.PNG

Form2

GraphicalOverlayDemo3.PNG GraphicalOverlayDemo4.PNG GraphicalOverlayDemo5.PNG

Introduction

The GraphicalOverlay component draws on top of a form's controls. It is essentially like laying a piece of glass over the form and drawing on the glass. I use this component to draw lines between controls to help users make sense of complex relationships in the UI. I use it sparingly, but sometimes you just need a big red arrow that says: This affects that! When done correctly, the result can be quite elegant.

Using the Code

To use the GraphicalOverlay component, follow these steps:

  1. Copy the following two files to your project's directory: GraphicalOverlay.cs, GraphicalOverlay.designer.cs.
  2. Add GraphicalOverlay.cs to your project. Visual Studio will automatically include GraphicalOverlay.designer.cs.

    Compile the project. This will create a GraphicalOverlay component in the Visual Studio toolbox.

  3. Drag a GraphicalOverlay component from the toolbox onto your form's design surface. The component will automatically be named graphicalOverlay1.
  4. In your form, create a paint event handler for graphicalOverlay1 (graphicalOverlay1_Paint()).
  5. In your form's constructor, after the InitializeComponents(); line, add the following line:
    C#
    public Form1()
    {
        InitializeComponent();
    
        graphicalOverlay1.Owner = this;
    }
  6. In graphicalOverlay1_Paint() (see step 5), use e.Graphics to draw anything you like, using form-relative coordinates.
    C#
    private void graphicalOverlay1_Paint(object sender, PaintEventArgs e)
    {
        // This event will fire for the form and each control on the form.
        // The graphical overlay component will have already transformed the
        // graphics object to use the form's coordinate system, 
        // so no control-specific calculations are required.
    
        Rectangle rect = this.ClientRectangle;
        rect.Inflate(-10, -10);
    
        using(Pen pen = new Pen(Color.Red, 5))
            e.Graphics.DrawEllipse(pen, rect);
    
        using(Font font = new Font("Arial", 14))
            e.Graphics.DrawString("Now is the time.", 
                                  font, Brushes.Green, 60, 110);
    
        [...]
    }
  7. To draw control-relative graphics, use the Coordinates() method to get the control's form-relative coordinates. See the Form1.graphicalOverlay1_Paint() event handler in the demo code for an example.
    C#
    private void graphicalOverlay1_Paint(object sender, PaintEventArgs e)
    {
        [...]
        // To draw relative to a control, use the Coordinates method.
        using (Pen pen = new Pen(Color.Blue, 3))
            e.Graphics.DrawEllipse(pen, pictureBox1.Coordinates());
    }

Points of Interest

The component contains the following event handlers:

  • Form_Resize
  • Control_Paint

When the graphicalOverlay1.Owner property is set, the component connects its Form_Resize event handler to the owner form's Resize event. Then, the component attaches its Control_Paint event handler to the Paint event for each of the owner form's controls (including the owner form itself).

As each control is repainted, the component handles the Paint event, transforms the coordinates of the e.Graphics object, then fires its own Paint event which will be handled by the form's graphicalOverlay1_Paint event handler.

Because the e.Graphics object received by graphicalOverlay1_Paint() has been transformed to use the form's coordinate system, all of the drawing logic is form-relative. Just draw as if you're drawing within the form's client area.

This approach makes it difficult to draw relative to the controls, however. So, to make control-relative drawing easier, I have added an extension method called Coordinates() to the System.Windows.Forms.Control class. The Coordinates() method converts the control's location to form-relative coordinates. Just draw using Coordinates(control) instead of control.Location.

Because the graphical overlay can be drawn over all of the form's controls, redrawing it requires the entire form to be invalidated. Calling the component's Invalidate() method will invalidate the form and each of the form's controls.

Limitations

The component responds to each control's Paint event. The TextBox control does not fire a Paint event, so the component cannot draw over TextBox controls. It may be possible to use text box controls from a third party, but I have not tested any of them.

The component can only draw over a control's client area. Some controls include a border that is not part of their client area, so the component cannot draw over the border. One solution to this problem is to turn off the control's border and draw it using the component.

The component can only draw within a form's client area. It cannot draw over the form's title bar or borders, and it cannot draw between forms. To simulate drawing over the form's borders, you would need to turn off the form's border and draw it with the component--and re-implement all of the lost functionality.

Demos

I have included two demo forms to help you understand how to implement your own graphicalOverlay1_Paint event handler.

Form1.cs is the one with the picture with red and blue rings and green text.

Note: While the Form1 demo is running, resize the form a few times.

Form2.cs is the demo with the group boxes and radio buttons.

Note: In order to switch between the Form1 and Form2 demos, you must modify the Program.cs file to run Form1 or Form2. By default, the demo will run Form2.

In the Form2 demo, the code in graphicalOverlay1_Paint() contains a lot of hard coded values. I could have calculated these values, but it would only have made it harder to read the code. The hard coded values may not work exactly right if your UI culture is different from mine or if your fonts are configured differently from mine. The screenshots at the beginning of the article will show you what they are supposed to look like.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionMake it dynamic Pin
Member 1122391427-Nov-16 23:05
Member 1122391427-Nov-16 23:05 
QuestionDoesn't work for me ???? Pin
KeldSo9-Mar-16 8:22
KeldSo9-Mar-16 8:22 
QuestionSlight fix to Coordinates() Pin
axeslash2-Feb-16 4:37
axeslash2-Feb-16 4:37 
QuestionGraphic Overlay not creating in visual studio 2010 toolbox Pin
Member 1183186712-Jul-15 10:53
Member 1183186712-Jul-15 10:53 
QuestionHelp with a 'System.ObjectDisposedException' Pin
asiwel22-Jun-15 13:51
professionalasiwel22-Jun-15 13:51 
SuggestionAdd a option To Scroll Drawings Pin
nycos6215-Jan-15 3:12
nycos6215-Jan-15 3:12 
BugIssue with NumericUpDown Pin
Abysmaroth19-Aug-14 1:12
Abysmaroth19-Aug-14 1:12 
QuestionSwitching between Images ? Pin
zeleksonob3-Aug-14 4:54
zeleksonob3-Aug-14 4:54 
QuestionCreate GraphicalOverlay object dynamically Pin
Member 107769789-Jul-14 17:25
Member 107769789-Jul-14 17:25 
GeneralThanks! Pin
Member 1063400028-Feb-14 12:18
Member 1063400028-Feb-14 12:18 
QuestionDraw line over UserControls with this code Pin
M_Mogharrabi2-Dec-13 23:09
M_Mogharrabi2-Dec-13 23:09 
BugAlmost works Pin
qubit10125-Jan-13 3:28
qubit10125-Jan-13 3:28 
Questionit works also on control as owner Pin
Member 889513027-Apr-12 6:17
Member 889513027-Apr-12 6:17 
QuestionAm able to overlay on picture box, but i want to overlay text on AxVLC plugin control. Is it possible? Pin
sirigineediravikumar18-Mar-12 0:19
sirigineediravikumar18-Mar-12 0:19 
AnswerRe: Am able to overlay on picture box, but i want to overlay text on AxVLC plugin control. Is it possible? Pin
RocketteScientist20-Mar-12 7:56
RocketteScientist20-Mar-12 7:56 
GeneralMy vote of 5 Pin
p1nkzz24-Feb-12 0:29
p1nkzz24-Feb-12 0:29 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey21-Feb-12 23:54
professionalManoj Kumar Choubey21-Feb-12 23:54 
GeneralMy vote of 4 Pin
tokenian11-Oct-11 21:03
tokenian11-Oct-11 21:03 
QuestionWhat about scrolling stuff? Pin
Rikard Häggström4-Oct-11 11:47
Rikard Häggström4-Oct-11 11:47 
AnswerRe: What about scrolling stuff? Pin
RocketteScientist4-Oct-11 15:44
RocketteScientist4-Oct-11 15:44 
GeneralMy vote of 5 Pin
BoilerProg25-Jul-11 4:52
BoilerProg25-Jul-11 4:52 
QuestionDynamically Create GraphicalOverlay and Class the Draw Code Pin
BoilerProg22-Jul-11 5:37
BoilerProg22-Jul-11 5:37 
AnswerRe: Dynamically Create GraphicalOverlay and Class the Draw Code Pin
RocketteScientist22-Jul-11 21:01
RocketteScientist22-Jul-11 21:01 
GeneralRe: Dynamically Create GraphicalOverlay and Class the Draw Code Pin
BoilerProg25-Jul-11 4:46
BoilerProg25-Jul-11 4:46 
GeneralBroken drawing of custom control, with fix Pin
Andrew Haydn Grant29-Sep-10 11:48
Andrew Haydn Grant29-Sep-10 11:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.