Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Understanding Function Types and Child Forms in C# Programming - Prof. Mark G. Terwilliger, Study notes of Computer Science

The concept of functions in c# programming, focusing on two types: those that compute results and those that perform tasks. It also covers the creation and usage of child forms to display results. Examples of function headers, parameter lists, and function invocations, as well as the creation and communication with a child form.

Typology: Study notes

Pre 2010

Uploaded on 08/07/2009

koofers-user-o1k
koofers-user-o1k 🇺🇸

10 documents

1 / 25

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
6-2 Introduction to Computer Programming Using C#
A Note on “Good” Programming Practices
While the analogy is far from perfect, the development of a computer program can be likened to a
construction project. In terms of planning and style, our projects so far haven’t been all that different
from a child’s tree fort. We’ve settled for figuring out how to get the job done, without worrying too
much about some of the consequences.
In contrast, developing a larger programming project is more like building a house. Detailed
blueprints need to be created, and examined by inspectors to ensure that the structure will be safe and
built to accepted standards. Only then can the contractor proceed to the groundbreaking. Once
construction begins, care must be taken to coordinate the various phases to ensure that everything
comes together correctly. Even then, problems can arise. In fact, it’s almost a sure bet that some tasks
will conflict. It’s common to hear about plumbers boring holes through wiring, or electricians
drilling through plumbing, as they try to complete their jobs.
As the projects get larger, the need for careful planning and coordination becomes more critical.
Following his graduation, my brother went to work for an engineering company in Minneapolis,
Minnesota. One of his assignments was to develop plans for the installation of heating, ventilation,
and air conditioning ducts in the Mall of America. One day, he confided to me that one of the smaller
stores in the mall wasn’t going to have any heating ducts, after all, because the only way to reach the
store would be to bore through one of the major support beams, and that simply wasn’t going to be
done.
When developing a large application, programmers must spend a great deal of time planning. The
actual development shouldn’t begin in earnest until a clear picture of the solution has been produced.
Even then, programmers should be prepared to deal with unanticipated problems. Probably the best
way to do so is to follow good programming practices. This includes simple strategies, like using
well-chosen variable names. It also includes following accepted design and implementation
strategies that are far beyond the scope of this course. In this chapter, we’ll look at a common
component of applications that are developed for graphical environments - the dialog box - and see
how to design dialog boxes that fit cleanly into the finished program.
Subprograms
In chapter 3, the use of named constants was briefly discussed. As you will recall, when you use a
named constant, such as PI, you can use that name in place of the corresponding constant value,
3.14159265. Named constants provide two major benefits - they make the programmer's job easier,
and also make the resulting program easier to understand.
In a similar way, subprograms provide a mechanism for giving a name to a set of program
instructions. This allows the programmer to refer to the set of instructions by that single name, rather
than having to replicate the corresponding instructions. To use a human-oriented analogy, this is like
letting the programmer say "Open the door" instead of having to explicitly list all of the steps
required to open the door - put your hand on the door knob, turn the knob until it releases the latch,
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19

Partial preview of the text

Download Understanding Function Types and Child Forms in C# Programming - Prof. Mark G. Terwilliger and more Study notes Computer Science in PDF only on Docsity!

6-2 Introduction to Computer Programming Using C#

A Note on “Good” Programming Practices

While the analogy is far from perfect, the development of a computer program can be likened to a construction project. In terms of planning and style, our projects so far haven’t been all that different from a child’s tree fort. We’ve settled for figuring out how to get the job done, without worrying too much about some of the consequences.

In contrast, developing a larger programming project is more like building a house. Detailed blueprints need to be created, and examined by inspectors to ensure that the structure will be safe and built to accepted standards. Only then can the contractor proceed to the groundbreaking. Once construction begins, care must be taken to coordinate the various phases to ensure that everything comes together correctly. Even then, problems can arise. In fact, it’s almost a sure bet that some tasks will conflict. It’s common to hear about plumbers boring holes through wiring, or electricians drilling through plumbing, as they try to complete their jobs.

As the projects get larger, the need for careful planning and coordination becomes more critical. Following his graduation, my brother went to work for an engineering company in Minneapolis, Minnesota. One of his assignments was to develop plans for the installation of heating, ventilation, and air conditioning ducts in the Mall of America. One day, he confided to me that one of the smaller stores in the mall wasn’t going to have any heating ducts, after all, because the only way to reach the store would be to bore through one of the major support beams, and that simply wasn’t going to be done.

When developing a large application, programmers must spend a great deal of time planning. The actual development shouldn’t begin in earnest until a clear picture of the solution has been produced. Even then, programmers should be prepared to deal with unanticipated problems. Probably the best way to do so is to follow good programming practices. This includes simple strategies, like using well-chosen variable names. It also includes following accepted design and implementation strategies that are far beyond the scope of this course. In this chapter, we’ll look at a common component of applications that are developed for graphical environments - the dialog box - and see how to design dialog boxes that fit cleanly into the finished program.

Subprograms

In chapter 3, the use of named constants was briefly discussed. As you will recall, when you use a named constant, such as PI , you can use that name in place of the corresponding constant value, 3.14159265. Named constants provide two major benefits - they make the programmer's job easier, and also make the resulting program easier to understand.

In a similar way, subprograms provide a mechanism for giving a name to a set of program instructions. This allows the programmer to refer to the set of instructions by that single name, rather than having to replicate the corresponding instructions. To use a human-oriented analogy, this is like letting the programmer say "Open the door" instead of having to explicitly list all of the steps required to open the door - put your hand on the door knob, turn the knob until it releases the latch,

Chapter 6: Subprograms and Dialog Boxes 6-

and then pull, or push, the door. Further, by using customizing data, in the form of parameters, you can have a generic set of instructions for opening a door that can be customized, at will, to open first the living room door, then the closet door, and then the bedroom door.

The function is used in C# to provide subprogram support. We already saw how several arithmetic operations are included in the math library. For example, the square root of a number can be computed by the standard built-in function, Math.Sqrt(). Similarly, the various event handlers you've been using in C# programs are, in fact, function subprograms, as are many other operations, such as Close() , Focus() , Convert.ToInt32() , Convert.ToDouble() , and String.Format().

If you think about the usage of these various functions, you may realize that they can be separated into two basic types - functions that compute a result, like the square root function, and functions that perform some task, like the close and clear functions. In C#, the distinction between these two types is conveyed syntactically through a “return type.” a task-oriented functions is often given a return type of void , while a computationally oriented function has a specific data type assigned to it.

A typical “header” for a C# function looks like this:

type fname (parameter list);

In this header, “type” refers to the return type of the function. As noted before, void is generally used for a task-oriented function, while a function that computes a result, say, of type double , would use the return type of double.

fname is the name of the function. As we’ve seen in the examples so far, the convention among C# programmers is to use an upper-case letter to start the function name.

The parameter list is a mechanism to provide information to the function that it will need to carry out its task. For example, if you’re going to compute a square root, you need to provide the value whose square root is desired; the parameter list is used to convey that information. We’ll see more about this later.

Within a function, the return operation can be used to tell the computer that the function’s work is done, and that control should be returned to the point from which the function was initiated. If the function is computing a result, the value of that result is appended to the return statement:

return answer;

If, however, the function has a return type of void, then the return statement is simply written as:

return;

Finally, if a C# function is defined within the body of a class (for example, within the definition of a form), then you need to decide if that function is to be private, or usable only from within other functions that are a part of the class, or public, or usable from outside of the class definition. The

Chapter 6: Subprograms and Dialog Boxes 6-

An Example Function for Computing a Result

As a first example function, suppose a credit card company uses the following rule to compute a customer’s minimum monthly payment:

If the card’s balance is greater than $100, the minimum monthly payment will be 5% of the balance, rounded to the nearest whole dollar. If the balance is between $5 and $100, the minimum payment will be $5.00. If the balance is less that $5, then the minimum payment will be the actual balance.

A programmer might choose to create a subprogram that implements this rule. Since the amount of the payment is based on the balance, the subprogram will need this value provided as a parameter. In most cases, the result will be a whole number, so you might be tempted to define the function’s result type to be int. However, in one case - when the balance is less than $5.00, the payment will be set equal to the balance, which may not be a whole number, so the correct result type would be double.

The actual implementation of the function is given below:

// Compute the minimum monthly payment on a credit card, // given the current account balance.

double MinPayment (double balance) { if (balance < 5) return balance; if (balance < 100) return 5; return Math.Round (0.05 * balance); }

A typical invocation of this function in a program might be:

double Payment = MinPayment (accountBalance);

An Example Subprogram for Performing a Task

As noted before, functions with the return type of void are usually associated with some type of task, and may not generate any results at all, although they might also generate multiple results. Many of the task-oriented functions you’ve used in your applications so far - Close() , Clear() , and Focus() , for example, have no parameters. Compare these examples to the ShowDialog() function, which uses 4 value parameters.

6-6 Introduction to Computer Programming Using C#

To illustrate a task-oriented function, we’ll use a problem that’s become a time-honored staple of computer science classes everywhere. An automated change dispenser needs to dispense the correct number of pennies, nickels, dimes, and quarters to a customer, given the total amount of change required. Naturally, the machine should dispense the minimum number of coins possible. For example, 36 cents in change could consist of 36 pennies, or 7 nickels and a penny, or maybe 3 dimes, a nickel, and a penny, among other combinations, but the smallest number of coins is obtained with a quarter, a dime, and a penny.

A strategy for determining the minimum number of coins consists of first dispensing as many quarters as possible, then as many dimes as possible, then as many nickels as possible, and finally as many pennies as required to reach the desired amount. While this could be implemented using a series of if statements, a simpler solution just uses integer division. To illustrate, suppose the desired amount of change was 72 cents. Since 25 divided into 72 yields 2, with a remainder of 22, the change machine should dispense 2 quarters. Now we divide 10 into the remainder, 22. This gives us a quotient of 2, with a remainder of 2. Therefore, we should dispense two dimes. Since 5 divided into the remainder 2 yields a quotient of zero, no nickels are required. However, the remainder, 2, represents the number of pennies required.

If we choose to implement this change-making algorithm as a function subprogram, we’ll need 5 parameters, representing the amount of change needed, along with the number of pennies, nickels, dimes, and quarters to be dispensed. The first parameter, representing the amount of change needed, will be a value parameter, since it is simply providing data to the subprogram. The remaining parameters will be output parameters, since they need to specify the number of coins of each coin type that will be required.

The complete implementation of the change-making function follows:

void makeChange (int amount, out int pennies, out int nickels, out int dimes, out int quarters) { quarters = amount / 25; { How many quarters? } amount = amount % 25; { How much more change? } dimes = amount / 10; { How many dimes? } amount = amount % 10; { How much more change? } nickels = amount / 5; { How many nickels? } pennies = amount % 5; { Everything else is pennies } }

A typical invocation of this function might be:

makeChange (0.93, out penny, out nickel, out dime, out quarter);

6-8 Introduction to Computer Programming Using C#

about box. When any type of run-time customization is needed, though, the preferred approach is to communicate via a function subprogram with the form.

Using a Child Form to Display Results

As a first example of the use of a custom child form, suppose you want to use a child form to display summary data from an application in this format:

If this form has been created as a child form with the name Form2 , then the first step in displaying the form is to declare and initialize a form variable in the main application:

public partial class Form1 : Form { Form2 summaryForm;

public Form1() { InitializeComponent(); summaryForm = new Form2();

To communicate with this form, we’ll use a function named, appropriately, showSummary. This function will have to value parameters – an int representing the number of customers, and a double , representing the total sales for the day. If these variables are named numCustomers and totalSales , respectively, then the function might be invoked from a “button click” event like this:

summaryForm.showSummary (numCustomers, totalSales);

To finish the connection, you now need to shift to the child form. Probably the easiest thing to do is first create the “button click” handler for the child form’s OK button. As you would expect, this is nothing more than a simple Close(); instruction.

Next, scroll down below the closing brace ( } ) of the button click handler, and enter the definition

Chapter 6: Subprograms and Dialog Boxes 6-

of the showSummary function:

void showSummary (int custCount, double salesTotal) { countOut.Text = "" + custCount; totalOut.Text = String.Format("{0, 7:c2}", salesTotal); this.ShowDialog(); }

There are several details here that are worth noting. Maybe the first thing that hit you is the fact that different names were used for the variables that were used in the original reference to the showSummary function from the parent form. I did this on purpose to emphasize the fact that the names don’t have to match. Parameters to the function are matched up on the basis of order, and not name.

In these instructions, it’s assumed that the label fields on the form have been renamed countOut and totalOut. When values are transferred into these label fields, we use the names that we specified in the parameter list.

Finally, to show the contents of the child form, the ShowDialog directive is again used. I used the keyword this to indicate that the form to be shown is the form that contains the definition of the showSummary function.

Using a Child Form for Program Input

In order to use a child form as an input dialog, we need to have the child form provide information back to the main form. Therefore, communication with the child form will be through a function that uses out parameters to return the input values to the parent.

Additionally, since the child form will be used repeatedly, we need to be able to clear the text boxes on the form, and re-set the focus to the first input box, each time the form is displayed. To see how all of this comes together, we’ll start with the following input dialog:

Chapter 6: Subprograms and Dialog Boxes 6-

Project Assignments

Project 6.1: Bob’s Burger Barn

Background: Your cousin Bob will soon be opening his own fast-food restaurant, Bob’s Burger Barn, and has offered to cut you in on the profits if you’ll develop a simple computer program for capturing order information at the counter. Putting your collective brainpower together, the two of you decided to go with a program that uses three screen layouts, as shown below:

Normally, the leftmost screen is visible. When the New Order button is clicked, the second form should be displayed. The cashier will enter the number of hamburgers, the number of orders of fries, and the number of drinks ordered on this screen. When this screen is closed, control will return to the main screen, where the value of the order is calculated and displayed using a MessageBox.

When either the Summary or Close buttons are clicked, the third screen should be displayed, complete with the current values of the four summary items updated. From the Summary button, control will return to the main screen. However, when this screen is displayed by clicking on the Close button, the program should instead halt.

Step 1: Create the Three Screens and Set Up the Linkages

As the section heading suggests, you should begin by creating the 3 screens that your program will need. For your convenience, it would be a really good idea to rename the Text Box controls on the second form and the output Label fields on the third form. When you’re comfortable with the layout of the three forms, and form variables for each to the main form, and add instructions to the main form’s constructor to initialize the two child forms.

Next, you should define event handlers for the three buttons on the main form. For now, the handler for the New Order button should just display the second form; later, you’ll add the functional linkage to properly display the form and retrieve the input values from it. If the form variable for this input form is named inputForm , then you can display the form with the instruction:

6-12 Introduction to Computer Programming Using C#

inputForm.ShowDialog();

In a similar way, define the handlers for the Register Summary and Close buttons to display the summary form. In addition, after displaying the summary form from the Register Summary button, the program should reset focus to the New Order button. When the summary form is displayed from the Close button, however, the program should instead quit.

Step 2: Define and Initialize the Necessary Summary Variables

As shown on the Register Summary form, your program needs to keep track of 4 pieces of information - the number of orders, the total of the orders, the value of the largest order, and the value of the smallest order.

You should make up names for these four variables, and define them at the beginning of the main form - the form with the three buttons – and initialize them appropriately. Note that the number of orders, the total of the orders, and the highest order value should be initialized to zero. The lowest order value, however, should be initialized to a ridiculously high value - perhaps 10000.

Step 3: Create the Facilities for Accessing the Order Entry Form

When the New Order button is clicked, your program will need to reference a function that has been associated with the order entry form. This function will be responsible for displaying the form, and then retrieving the input values from the Text Box controls on the form, and returning them as out parameters.

Your first step should be to double-click the Order OK button on the order entry form, and add the Close() instruction to the button’s Click event handler. You need to implement this, anyway, and it will also open up the program code for the order entry form.

Next, scroll down below the closing brace ( } ) for the Click event handler, and add your function for displaying the form and retrieving the values from the Text Box controls:

public void getOrderInfo(out int burgers, out int fries, out int drinks) { this.ShowDialog(); burgers = Convert.ToInt32(burgersIn.Text); fries = Convert.ToInt32(friesIn.Text); drinks = Convert.ToInt32(drinksIn.Text); }

In this function, I’m assuming that you’ve renamed the Text Box controls on the form.

6-14 Introduction to Computer Programming Using C#

Step 5: Add Instructions to Compute the Summaries

Well, you’re in the home stretch now. All that’s left is to add the instructions for finding the values of the four summary variables. Counting the number of orders should be easy, and finding the total dollar value of all of the orders shouldn’t be much harder.

If you’ve read the previous chapter, you’ll know how to find the smallest and largest values, too. Rather than making you squirm, though, I’ll recap. To find the smallest value from a set of values, you need to create a “smallest value so far” variable. And you’ve already got that. You also need to initialize that variable to some ridiculously large number, and that should already be done, too. So all that’s left is for you to add an instruction that compares the current value to the “smallest value so far,” and, if the current value is smaller, the “smallest value so far” should be replaced with the current value. In the context of this project, you might do it like this:

if (totalBill < smallestOrder) smallestOrder = totalBill;

Finding the largest order would be similar.

Step 6: Display the Results on the Summary Child Form

All that’s left now is to transfer the computed results to the summary form, and display that form. First, add the Close() instruction needed to support the OK button on the summary form. Next, scroll down below the OK button event handler, and create the function that will transfer the values to the summary form, and then display the form. A typical implementation of this function might be:

public void showSummary(int numOrders, double orderValue, double smallOrder, double largeOrder) { label5.Text = "" + numOrders; label6.Text = String.Format("{0, 7:c2}", orderValue); label7.Text = String.Format("{0, 7:c2}", smallOrder); label8.Text = String.Format("{0, 7:c2}", largeOrder); this.ShowDialog(); }

Once this is in place, replace the ShowDialog() directive for the summary form that you added earlier with an invocation of this function to display the results.

Chapter 6: Subprograms and Dialog Boxes 6-

Project 6.2: Benji’s Big Top

Your uncle Benji owns a traveling circus, and is looking for some help managing the ticket booth. You’ve offered to help him out by creating a C# program to track his ticket sales. The main form for your application should look like this - notice that this form should be centered on the screen:

When the Buy Tickets button is clicked, a child form will be displayed, asking for the number of Children’s tickets, the number of Adult tickets, and the number of Senior Citizen tickets. This form should have a layout similar to the following; this form should also be centered on the screen:

After this form has been displayed, the information for the number of tickets of each type is used to compute the total charge for the tickets; this value is then displayed, using a Message Box. In addition, the program should keep track of the total number of tickets of each type, as well as the total revenue generated by sales within each category.

When the Sales Summary button is clicked, the number of children, adult, and senior citizen tickets

Chapter 6: Subprograms and Dialog Boxes 6-

revenue totals.

Next, create the Click event handler for the Buy Tickets button. For now, create 3 integer variables within this handler to hold the number of child, adult, and senior citizen tickets that are purchased. Next, add the single instruction:

orderForm.getOrder (out numChildren, out numAdults, out numSeniors);

Note that I’ve assumed that you chose to name your “ticket count” variables numChildren , numAdults , and numSeniors. You may need to adjust these to match the names you’ve chosen to use. You’ll fill in the remainder of this Click handler later; for now, this is enough to enable you to display the order entry form.

Next, create a Click event handler for the Sales Summary button, and add the single instruction:

summaryForm.Show_Summary (totChildren, childRevenue, totAdults, adultRevenue, totSeniors, seniorRevenue);

Again, you may need to alter the variable names I’ve shown to match the names that you created.

Now that you’ve got the connections to the child forms set up on your main form, you should turn your attention to the child forms. You should begin by creating the Click handler for the OK button on the order entry form – this handler only needs to close the form.

Once this is in place, add the definition for the getOrder function:

public void getOrder(out int child, out int adult, out int senior) { this.ShowDialog(); child = Convert.ToInt32(childTicketsIn.Text); adult = Convert.ToInt32(adultTicketsIn.Text); senior = Convert.ToInt32(seniorTicketsIn.Text); }

Of course, I’m assuming here that you’ll replace names that I used for the Text Box components with the names that you used.

While you’re still working on the order entry form, create an Activated event handler. Within this handler, add instructions to clear the 3 Text Box controls, and to shift focus to the “number of child tickets” control.

