How are Windows Forms Controls Created and Rendered Onto a Form?

In order to answer this question, I will use a project that I created in a previous demo. This demo is available here https://win-forms.com/2020/08/16/shapes-objects-and-lists-with-windows-forms/. You may clone the repository or download the code from here https://github.com/dwarwick/Shapes.

This post will cover how Windows Forms, or winforms for short, handles drawing controls on the forms. Examples of controls are text boxes, labels, list boxes, combo boxes, etc.

When you create a winforms project, a single windows form is created. The name of the form is Form1 by default, but you can, and should, rename it. You can also add as many additional forms to your project as you need.

Form Files

Each form consists of 3 files by default. For the purposes of this discussion, we will assume the name of the form is MainForm.

MainForm.cs is a file that normally contains all of the logic code behind the form. This file contains code that interacts with the controls on the form and the algorithms that make the program do what it is supposed to do.

MainForm.Designer.cs is a file that actually creates the controls, sets the initial property values of the controls, and renders the controls onto the form. This is what we will be diving into for this post.

MainForm.resx contains resources that are used by the form. We will not be discussing this today.

Identifying the 3 Files that Are a Form

We can browse to our solution folder to view these files on our hard drive as well. With MainForm.cs selected, you can view the path to the file in the properties window.

Finding File Location Using Properties Window

Lets open our File Explorer and navigate to the folder to view the form files.

File Explorer View of Project Files

In the File Explorer view, you can see 3 distinct files named MainForm.cs, MainForm.Designer.cs, and MainForm.resx. Close the File Explorer window and go back to Visual Studio.

Design View of Form

In the Solution Explorer, double click MainForm.cs. You will see the form open in Design View.

Form Open in Design View

This form was created by dragging and dropping each control onto the form and setting properties on each control using the properties window. See the Shapes Demo for more details on this.

Designer File Code

Open the MainForm.Designer.cs file to view the code that is used to create all of these controls and set the property values for each control.

Designer File Control Variables

In the image above, you can see that there are several variables that are declared. Each variable is named for one of the controls that are being used on our form. There are variables of type TextBox, Button, and Label. Each variable has of course been declared and given a Name such as txtBox_X. Each time a new control is dragged onto the form, Visual Studio creates a new variable in the designer file for you.

Now expand the plus sign next to the words Windows Form Designer generated code if you have not already expanded it.

You may see other plus signs that need to be expanded to view the full code in this file.

Plus Sign

The code in the image above simply declares a variable that represents a control. It does not actually create the control or define any properties.

InitializeComponent Method

Notice that there is a method named InitalizeComponent. This method is responsible for initializing all new controls and setting the properties on those controls.

As I stated before, when you drop a control on the form, a new variable is created for the control. At the same time, Visual Studio adds a new line of code to create a new instance of the control and sets some default property values for the control such as Name and TabIndex. And depending on where you drop the control and what size you make it, it sets the Location and Size properties as well.

Scroll down to the bottom of the InitializeComponent method.

Form Properties

Here you can see that our textboxes, labels, and button are actually added to the Controls Collection of the form. The controls are not actually associated with the form until they are part of the form Controls Collection. Next the Layout is performed and the form will be loaded with the controls positioned according to their assigned properties. This is the end of the InitializeComponent method.

The InitializeComponent method is called from the constructor of the MainForm class. Right click MainForm.cs and select View Code.

Initialize Component Method Called from Form Constructor

When we start debugging a form, the constructor runs before any other code in the MainForm class. The constructor runs the InitializeComponent method to load and position the controls onto the form.

Any changes that are made to a control on the form in design view are automatically updated in the designer file. If you change the color of a text box, or resize it, or set it to disabled, or make any other changes to it, those properties are updated automatically in the designer file.

Events

Events are also associated with their methods in the designer file. Have a look at the button properties in the designer file.

Button Click Event in Designer File

Here you can see that btnDraw Click event is associated with a method named btnDraw_Click. This line is added when you either double click a button in the form design view, or double click the click row for the button in the property window, or when you use the property window to browse to a button event method that has already been created in MainForm.cs.

If you enjoyed this post, please Like it so that you will be notified of new posts as I create them. I also have several other posts about Windows Forms available on my blog home page at https://win-forms.com.

If you have questions, comments, or suggestions, please leave a comment below.

Working with Buttons in Windows Forms

Buttons allow users to interact with a winforms application. The most popular event that is used for buttons is the click event.

An event is like a trigger for something to happen in the application. So it is like saying, “when this event happens, do this …”. So in this case, the event is that a button was clicked.

For our demonstration, we will create a simple winforms application that increments or decrements a counter (integer) that is displayed on a form.

A video of the demo is provided here, followed by step by step instructions.

Video of this Demo

Setup Your Environment

The first step is to launch Microsoft Visual Studio. If you do not have Visual Studio, see my post here, https://win-forms.com/2020/07/25/create-a-hello-world-winforms-application/ to learn how to download and install Microsoft Visual Studio and create your first Hello World application using Windows Forms.

Once Visual Studio is open, create a new project.

Create A new Project

Choose Windows Forms App (.Net Framework) C# as the template. Filter on C# Windows Desktop as shown in the image below.

Selecting Windows Forms type of Project

After you have selected the Windows Forms template, select Next. Name your project as ButtonDemo. I will be using .Net Framework 4.7.2 for this demo.

Name the Project

Click the Create Button. Once your project has been created, you will be presented with the blank Windows Forms template .

Blank Windows Forms Template

Rename our Form

Notice that our form gets the default name of Form1. It is good practice to name this to something more meaningful. When you start working on projects that contain several forms, you will have a hard time trying to keep track of each form and what they are used for if they are named Form1, Form2, Form3, etc.

Let’s name our form as MainForm to indicate that this is the form that will load when the application starts up. Right click Form1 in the Solution Explorer and click Rename. After you rename the form, press Enter.

Renaming Form1 to MainForm

Rename the Form Heading

Showing Form1 in Form Heading

Let’s change the heading for MainForm to display Main Form. Select the form by click on the form in design view. When the form is selected, you will see sizing handles on the form border and MainForm will be displayed at the top of the properties window.

Indications that Form1 is Selected

When MainForm is selected, you can find the Text property of the form in the properties window, as shown above, and change the text from Form1 to Main Form as shown below.

Form1 Text Property Now Displays Main Form

Add Controls to the Form

Open the Toolbox, which should be on the upper left edge of Visual Studio.

Location of the Toolbox in Visual Studio

The Toolbox contains all of the controls that are available in our chosen Framework, which is .Net Framework 4.7.2 in our case.

When the toolbox is open, drag 2 buttons and a label out onto the approximate middle of the form.

Label and Button in the Toolbox
Buttons and Label on the Form

Set Properties on the Controls

Now we need to change the Text Property of button1 and the Name Property of button1. Select button1 on the form by left clicking it 1 time. You will see sizing handles around the button when it is selected and you will see button1 at the top of the properties window.

button1 Selected and the Default Properties

With button1 selected, change the Text Property to -, the hyphen or minus symbol. Change the Name property to btnDecrement. btn means button. When we reference the button in code by the Name property, it will be easy for us to recognize that it is a button because the name begins with btn.

button1 Changed to Correct Properties

Now select button2 and make similar changes. Change the Tex Property to +, the plus symbol. Change the Name Property to btnIncrement.

btnIncrement Properties

Select the label1 control. Change the Name property to lblValue. Change the Text property to 0, the number zero. When the form first loads, we want it to display a default value of 0.

lblValue Properties
Completed Form Design

Click Events for the Buttons

An event is basically something that triggers some code to run. A click event “fires” when the user clicks the mouse on a control. a Key Down event fires when the user presses a key down. A Key Up event fires when the key is released. There are many other events that can be “Trapped“. If you want to execute some code when a particular event happens on a particular control, then you create an Event Listener. There are a few different ways to create an event listener. I will show you the 2 easiest ways to create button click event event listeners.

Create Button Click Events Method 1

Buttons are meant to accept clicks. The Click event is the default event for the button control. Double-Click btnDecrement on the form designer. You should see the MainForm code file open and you should see an empty click event method for btnDecrement.

Empty btnDecrement_Click Event Handler

Code that we want to execute when someone clicks btnDecrement belongs inside this method. What do we want to happen when someone clicks the decrement button? We want to decrement an integer by 1. To make it somewhat interesting, let’s add a condition that says our integer cannot go less than 0.

The first thing that we need is a variable to hold our integer value. We need to be able to access this variable from anywhere in our MainForm class. The reason for this is that we are going to be manipulating this variable from 2 different methods. One of the methods is the decrement button click event handler method. The other place is the increment button click event handler. I have not introduced you to passing variables from method to method yet, so we will make the integer variable accessible to the entire class for our demo.

In order for a variable to be accessible to the entire class, we need to declare it directly inside the class curly braces.

namespace ButtonDemo
{
    public partial class MainForm : Form
    {
        //This is where class level variables belong

        public MainForm()
        {
            InitializeComponent();
        }

        //You could also declare them here

        private void btnDecrement_Click(object sender, EventArgs e)
        {
            
        }

        //You could also declare them here
    }
}

I have added comments to indicate where class level variables normally go, but also to show alternate locations. Basically, as long as you do not declare them inside methods or constructors, you are usually OK.

public partial class MainForm : Form
    {
        //This is where class level variables belong
        int m_iValue;

        public MainForm()
        {
            InitializeComponent();
        }

        //You could also declare them here

        private void btnDecrement_Click(object sender, EventArgs e)
        {
            
        }
        //You could also declare them here
    }

We have declared an integer variable at the class level called m_iValue. The m means that it is a member of the class. This distinguishes it from local variables, which would be declared inside of methods. The i means that it is an integer. This way, even if I have hundreds or thousands of variables of various types in an application, I can instantly recognize that this variable is an integer. That is important because I need to know the type in order to know how to use it in various places in code.

Add Code to the Button Click Events

private void btnDecrement_Click(object sender, EventArgs e)
{
    if (m_iValue > 0)
    {
         m_iValue--;
    }
    lblValue.Text = m_iValue.ToString();
}

Every time someone clicks the btnDecrement button, the code in the btnDecrement click event handler will run. By default, the value of a newly declared integer is 0. So when we first run our program, the value of m_iValue will be 0. Since m_iValue is not greater than 0, m_iValue will not decrement. In order for the code inside the if statement to execute, the condition inside the parenthesis has to evaluate to true. Therefor, m_iValue must be greater than 0 in order for m_iValue to be decremented. m_iValue– means decrement the value of m_iValue by 1. Our if statement prevents m_iValue from going negative.

Next, lblValue.Text = m_iValue.ToString(); populates the Text property of the label on our form with the text version of the integer value. We must convert the integer value to a string. A string is a text data type as opposed to numbers. The Text property can only be assigned a text value. This is why we have to use ToString().

Go back to the form designer. We are going to use a different technique to create the click event for btnIncrement. Single click btnIncrement to select it. Now click the lightning bolt icon on the properties window.

btnIncrement Event Listing Arranged by Category

Notice in the image above that I have selected the lightning bolt. These are the events that are available for the button. Also notice that my view is by category instead of alphabetical (Green circle on the left). So in this view, the default event (Click) is at the top of the list. Double click the word Click or the empty space to the right of the word Click. A new empty event will be created in the MainForm class code file.

public partial class MainForm : Form
{
   //This is where class level variables belong
   int m_iValue;

   public MainForm()
   {
      InitializeComponent();
   }

   //You could also declare them here

   private void btnDecrement_Click(object sender, EventArgs e)
   {
      if (m_iValue > 0)
      {
         m_iValue--;
      }
      lblValue.Text = m_iValue.ToString();
   }

   private void btnIncrement_Click(object sender, EventArgs e)
   {

   }

   //You could also declare them here
}

Now we just need to add our code for the btnIncrement event handler. It will be similar to the decrement event handler. We will enforce a rule that the value cannot go above 10.

private void btnIncrement_Click(object sender, EventArgs e)
{
   if (m_iValue < 10)
   {
      m_iValue++;
   }
   lblValue.Text = m_iValue.ToString();
}

We check to ensure that the value of m_iValue is less than 10. If that condition is true, the code inside the if statement will run, which means the value of the variable will increment by 1. Then the Text property of the label will be set to the value of the m_iValue variable (converted to a string).

Lets Run Our Program

Run the Program

Click the green Start Arrow or press F5 on your keyboard to run our program. After a few seconds to a few minutes, depending on your computer, you should see your form pop up. If not, go back and double check your code against this tutorial. You should not have anything underlined in red in your code. If you do, those red underlines are where the problem is. You may have forgotten a semi-colon or a brace or a parenthesis, or the some code may not be in the proper case. It is all case sensitive.

Full Code

If you did not see any errors and your form loaded, try clicking the buttons to ensure that you see a value incrementing and decrementing.

Application Running

If you have any questions or comments, please comment below and I will get back to you.

Create a “Hello World” Winforms Application

The only tool that you need to create a Winforms application is Visual Studio. Some die-hard coders would probably tell you that they could do it with Windows Notepad, but I prefer to use Microsoft Visual Studio, and that is what I will use in all of my blog posts.

Visual Studio Community Edition is free, but their are also some paid editions available that offer additional features. Visual Studio can be downloaded from https://visualstudio.microsoft.com/vs/.

Installing Visual Studio

Navigate to https://visualstudio.microsoft.com/vs/ and download the Visual Studio edition that you want to work with. I use Visual Studio Community Edition for personal projects and that works well for me. At work, I use Professional Edition, but the only reason for that is because of the licensing requirements. I do not choose Professional because of the additional features. Community Edition has everything I need.

Visual Studio Download Page

By default, the installer should be downloaded to you Downloads folder. Launch the installer.

Choose Edition to Install

Click the Install button for the edition that you want to install. Select the .Net desktop development workload as shown below. Notice that I have removed some of the default options from the Optional components pane to the right, and I elected to install .Net Framework 4.61. The reason I chose this framework is because I use it a lot. You do not have to install .Net Framework 4.6.1. I will be using .Net Framework 4.7.2 for this demo.

Installation Choices

You may choose to install any or all additional workloads and components. At a minimum, install .Net desktop development and .Net Framework 4.6.1 to follow along with this demo. Once you have made your choices, click the Install button in the lower right corner. Depending on your system, this installation could take a little while. By the way, you can always re-run this installer to load additional workloads or components, or remove them.

Launch Visual Studio

If Visual Studio does not automatically launch after it finishes installing, you can find it in your Start Menu. Notice that the installer is also in the Start Menu.

Visual Studio in the Start Menu

Go ahead and launch Visual Studio.

Let’s Create Our Hello World Project

Create a New Project Button

As you can see under Get Started in the image above, you have several options for getting started on new or existing projects. One of the options is Create a New Project. Choose this option.

Choosing the C# Windows Desktop Forms App Template

Right away when you stare at all of the possible choices for the type of app to create, it may seem a little overwhelming. But there are 3 combo boxes at the top of the list that will help you narrow down the choices. Choose, as I have, C# for the programming language, Windows for the Platform type, and Desktop for the Project Type.

If you installed additional Workloads, your list may look different than mine. I have the correct project template circled in green in the image above. Select “Windows Forms App (.Net Framework)” and then click the Next button.

Naming Your Project

Type your Project Name as Hello World. Change the Framework to .Net Framework 4.7.2 if it does not default to 4.7.2. Once this is done, click the Create button to create our project.

Exploring our Project / Solution

Initial Project View

I don’t want to get into too much detail in this post because this post is just supposed to be a Hello World demo. But I do want to explain a little bit about what you are seeing as shown in the image above.

At the very top of the Solution Explorer, you see Solution ‘Hello World’ (1 of 1 project). The solution is the container for all of the related projects. Each project will compile to a single Executable (i.e. Hello World.exe) or DLL (i.e. Hello World.dll) when the solution is compiled. The default is to compile to an executable and that is what we are doing. Our solution currently contains 1 C# project called Hello World. The project also contains 1 form called Form1 and 1 class file called Program.cs.

Program.cs is the main entry point of the project. This means the when we start debugging the project, the code in Program.cs will execute first. There is code in Program.cs that will launch Form1.

App.config just contains some basic configuration info for the Hello World project. Properties are the project properties.

Let’s Rename Our Form1 to MainForm

I despise default values. Visual Studio named our form as Form1. If you had a project that contained several forms, it would be hard for any developer to keep track of the purpose of each form if they were named Form1, Form2, Form3, etc. So whenever you create a new form or button or text box, or whatever, please name it something meaningful to make it easier to remember what it is for.

Renaming Form1

Right click Form1 in the Solution Explorer and select Rename as shown in the image above. Name it MainForm with no spaces between Main and Form.

Form1 Renamed to MainForm

Displaying Hello World on Our Form

If the blank MainForm is not displayed in Design View as shown below, double click MainForm to open it in Design View.

Open MainForm in Design View if Not Already Open

Once the MainForm is open in Design View, click the background or border of the form to select it. You will see sizing handles on the right and bottom edge of the form when it is selected. You will also notice that MainForm is displayed at the top of the Properties window as shown in the image above.

When the form is selected, look at the Properties window and find the Text property. It should say Form1.

MainForm Text Property Incorrectly Says Form1

We need to change this to Hello World. Notice that in the top left border of our MainForm it says Form1. Type Hello World in place of Form1 and press Enter. Now the top left form border says Hello World.

Add a Label Control

On the left edge of the Visual Studio window, you should see the Toolbox.

ToolBox Normal Location

If you do not see it there, go to the View Menu and Select Toolbox. Once you see it attached to the edge of the Visual Studio window, click to open it. The Toolbox contains all of the available form controls such as labels, buttons, text boxes, etc.

When the Toolbox has opened, you can see that there are various categories of controls. If you expand All Windows Forms, you will be able to view all of the available controls.

Some of the Windows Forms Controls

The image shows some of the available controls. The list is pretty long.

Find the Label Control and drag it to the middle of the form somewhere and then drop it.

Label in the Toolbox
Label on the MainForm

Ok, the label is on the MainForm with a default text property of Label1. The label should also be selected by default. If you deselected it, please click the label on the form and confirm that Label1 is selected at the top of the properties window.

Label 1 Selected

When you have confirmed that Label1 is selected, change the Text property to Hello World! Now find the Font Property and open it by clicking the plus sign. Change the font size to 24 and position the label at the middle of the form by dragging it.

Setting Font Size

Let’s Run Our Application!

At the top of your Visual Studio window, you should see Green Arrow button labeled Start. If you do, click it to run your application. If not, go to the View Menu and select Toolbars > Standard to display the Standard Toolbar, or press F5 to run it if you don’t want to display the Standard Toolbar.

When the application finishes compiling, you should see your form pop up and display Hello World in the middle of your form.

Running Application

You can click the Minimize button in the upper right of the form to minimize the form, or the maximize button to maximize it. Of course you can close the form by clicking the X. Closing the form also stops the application from running. You can also stop the application from running by clicking the red stop button in Visual Studio.

Stopping the Application

Where Is Your Executable?

When you started the application, an Executable file was created which represents your application. In your Solution Explorer, select the top level solution node. Look in the properties window for the path to the solution file.

Path to the Solution File

Navigate to that folder.

Solution Folder

You can open your solution by double clicking the Hello World.sln file, but next time you open Visual Studio, this solution should show up as a recent solution.

Now navigate into the Hello World folder. This is the Hello World project folder.

Project Folder

Some of these files should seem somewhat familiar to you. You see these file in the Solution Explorer. Now open the bin (stands for binaries) folder. You will see 2 folders. One is Debug, the other is Release. We have only run our project in Debug mode, so the Debug folder is the only one that will have files right now. If we were to go back into Visual Studio and change Debug to Release and run it, then the Release folder would be populated. For now, navigate to the Debug folder.

Debug Folder Contents

There is your executable. Since this is a debug version of the executable, you should not distribute it. Any executables or dll’s that you want to distribute should be compiled in Release mode.

If you have any questions or comments, please leave a comment below.

Powered by WordPress.com.

Up ↑

%d bloggers like this: