- understanding the concept of custom control;
- understanding the differences between extended controls, composite controls and custom controls;
- creating a custom control and using it in a different project;
- drawing shapes and text on a windows forms control / form;
Full source code available, check the
NumericTextBoxControlSample
sample
How to: Inherit from Existing Windows Forms Controls: https://docs.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-inherit-from-existing-windows-forms-controls
Full source code available, check the
NumericTextBoxControlSample
sample
How to: Inherit from the UserControl Class: https://docs.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-inherit-from-the-usercontrol-class
The Graphics class provides methods for drawing objects to the display device.
Activity
Full source code available, check the
BarChartGraphicsSample
sample
-
Create a new project of the type "Class Library (.NET Framework)" (recommended) or "Windows Forms Control Library (.NET Framework)" with the name "ChartLibrary"
-
Add a new class
BarChartValue
, defined as follows:public class BarChartValue { public string Label { get; set; } public float Value { get; set; } public BarChartValue(string label, float value) { Label = label; Value = value; } }
-
Add a new "Custom Control (Windows Forms)" and name it
BarChartControl
-
Add the
Data
property in theBarChartControl
classprivate BarChartValue[] _data; public BarChartValue[] Data { get { return _data; } set { _data = value; } }
-
Modify the constructor of the
BarChartControl
class as follows:public BarChartControl() { InitializeComponent(); //redraws the chart if the control is resized ResizeRedraw = true; //default data Data = new[] { new BarChartValue("2015", 30), new BarChartValue("2016", 80), new BarChartValue("2017", 40) }; }
-
Handle the
Paint
event for theBarChartControl
as follows:private void BarChartControl_Paint(object sender, PaintEventArgs e) { //get the drawing context Graphics graphics = e.Graphics; //get the drawing area Rectangle clipRectangle = e.ClipRectangle; //determine the width of the bars var barWidth = clipRectangle.Width / Data.Length; //compute the maximum bar height var maxBarHeight = clipRectangle.Height * 0.9; //compute the scaling factor based on the maximum value that we want to represent var scalingFactor = maxBarHeight / Data.Max(x=>x.Value); Brush redBrush = new SolidBrush(Color.Red); for (int i = 0; i < Data.Length; i++) { var barHeight = Data[i].Value * scalingFactor; graphics.FillRectangle( redBrush, i * barWidth, (float) (clipRectangle.Height - barHeight), (float) (0.8 * barWidth), (float) barHeight); } }
-
Add a new Windows Forms project called "BarChartGraphicsSample"
-
Add a reference to the ClassLibrary project created earlier
-
From the ToolBox drag a 'BarChartControl' to the default form in the project
Assignments (for you to try) 🎮
- Display on each bar the
Label
andValue
properties of the correspondingBarChartValue
object.
Activity
Full source code available, check the
PieChartGraphicsSample
sample
-
Create a new project with the name “PieChartGraphicsSample”
-
Add a new class
PieChartCategory
, defined as follows:internal class PieChartCategory { public string Description { get; set; } public float Percentage { get; set; } public Color Color { get; set; } public PieChartCategory(string description, float percent, Color color) { Description = description; Percentage = percent; Color = color; } }
-
Add a new "Custom Control (Windows Forms)" and name it “PieChartControl”
-
Add the “Data “ property in the “PieChartControl” class
private PieChartCategory[] _data; public PieChartCategory[] Data { get { return _data; } set { if(_data == value) return; _data = value; //trigger the Paint event Invalidate(); } }
-
Modify the constructor of the “PieChartControl” class as follows:
public PieChartControl() { InitializeComponent(); //redraws if resized ResizeRedraw = true; //Default data Data = new[] { new PieChartCategory("Category 1", 20, Color.Red), new PieChartCategory("Category 2", 80, Color.Blue) }; }
-
Handle the “Paint” event for the “PieChartControl” as follows:
private void PieChartControl_Paint(object sender, PaintEventArgs e) { //width reserved for displaying the legend int legendWidth = 150; //get the drawing context Graphics graphics = e.Graphics; //get the drqwing area Rectangle clipRectangle = e.ClipRectangle; //compute the maximum radius float radius = Math.Min(clipRectangle.Height, clipRectangle.Width - legendWidth) / (float)2; //determine the center of the pie int xCenter = (clipRectangle.Width - legendWidth) / 2; int yCenter = clipRectangle.Height / 2; //determine the x and y coordinate of the pie float x = xCenter - radius; float y = yCenter - radius; //determine the width and the height float width = radius * 2; float height = radius * 2; //draw the pie sectors float percent1 = 0; float percent2 = 0; for (int i = 0; i < Data.Length; i++) { if (i >= 1) percent1 += Data[i - 1].Percentage; percent2 += Data[i].Percentage; float angle1 = percent1 / 100 * 360; float angle2 = percent2 / 100 * 360; Brush b = new SolidBrush(Data[i].Color); graphics.FillPie(b, x, y, width, height, angle1, angle2 - angle1); } //draw the pie contour Pen pen = new Pen(Color.Black); graphics.DrawEllipse(pen, x, y, width, height); //draw the chart legend float xpos = x + width + 20; float ypos = y; for (int i = 0; i < Data.Length; i++) { Brush b = new SolidBrush(Data[i].Color); graphics.FillRectangle(b, xpos, ypos, 30, 30); graphics.DrawRectangle(pen, xpos, ypos, 30, 30); Brush b2 = new SolidBrush(Color.Black); graphics.DrawString(Data[i].Description + ": " + Data[i].Percentage + "%", Font, b2, xpos + 35, ypos + 12); ypos += 35; } }
-
Add the “PieChartControl” to the “MainForm” (using the Toolbox)
-
Handle the “Load” event for the “MainForm” as follows:
private void MainForm_Load(object sender, System.EventArgs e) { PieChartCategory[] pieCategories = { new PieChartCategory("Gold", 20, Color.Red), new PieChartCategory("Stocks", 15, Color.Blue), new PieChartCategory("Bonds", 35, Color.Magenta), new PieChartCategory("ETFs", 15, Color.YellowGreen), new PieChartCategory("Options", (float) 7.5, Color.Tomato), new PieChartCategory("Cash", (float) 7.5, Color.Beige) }; pieChartControl1.Data = pieCategories; }
Activity
Full source code available, check the
ClockControlSample
andClockControlAppSample
samples
- Windows Forms Control Development Basics: https://docs.microsoft.com/en-us/dotnet/framework/winforms/controls/windows-forms-control-development-basics
- How to: Inherit from Existing Windows Forms Controls: https://docs.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-inherit-from-existing-windows-forms-controls
- How to: Inherit from the UserControl Class: https://docs.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-inherit-from-the-usercontrol-class