Now it’s time to turn your attention to the Sales Summary form. First, implement the Click handler

6-18 Introduction to Computer Programming Using C#

for the form’s OK button – again, all you need to do is close the form.

Next, add the definition for the showSummary function:

public void showSummary(int childTickets, double childRevenue, int adultTickets, double adultRevenue, int seniorTickets, double seniorRevenue) { chTix.Text = "" + childTickets; chRev.Text = String.Format("{0, 7:c2}", childRevenue); adTix.Text = "" + adultTickets; adRev.Text = String.Format("{0, 7:c2}", adultRevenue); srTix.Text = "" + seniorTickets; srRev.Text = String.Format("{0, 7:c2}", seniorRevenue); this.ShowDialog(); }

Of course, you may need to adjust the names for the label fields to match the names that you used.

Step 3: Give Your Project a Preliminary Test Run

At this point, you should be able to run your program for the first time. Clicking on the Buy Tickets and either the Show Summary or Done buttons should force the two child forms to display. Of course, the values entered on the first form will be ignored, and the summary values will still all be zero.

Step 4: Complete the Implementation of the Buy Tickets Button

When the Buy Tickets button is clicked, your application should figure out how much to charge for the requested tickets, display the resulting charge, and update the sales summary figures. First, though, some background is in order.

Benji charges $5.00 for a children’s ticket, $12.00 for an adult ticket, and $10.00 for a senior citizen ticket. However, since Benji knows that children who are accompanied by adults are very likely to buy a lot more snacks and souvenirs, he adds an incentive - each adult can bring a child for free, while each senior citizen can bring two children for free, since grandparents are even more likely to spend money to spoil the children. While this is a great marketing idea for Benji, it does complicate your job a little.

The first thing you’ll want to do is define some constants to hold the prices for the individual ticket types to the event handler. Next, you’ll want to add one more variable of type int to hold the number of free children tickets that might be awarded with this sale, and three variables of type double to hold the amount of the charges for each of the ticket classifications.

6-20 Introduction to Computer Programming Using C#

Project 6.3: Rating Collegiate Quarterbacks

It seems that individuals who don’t have the talent to be great athletes often choose to devote a great deal of their time and energy to collecting and analyzing statistics related to their favorite sports. Often, these statistics are used to support arguments over who is the best (or, in some cases, worst) player or team. One of the more interesting statistics is the quarterback passing efficiency rating - a composite measurement that tries to distill a quarterback’s various performance statistics into a single number. This rating is based on the number of passes attempted and completed, the total yardage from all passes, and the number of touchdown passes and interceptions thrown by the quarterback.

For this exercise, you’ll be developing a C# application that a fan could use to compute quarterback ratings, using the formula for collegiate quarterbacks. It shouldn’t come as a surprise to any die-hard fans to learn that the formula used to rate NFL quarterbacks is significantly more complicated.

Step 1: Create the Main Form

The program’s main form will be quite simple; its creation shouldn’t pose any serious challenges. However, you should make sure that the form is centered.

Of course, this doesn’t address what goes into the event handlers that will be associated with those buttons, but we’ll address that later. For now, some verbal explanation will suffice.

When the first button (“ Enter Another Quarterback’s Data ”) is clicked, a data entry dialog box will be displayed. The keyboard user will presumably enter the necessary data values, and then click an “ OK ” button. At this point, the quarterback’s passing rating will be computed and displayed in a

Chapter 6: Subprograms and Dialog Boxes 6-

second dialog box.

When the second button ( “No More Data” ) is clicked, a third dialog box will be displayed. This box will show the number of quarterbacks that were rated, along with the average rating, and the name and rating for the quarterback with the highest rating. After this dialog box is closed, the program should terminate.

Step 2: Create the Required Dialog Boxes

Remember – to add the additional forms to your C# project, use the “Add Windows Form…” option in the “Project” menu. The first dialog box will be used to obtain the data for a single quarterback; use a format similar to the following. Be sure to keep track of the names you use for the various text boxes, and again be certain that this and the remaining forms are centered when they are displayed.

The second dialog box will be used to display the rating information for a single quarterback. This dialog box should have a layout similar to the following: