This is the solution for the challenge called ChallengePostalCalculatorHelperMethods, the first of two challenges for the recent lessons covering the creation of helper methods. Because of the nature of this challenge, there are many different ways to solve it. If you created a program that functions according to the challenge’s requirements, then you successfully completed the challenge; regardless of whether or not it matches this solution. This is simply one of many possible solutions, not necessarily even the best. That being said, here is one solution for this challenge.
Step 1: Create the Default.aspx Page
As per the first non-functional requirement of this challenge, create a new project and call it ChallengePostalCalculatorHelperMethods. Then, add the Default.aspx page as we’ve done throughout this course. Add the following text and server controls to the page:
Next, add all three radioButtons to a common group called methodGroup.
Step 2: Create EventHandlers
In the requirements.txt document, the instruction is to produce a result on the screen as soon as the minimum amount of information is input. In order to do this, we’ll need to post back to the server every time an input is changed. We’ll do this by setting the AutoPostBack behavior. To do this, navigate to the properties window on a selected server control, and under Behavior, double click AutoPostBack:
Once this is completed for each of the server controls, we also need to create an EventHandler for when either the text is changed, or when a radioButton is selected. To do this, click on the lightning bolt in the properties window and double-click on either TextChanged (for TextBox) or CheckedChanged (for radioButton) under Action:
Step 3: Generating your First Method
While there are different methods (EventHandlers) for each server control, they will all be calling a single helper method that will check to see if sufficient user input is available to perform a calculation. Underneath your last generated method, create a new private void method called called performChanged(). We’ll worry about filling in the code for the method later.
Another way to create a method is to generate a method stub. To do this, go in to one of the existing methods and type in performChanged(). Notice that there is a red squiggly, indicating that no such reference exists. If you hover your mouse over that line of code, however, you’ll see a lightbulb icon called quick actions, and if you click on that you’ll be able to generate a method stub:
Note: Inside of the generated method, there is a line that throws a new exception:
We’ll cover exceptions and what they do in upcoming lessons in more detail. For now, know that it keeps Visual Studio from having a compilation error if you forget to fill in the method you generated.
Inside each of the EventHandlers, call the new performChanged() method.
Step 4: Creating your Code Outline
A useful way of creating code is to map out what the program needs to accomplish, in common terms, before writing your program. In this case, we need to:
- Check that there is sufficient data to perform a calculation
- Calculate the volume of the shipping container
- Determine the multiplier
- Calculate the total cost
- Display the cost to the user
What we can do now is generate methods to accomplish each of these tasks, then address each of them once they’re all in place.
To begin with, we need to check that there are values in the TextBoxes and one of the CheckBoxes before performing our calculation. To do this, let’s create a conditional check inside performChanged() that does the following:
Note: This valuesExist() method has yet to be created, but we are referencing it here for the sake of having our logic in place. We know that whenever a value has changed and performChanged() is called, we need to check if valuesExist(). If they do not, then we’ll cancel the operation.
Let’s continue by generating a method stub for the valuesExist() method. Notice how Visual Studio already knows that the method type should be bool, since it was generated from within a conditional check:
We won’t fill in the code logic for the methods until we’ve finished generating them. Next, let’s create a method for calculating the volume based on the input from the users. This is a great opportunity to use an output parameter in our methods.
Inside performChanged(), create another conditional statement to check if the input from the users can be used to get a volume:
This tryGetVolume() method will eventually evaluate whether or not the text can be parsed to an int. It will return true if it can, and false if it cannot. If it returns false, then we will return out of the performChanged() method. Notice it also has an output parameter that corresponds to the volume variable created above it. Now, generate a method stub for the tryGetVolume() method, and see the results:
See how it not only recognized that the method was a bool, but also that it has an integer output called volume.
Next, we need to determine what the postage multiplier will be based on the radioButton selected by the user. In order to do this, create a new double called postageMultiplier and set it equal to a new method called getPostageMultiplier() and generate a stub for it:
Next, we’ll create a calculation for what the cost will be by multiplying the volume by the postageMultiplier:
Finally, we’ll need to display the cost to the user in the resultLabel. We’ll use a String.Format() to accomplish this:
Your performChanged() method should look like this:
Step 5: Filling in the Logic
Let’s start filling in the code’s logic with the valuesExist() method. We’ll use two conditional statements to check if none of the radioButtons are checked, or if one of the two required TextBoxes are not filled in. If either of those cases are true, valuesExist() will return false. Otherwise, we’ll return true:
Remember that the Text.Trim() method evaluates the text after any blank spaces have been removed, or trimmed, from its value. This keeps the calculation from being affected by someone simply pressing the space bar within the text field.
Next, we’ll work with the tryGetVolume() method stub we generated. What we need to do is determine if the values the user input can be converted to integers. To do this, we’ll create integers for width, height and length, each set to 0. Then, we can use several conditional checks, each checking if(!int.TryParse()) for each for each of the TextBoxes, with the output being set to the appropriate variable (width, height or length). If width or height cannot be parsed, we’ll return false. If length cannot be parsed, we will set length equal to 1, because it is an optional value. If all those conditional checks go through, we’ll return true:
Finally, we need to work with the getPostageMultiplier() method. To do this, we’ll create three conditionals to check which radioButton is checked, and return the appropriate decimal multiplier. If none are selected, we’ll return 0:
Step 6: Test your Code and Refine
Now, save and run your project and see the result:
At this point, your code is fully functional and meets the requirement set out in the challenge. However, we can still make it better. When you think about it, why should we need six different events all calling the exact same method? There is a way around this. What we can do is create a new event called handleChange:
Now, you can delete all the EventHandlers that we previously had. What we’ll now do is go back into the properties for each server control, and instead of having the event register where it previously did, we can change it to handleChange:
Save your project and run it. You’ll see that it works exactly as it did before, but without the code redundancy we had before.
The moral of the story is this: Even though we had six different server controls, they all shared the same method and method signature. When you recognize this, you can simply set the property for handling the event to a common method. This drastically reduces the length and complexity of your code. Whenever you see redundancy throughout your code, you should look for different ways to reduce the complexity.
This completes the solution for ChallengePostalCalculatorHelperMethods. While this solution is rather lengthy, the actual code behind it isn’t very complicated. It requires a lot of thinking and creativity, but if you apply the concepts we’ve learned up until this point, it shouldn’t be too difficult. Again, if you achieved the goal but used came up with a different solution, that’s fine. In coding, there are many roads to the same destination. Keep up the great work, and keep reviewing for the first Mega Challenge coming up soon.