Lesson 17 - Custom Controls In C# .NET
In the previous 4 lessons we worked with the basic controls provided by the .NET Framework itself. We completed this with Windows Forms Controls For The Fourth Time. But you may admit that these aren't limitless and simply might not cover all our needs every time. In today's C# tutorial, we're going to take a look at creating custom controls.
Let's consider that we need to make a progressbar that fills from right to left. The result will look something like this:
The ProgresBar
will be quite ordinary, except it'll only be
filled from right to left.
Adding a control into the project
In the Solution Explorer, we'll right-click the project and select Add New
Item. In the Add New Item dialog, we'll select the User Control and name it
MyProgressBar.cs
.
The control designer will open. We'll put a PictureBox
into the
control. In the Properties window, we'll set Width
of the user
control to 200
, and Height
to 25
. To the
PicureBox
, we'll set Location
to 0;0
,
Width
to 200
, Height
to 25
,
and Anchor
to Top
, Left
,
Bottom
, and Right
(basically all the sides). This
ensures that the user control will have the size 200x25, and the
PictureBox
(which we'll later use for rendering) will be resized
together with the whole control.
In the Solution Explorer, we'll click on MyProgressBar.cs
, and
then on Show Code. We'll add MaxValue
and Value
properties of the int
type. Next we'll create a private field
MinValue
, which we'll set to 0
. In the setters of the
properties, we'll call the ProgressBar_Paint()
method, passing
null
as the first and second parameters. This method doesn't exist
yet, we'll add it later.
private int _value = 0; public int Value { get { return _value; } set { _value = value; ProgressBar_Paint(null, null); } } private int minValue = 0; private int _maxValue = 100; public int maxValue { get { return _maxValue; } set { _maxValue = value; ProgressBar_Paint(null, null); } }
Next, we'll add Increment()
and Decrement()
methods, both with no parameters. We'll also overload these methods to accept
one parameter - Value
. Inside these methods, we'll either increment
or decrement the value of the progressbar. The methods' code will be as
follows:
public void Increment(int Value) { if (this.Value + Value > maxValue) throw new ArgumentOutOfRangeException("The max value exceeded"); this.Value += Value; } public void Increment() { if (this.Value + 1 > maxValue) throw new ArgumentOutOfRangeException("The max value exceeded"); this.Value += Value; } public void Decrement(int Value) { if (this.Value - Value < minValue) throw new ArgumentOutOfRangeException("The min value exceeded"); this.Value -= Value; } public void Decrement() { if (this.Value - 1 < minValue) throw new ArgumentOutOfRangeException("The min value exceeded"); this.Value -= 1; }
Inside each method, we verify that the value hasn't exceeded the maximum or
the minimum. If so, we throw an ArgumentOutOfRangeException
. If the
new value is valid, then we increment or decrement it.
Now we have to draw the progressbar, so let's move to the designer. In the
Properties window, we'll go to the events and add the
ProgressBar_Paint()
method to the Paint
event. Then
we'll go back to the code and add the following code into the
ProgressBar_Paint()
handler:
Graphics g = pictureBox1.CreateGraphics(); double fillLength = (double)this.Value * 100.0 / (double)maxValue / 100.0 * (double)this.Width; g.Clear(Color.Green); g.FillRectangle(Brushes.White, new Rectangle(0, 0, this.Width - int.Parse(fillLength.ToString()), 25));
On the first line, we declare the PictureBox
graphics which
we're going to be drawing on. Then we calculate the size of the filled part (in
pixels) using the rule of three, and then we draw it from the end.
Now let's move to the form. We'll add two buttons and one
NumericUpDown
at the bottom. We'll set the buttons' text to
+
and -
and we won't change anything for the
numericUpDown
.
Using the User Control
From the Toolbox
Note that a new group has been added to the Toolbox:
<project name> Components
. In this group there's a pointer
that is automatically added to every group, and we can see our progressbar. This
progressbar can now be treated like any other control. Let's add the new
progressbar into the form. Now there's a new type of control in our form.
From the Code
Let's move to the form code and create a private prog
field of
the MyProgressBar
type and initialize it right away. We'll set its
Location
to 12;43
in the constructor and add it to the
form.
MyProgressBar prog = new MyProgressBar(); public Form1() { InitializeComponent(); prog.Location = new Point(12, 43); Controls.Add(prog); }
We'll also add event handlers for both buttons that will increment and decrement the progressbar.
private void button1_Click(object sender, EventArgs e) { try { if (numericUpDown1.Value > 1) { prog.Increment(int.Parse(numericUpDown1.Value.ToString())); myProgressBar1.Increment(int.Parse(numericUpDown1.Value.ToString())); } else { prog.Increment(); myProgressBar1.Increment(); } } catch (ArgumentOutOfRangeException ex) { MessageBox.Show(ex.Message); } } private void button2_Click(object sender, EventArgs e) { try { if (numericUpDown1.Value > 1) { prog.Decrement(int.Parse(numericUpDown1.Value.ToString())); myProgressBar1.Decrement(int.Parse(numericUpDown1.Value.ToString())); } else { prog.Decrement(); myProgressBar1.Decrement(); } } catch (ArgumentOutOfRangeException ex) { MessageBox.Show(ex.Message); } }
Now try the program and see that it works and the progressbar is loading in the opposite direction.
Custom user controls are useful for specific things, creating our own
TextBox
would probably be a nonsense. It'd be the same as
reinventing the wheel. But if you really need a control for specific purposes,
it's definitely the way to go.
In this lesson, we learned how to create and implement our own controls. You have also completed the entire WinForms course and can continue with other courses in the C# .NET section.
Did you have a problem with anything? Download the sample application below and compare it with your project, you will find the error easily.
Download
By downloading the following file, you agree to the license terms
Downloaded 27x (425.84 kB)
Application includes source codes in language C#