Skip to content

Instantly share code, notes, and snippets.

@sachintha81
Last active October 21, 2021 02:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sachintha81/75f7d145a4128eead748a8fc5b104525 to your computer and use it in GitHub Desktop.
Save sachintha81/75f7d145a4128eead748a8fc5b104525 to your computer and use it in GitHub Desktop.
Drawing a Custom Control on C# WinForms
using System;
using System.Drawing;
using System.Windows.Forms;
namespace CustomControls
{
public class NodeControl : Control
{
private Graphics G = null;
public NodeControl()
{
this.DoubleBuffered = true;
}
/// <summary>
/// OnPaint event of the object.
/// </summary>
/// <param name=""e""></param>
protected override void OnPaint(PaintEventArgs e)
{
G = e.Graphics;
G.SetHighQuality();
DrawNode();
}
/// <summary>
/// On resize event of the object.
/// </summary>
/// <param name=""e""></param>
protected override void OnResize(EventArgs e)
{
Invalidate();
base.OnResize(e);
}
/// <summary>
/// Draws a node control.
/// </summary>
protected void DrawNode()
{
G.FillEllipse(new SolidBrush(NodeColor), new Rectangle(0, 0, DefSize, DefSize));
}
}
public static class GraphicsExtensions
{
public static void SetHighQuality(this Graphics g)
{
g.CompositingMode = CompositingMode.SourceOver;
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
}
public static void DrawCircle(this Graphics g, Pen pen, float centerX, float centerY, float radius)
{
g.DrawEllipse(pen, centerX - radius, centerY - radius, radius + radius, radius + radius);
}
public static void FillCircle(this Graphics g, Brush brush, float centerX, float centerY, float radius)
{
g.FillEllipse(brush, centerX - radius, centerY - radius, radius + radius, radius + radius);
}
}
}
@sachintha81
Copy link
Author

Create a custom control by deriving a class from System.Windows.Forms.Control.

After compiling, this control will automatically appear in the Toolbox of the Form designer and you can drag and drop it on a form surface.

It is important to understand that you should not draw by calling the OnPaint() method directly. Instead call the Invalidate() method of your control at each Time Tick (in case the control is redrawn repeatedly based on a timer). Windows decides when the control has to be redrawn and calls OnPaint() when necessary. (For instance when your control was hidden behind another form and now becomes visible.)

// At each tick:
electionDisplayControl1.Invalidate(); 

DoubleBuffered eliminates flicker. It is good to redraw the control when it is resized. You could anchor the control to the edges of your form in order to allow the user to resize it by resizing the form. It is a good idea to determine the size of the shapes relative to the size of the control. This creates an automatic zoom effect. You can easily adapt the coordinate system with

g.ScaleTransform(sx, sy);
g.TranslateTransform(dx, dy);

You can find a tutorial here:
http://www.c-sharpcorner.com/article/gdi-tutorial-for-beginners/
https://www.google.ch/search?q=gdi%2B%20tutorial

SetHighQuality is an extension methods. Please find it in the code as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment