Windows Forms Applications
We could justifiably continue using the console as our primary output stream. Many introductory courses limit coverage to the console for the entire course so the focus can be directed to the code. However, to provide initial exposure to the topic, in this and the next chapter, we will use Windows forms for application development. The console window is a very useful and productive interface for systems administrators, database admins, and web developers. Alternatively, most students and almost all working professionals are more accustomed to working with GUI (graphical user interface) applications. GUI applications can be considerably more intuitive and easier to work with for non-technical users.
In this chapter and the next we will use Windows Forms to build two GUI applications. Windows Forms is the GUI technology introduced with the initial release of .NET in Feb2002. When .NET 3.0 was released in Nov2006 a new GUI technology was added named WPF (Windows Presentation Foundation). WPF is based on XAML (pronounced "Zamil") which was a new markup language developed by Microsoft. WPF is not covered in this course for a number of reasons including: Windows Forms is covered, time constraints, and adequate coverage of WPF is a bit complex for an introductory course.
Event Driven Programming
Graphical user interfaces operate on the event driven programming model. The application waits for an event to occur and it responds to (or handles) that event. Events are usually, but not always, initiated by the user. A common event initiated by a user is the "Click" event associated with a button. When the user clicks a button, s/he expects something to happen. The button responds to the click by generating a Click event. The Click event is handled by code in a method associated with the Click event for that button. The code that "makes something happen" is located in a method known as an event handler.
In VS, controls have a default event associated with them. For instance, the default event associated with a button control is the Click event. There are also many other events associated with controls that can be viewed in the Properties Window by clicking the lightning bolt (more on this below).
Building C# GUI Applications
There are a series of common steps that developers follow while developing C# GUI applications. The steps outlined below are not irrevocable, inflexible, or exhaustive. However, they represent a typical development pattern for a single-form application.
Before opening Visual Studio:
- List the requirements of the application
- Draw or construct a visual draft/sketch of the UI (user interface)
- Make a list of and name the controls on the form
- Make a list of and name the classes associated with the application
- Make a list of and name the fields/properties of the classes
- Make a list of and name the methods of the classes
In Visual Studio:
- Add the controls to the form (name the controls as added per the list above)
- Modify the control properties in the Properties Window per design specifications
- Refine the form design (control alignment, form appearance, etc.)
- Double-click on event generating controls to add event handlers to those controls
- Add the appropriate code to the event handlers
- Test and refine the code as required
The WindowsForms Application
We are now ready to begin developing a forms application. Select File | New | Project to add solution and project or R-Click the ITSE1331Solution-1 and add a new project as shown below. In the New Project dialog select Windows Forms Application instead of Console Application that we have selected previously. Change the name to WindowsForms unless you have used that name already. If so, use a name of your choosing and select OK.
The VS IDE is a sophisticated and powerful development platform. But, that sophistication and capability come at the price of complexity. The tool can seem a little overwhelming to new developers. In this chapter and the next, we will step through a few introductory topics one-by-one and purposefully, but gradually, increase proficiency with the IDE.
When the project window opens in VS, the first thing we want to do is to change the name of our form file from Form1.cs to a more useful and descriptive name such formMain.cs. Rename objects as early as you can. Renaming is more challenging after code has been written to reference the objects. Visual Studio will make some automatic name replacements when a name dependency is changed. However, it is better practice to get the names right early, before extensive coding.
In Solution Explorer, R-click on Form1.cs and select Rename. You should see the notification window below asking if you would like to change the name of references to the form. Renaming in the references in code and controls is called refactoring which is the act of 'changing form without changing function'. Select Yes. Notice that the filename changes in Solution Explorer. Click on the form to ensure the Properties window is showing properties for form-main. Note: to make the Properties Window show the properties for a particular control, click on the control. BE CAREFUL not to double-click on the control because that produces code that you may not want (more on this below). The name is also changed in the Properties window which normally appears below the Solution Explorer.
Make a few other changes in the Properties window. Change the BackColor of the form, the font size, and the text. I chose "192, 255, 255" for the BackColor, 12 for the font size, form Size to "500,800", and the Text property of "Windows Form Control Examples". Notice in the image below the changes applied to the form after making those settings (full size not shown). Recall in our discussion on object orientation that objects contain two things: functionality and data. All of the properties shown for the form represent data elements of the form object. The properties can be set at design time (like we just did) or at runtime using the dot . operator (a.k.a. member access operator) which we will do the in the code segments.
Our goal is to build an app that demonstrates the VS GUI building process and implements a few of the controls available in VS. The general requirements are listed below. More specific details are provided as we build the application. Note that unlike the preceding chapters, we do not work with Program.cs in this or the next chapter. Instead, we work with the class file that VS studio creates for the form. In our case, formMain.cs.
Application Requirements (see WindowsForms Finished State below)
- Two textboxes for name and hobby entry
- Three labels to display a greeting to the user using name and hobby
- One button to display greeting
- One groupbox containing three radio buttons to alter message type in a messagebox
- One groupbox containing three checkboxes to alter control background colors
- One button to display a messagebox and make changes based on radio and checkbox selections
- One button to change the form background to an image
Now we are ready to add a few controls (like buttons, labels, textboxes, etc.) to our form.
WindowsForms Finished State
Add the controls
See the image above labeled "WindowsForms Finished State". That is our goal (along with the required functionality). Visual studio makes it very convenient to build GUI applications quickly. Let's begin adding the controls to reach the application finished state as shown. There are two ways to add controls to a form: dragging the control from the toolbox or double-clicking on the control in the toolbox. The steps below follow the requirements listed above. Use the image "WindowsForms Finished State" as your visual guide.
Implementing the Design Requirements
- Add two textboxes to the form; size and place as shown. In the Properties Window, change the names of the textboxes to something meaningful such as textBoxYourName and textBoxHobby. There are a variety of opinions regarding control naming in VS. I prefer control name first followed by purpose but I will leave that to developer preference. Set the Text property of each box to the values shown.
- Add three labels and name appropriately. From this point, I will not repeat the advice to name appropriately. Set the Visible property of each to False which means that the labels will initially not be visible on the form. When do you think the labels will become visible?
- Add a "Display Greeting" button.
- Add a groupbox to the form and THEN add three radio buttons to the groupbox. By adding radio buttons to the same groupbox, the buttons behave as a group in which one and only one can be selected.
- Add a groupbox to the form and THEN add three checkboxes to the groupbox.
- Add a "Display MessageBox" button.
- Add a "Change Form Background" button.
We are done. Well, not quite. We have completed steps 1, 2, and 3 in the "In Visual Studio" list above. You should have the visual design of the application complete. Step four in the Visual Studio list is "Double-click on event generating controls to add event handlers to those controls". Of the 17 controls on the form, which ones do you think should generate events? That's right, our three buttons.
In VS, controls have default events associated with them. For instance, the default event associated with a button control is the Click event. When we double-click a control (DON'T do this yet), VS produces a starting point (a.k.a template or method stub) for that control's starting event. For example, I added a button to the form and double-clicked the button which produced the event handler template in form class file, formMain.cs which is where we will do our coding. The "sender" argument is the object that generated the event (button1 in this case). The "e" argument contains details about such as size, location, etc.
BE CAREFUL when adding event handlers to your application. Since it is so easy to add the handlers to a control by double-clicking, it is therefore so easy to unintentionally add an event handler to a control by mistake. I will demonstrate this undesirable consequence and the steps required to repair it.
Removing an Event Handler
Suppose, by mistake, I double-clicked the "labelHello"control on the form. The click event handler is generated in formMain.cs as shown. Since it was a mistake, I want to remove the event handler. However, notice that a reference was also generated and that reference must also be removed. The reference is located in the formMain.Designer.cs file. Normally, this file should NOT be modified. However, we need to remove the reference.
Let's see what happens when I remove the event handler but do not remove the reference. I just removed the event handler and clicked on the formMain.cs [Design] tab to open the design view and received the error below. This means that the reference in formMainDesigner.cs still exists but the event handler not longer exists in formMain.cs. The error is on line 92. From this window, I click the highlighted link to open formMainDesigner.cs.
In formMainDesigner.cs, I remove the error line below, Ctrl-s to save, and close the file. The form then appears as it should in design view. Note: this event handler and reference removal process can be a little quicker by double-clicking on message "92: this.labelHello.Click..." in the reference popup. That will open formMainDesigner.cs directly at the appropriate line.
Coding the Method Requirements
In addition to adding event handlers by double-clicking controls, event handlers can also be added via the Events View in the Properties Window. To see events associated with a control instead of the control properties, select the lightning bolt as shown. To code a particular event or navigate to an event that has been coded, simply click the event in the list.
Back to our three buttons. Let's code the "Display Greeting" button first. In design view, double-click to add the event handler. This is the first time we have seen formMain.cs, the "code behind" file for the form we designed. Line 13 specifies that this will be a partial class which means that the code for the class will be in multiple files (formMain.cs and formMainDesigner.cs). The ": Form" on line 13 means that formMain inherits from the superclass Form. By doing so, our form contains all of the fields, properties, and methods in the Form super class. Lines 15-18 contain the constructor for the form. There is a call to InitializeComponent() which is in the formMainDesigner.cs file. That is the method that contained the undesired reference we removed above.
On lines 22, 24, and 26 the Visible properties of the labels are set to true. On lines 23 and 25, the Text properties of two labels are set using values the user supplied in the textboxes. So, when the user clicks the Display Greeting button the labels will be shown with the appropriate greeting. You should test this functionality and address any errors.
We are now ready to code the Display MessageBox event handler. In design view, double-click the button to produce the template. On line 31, a DateTime object is created with the current date and time (Now). On lines 32 and 33 the string dateTimeMessage is created which will be added to the messagebox displayed.
Lines 35-52 contain if-else-if-else statements corresponding to the radio buttons. Radio buttons enforce "mutually exclusive" behavior which means that only one can be selected (much like an actual radio button tunes the radio to one station at a time). Line 35 checks to see if the raidoButtonWarning button is checked. If so, the static Show method of the MessageBox class is called with the appropriate settings. Inspect the arguments to ensure you understand their purposes. More coverage of the MessageBox class can be reviewed here.
Line 47 is a simple else (a.k.a trailing else) which will be executed if both of the prior two checks are false. Notice on the form that the "Information" icon is the default setting. Note the different icons produced when the MessageBoxes are displayed based on the radio button selected.
Lines 54-82 contain three if-else statements that are asking which, if any, of the checkboxes have been selected. Unlike radio buttons in which one and only one from the group can be selected, none or all of the checkboxes can be selected. What is being performed in each of the else statements in lines 54-82? What is the observable effect on the controls?
The last button we need to code is the Change Background button. Notice that this on line 86 refers to the current object which is the form.
In this chapter we reviewed the common steps to building a C# GUI application. When developing your applications, it is important to follow these steps or a similar process. The WindowsForms example demonstrated six different types of controls and the use of the Show() method of the MessageBox class. The event generator and event handler relationship was covered and demonstrated with three event generating buttons.
Testing the Application
Be sure to thoroughly test your application by altering the radio button and checkbox combinations. In the WindowsForms Test Output below, the Warning symbol is shown in the messagebox and all three checkboxes are selected thereby changing the targeted controls. In the Background Image Change example shown, we see the image in the form background.
WindowsForms Test Output
Background Image Change
In the next chapter we take a look at a few of the database concepts in a simple data connected C# application.