Get up to 80 % extra points for free! More info:

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:

Reversed progressbar - Form Applications in C# .NET Windows Forms

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.

Add New Item – User Control - Form Applications in C# .NET Windows Forms

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.

Increment and decrement buttons - Form Applications in C# .NET Windows Forms

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#

 

Previous article
Windows Forms Controls For The Fourth Time
All articles in this section
Form Applications in C# .NET Windows Forms
Article has been written for you by David Capka Hartinger
Avatar
User rating:
No one has rated this quite yet, be the first one!
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn university David learned IT at the Unicorn University - a prestigious college providing education on IT and economics.
Activities