- •Microsoft C# Programming for the Absolute Beginner
- •Table of Contents
- •Microsoft C# Programming for the Absolute Beginner
- •Introduction
- •Overview
- •Chapter 1: Basic Input and Output: A Mini Adventure
- •Project: The Mini Adventure
- •Reviewing Basic C# Concepts
- •Namespaces
- •Classes
- •Methods
- •Statements
- •The Console Object
- •.NET Documentation
- •Getting into the Visual Studio .Net Environment
- •Examining the Default Code
- •Creating a Custom Namespace
- •Adding Summary Comments
- •Creating the Class
- •Moving from Code to a Program
- •Compiling Your Program
- •Looking for Bugs
- •Getting Input from the User
- •Creating a String Variable
- •Getting a Value with the Console.ReadLine() Method
- •Incorporating a Variable in Output
- •Combining String Values
- •Combining Strings with Concatenation
- •Adding a Tab Character
- •Using the Newline Sequence
- •Displaying a Backslash
- •Displaying Quotation Marks
- •Launching the Mini Adventure
- •Planning the Story
- •Creating the Variables
- •Getting Values from the User
- •Writing the Output
- •Finishing the Program
- •Summary
- •Chapter 2: Branching and Operators: The Math Game
- •The Math Game
- •Using Numeric Variables
- •The Simple Math Game
- •Numeric Variable Types
- •Integer Variables
- •Long Integers
- •Data Type Problems
- •Math Operators
- •Converting Variables
- •Explicit Casting
- •The Convert Object
- •Creating a Branch in Program Logic
- •The Hi Bill Game
- •Condition Testing
- •The If Statement
- •The Else Clause
- •Multiple Conditions
- •Working with The Switch Statement
- •The Switch Demo Program
- •Examining How Switch Statements Work
- •Creating a Random Number
- •Introducing the Die Roller
- •Exploring the Random Object
- •Creating a Random Double with the .NextDouble() Method
- •Getting the Values of Dice
- •Creating the Math Game
- •Designing the Game
- •Creating the Variables
- •Managing Addition
- •Managing Subtraction
- •Managing Multiplication and Division
- •Checking the Answers
- •Waiting for the Carriage Return
- •Summary
- •Chapter 3: Loops and Strings: The Pig Latin Program
- •Project: The Pig Latin Program
- •Investigating The String Object
- •The String Mangler Program
- •A Closer Look at Strings
- •Using the Object Browser
- •Experimenting with String Methods
- •Performing Common String Manipulations
- •Using a For Loop
- •Examining The Bean Counter Program
- •Creating a Sentry Variable
- •Checking for an Upper Limit
- •Incrementing the Variable
- •Examining the Behavior of the For Loop
- •The Fancy Beans Program
- •Skipping Numbers
- •Counting Backwards
- •Using a Foreach Loop to Break Up a Sentence
- •Using a While Loop
- •The Magic Word Program
- •Writing an Effective While Loop
- •Planning Your Program with the STAIR Process
- •S: State the Problem
- •T: Tool Identification
- •A: Algorithm
- •I: Implementation
- •R: Refinement
- •Applying STAIR to the Pig Latin Program
- •Stating the Problem
- •Identifying the Tools
- •Creating the Algorithm
- •Implementing and Refining
- •Writing the Pig Latin Program
- •Setting Up the Variables
- •Creating the Outside Loop
- •Dividing the Phrase into Words
- •Extracting the First Character
- •Checking for a Vowel
- •Adding Debugging Code
- •Closing Up the code
- •Summary
- •Introducing the Critter Program
- •Creating Methods to Reuse Code
- •The Song Program
- •Building the Main() Method
- •Creating a Simple Method
- •Adding a Parameter
- •Returning a Value
- •Creating a Menu
- •Creating a Main Loop
- •Creating the Sentry Variable
- •Calling a Method
- •Working with the Results
- •Writing the showMenu() Method
- •Getting Input from the User
- •Handling Exceptions
- •Returning a Value
- •Creating a New Object with the CritterName Program
- •Creating the Basic Critter
- •Using Scope Modifiers
- •Using a Public Instance Variable
- •Creating an Instance of the Critter
- •Adding a Method
- •Creating the talk() Method for the CritterTalk Program
- •Changing the Menu to Use the talk() Method
- •Creating a Property in the CritterProp Program
- •Examining the Critter Prop Program
- •Creating the Critter with a Name Property
- •Using Properties as Filters
- •Making the Critter More Lifelike
- •Adding More Private Variables
- •Adding the Age() Method
- •Adding the Eat() Method
- •Adding the Play() Method
- •Modifying the Talk() Method
- •Making Changes in the Main Class
- •Summary
- •Introducing the Snowball Fight
- •Inheritance and Encapsulation
- •Creating a Constructor
- •Adding a Constructor to the Critter Class
- •Creating the CritViewer Class
- •Reviewing the Static Keyword
- •Calling a Constructor from the Main() Method
- •Working with Multiple Files
- •Overloading Constructors
- •Viewing the Improved Critter Class
- •Adding Polymorphism to Your Objects
- •Modifying the Critter Viewer in CritOver to Demonstrate Overloaded Constructors
- •Using Inheritance to Make New Classes
- •Creating a Class to View the Clone
- •Creating the Critter Class
- •Improving an Existing Class
- •Introducing the Glitter Critter
- •Adding Methods to a New Class
- •Changing the Critter Viewer Again
- •Creating the Snowball Fight
- •Building the Fighter
- •Building the Robot Fighter
- •Creating the Main Menu Class
- •Summary
- •Overview
- •Introducing the Visual Critter
- •Thinking Like a GUI Programmer
- •Creating a Graphical User Interface (GUI)
- •Examining the Code of a Windows Program
- •Adding New Namespaces
- •Creating the Form Object
- •Creating a Destructor
- •Creating the Components
- •Setting Component Properties
- •Setting Up the Form
- •Writing the Main() Method
- •Creating an Interactive Program
- •Responding to a Simple Event
- •Creating and Adding the Components
- •Adding an Event to the Program
- •Creating an Event Handler
- •Allowing for Multiple Selections
- •Choosing a Font with Selection Controls
- •Creating the User Interface
- •Examining Selection Tools
- •Creating Instance Variables in the Font Chooser
- •Writing the AssignFont() Method
- •Writing the Event Handlers
- •Working with Images and Scroll Bars
- •Setting Up the Picture Box
- •Adding a Scroll Bar
- •Revisiting the Visual Critter
- •Designing the Program
- •Determining the Necessary Tools
- •Designing the Form
- •Writing the Code
- •Summary
- •Chapter 7: Timers and Animation: The Lunar Lander
- •Introducing the Lunar Lander
- •Reading Values from the Keyboard
- •Introducing the Key Reader Program
- •Setting Up the Key Reader Program
- •Coding the KeyPress Event
- •Coding the KeyDown Event
- •Determining Which Key Was Pressed
- •Animating Images
- •Introducing the ImageList Control
- •Setting Up an Image List
- •Looking at the Image Collection
- •Displaying an Image from the Image List
- •Using a Timer to Automate Animation
- •Introducing the Timer Control
- •Configuring the Timer
- •Adding Motion
- •Checking for Keyboard Input
- •Working with the Location Property
- •Detecting Collisions between Objects
- •Coding the Crasher Program
- •Getting Values for newX and newY
- •Bouncing the Ball off the Sides
- •Checking for Collisions
- •Extracting a Rectangle from a Component
- •Getting More from the MessageBox Object
- •Introducing the MsgDemo Program
- •Retrieving Values from the MessageBox
- •Coding the Lunar Lander
- •The Visual Design
- •The Constructor
- •The timer1_Tick() Method
- •The moveShip() Method
- •The checkLanding() Method
- •The theForm_KeyDown() Method
- •The showStats() Method
- •The killShip() Method
- •The initGame() Method
- •Summary
- •Chapter 8: Arrays: The Soccer Game
- •The Soccer Game
- •Introducing Arrays
- •Exploring the Counter Program
- •Creating an Array of Strings
- •Referring to Elements in an Array
- •Working with Arrays
- •Using the Array Demo Program to Explore Arrays
- •Building the Languages Array
- •Sorting the Array
- •Designing the Soccer Game
- •Solving a Subset of the Problem
- •Adding Percentages for the Other Players
- •Setting Up the Shot Demo Program
- •Setting Up the List Boxes
- •Using a Custom Event Handler
- •Writing the changeStatus() Method
- •Kicking the Ball
- •Designing Programs by Hand
- •Examining the Form by Hand Program
- •Adding Components in the Constructor
- •Responding to the Button Event
- •Building the Soccer Program
- •Setting Up the Variables
- •Examining the Constructor
- •Setting Up the Players
- •Setting Up the Opponents
- •Setting Up the Goalies
- •Responding to Player Clicks
- •Handling Good Shots
- •Handling Bad Shots
- •Setting a New Current Player
- •Handling the Passage of Time
- •Updating the Score
- •Summary
- •Chapter 9: File Handling: The Adventure Kit
- •Introducing the Adventure Kit
- •Viewing the Main Screen
- •Loading an Adventure
- •Playing an Adventure
- •Creating an Adventure
- •Reading and Writing Text Files
- •Exploring the File IO Program
- •Importing the IO Namespace
- •Writing to a Stream
- •Reading from a Stream
- •Creating Menus
- •Exploring the Menu Demo Program
- •Adding a MainMenu Object
- •Adding a Submenu
- •Setting Up the Properties of Menu Items
- •Writing Event Code for Menus
- •Using Dialog Boxes to Enhance Your Programs
- •Exploring the Dialog Demo Program
- •Adding Standard Dialogs to Your Form
- •Using the File Dialog Controls
- •Responding to File Dialog Events
- •Using the Font Dialog Control
- •Using the Color Dialog Control
- •Storing Entire Objects with Serialization
- •Exploring the Serialization Demo Program
- •Creating the Contact Class
- •Referencing the Serializable Namespace
- •Storing a Class
- •Retrieving a Class
- •Returning to the Adventure Kit Program
- •Examining the Room Class
- •Creating the Dungeon Class
- •Writing the Game Class
- •Writing the Editor Class
- •Writing the MainForm Class
- •Summary
- •Chapter 10: Chapter Basic XML: The Quiz Maker
- •Introducing the Quiz Maker Game
- •Taking a Quiz
- •Creating and Editing Quizzes
- •Investigating XML
- •Defining XML
- •Creating an XML Document in .NET
- •Creating an XML Schema for Your Language
- •Investigating the .NET View of XML
- •Exploring the XmlNode Class
- •Exploring the XmlDocument Class
- •Reading an Existing XML Document
- •Creating the XML Viewer Program
- •Writing New Values to an XML Document
- •Building the Document Structure
- •Adding an Element to the Document
- •Displaying the XML Code
- •Examining the Quizzer Program
- •Building the Main Form
- •Writing the Quiz Form
- •Writing the Editor Form
- •Summary
- •Overview
- •Introducing the SpyMaster Program
- •Creating a Simple Database
- •Accessing the Data Server
- •Accessing the Data in a Program
- •Using Queries to Modify Data Results
- •Limiting Data with the SELECT Statement
- •Using an Existing Database
- •Adding the Capability to Display Queries
- •Creating a Visual Query Builder
- •Working with Relational Databases
- •Improving Your Data with Normalization
- •Using a Join to Connect Two Tables
- •Creating a View
- •Referring to a View in a Program
- •Incorporating the Agent Specialty Attribute
- •Working with Other Databases
- •Creating a New Connection
- •Converting a Data Set to XML
- •Reading from XML to a Data Source
- •Creating the SpyMaster Database
- •Building the Main Form
- •Editing the Assignments
- •Editing the Specialties
- •Viewing the Agents
- •Editing the Agent Data
- •Summary
- •List of Figures
- •List of Tables
- •List of Sidebars
Arrays are much like any other type of variable. They can be created at the class level or inside methods, and they can be declared with the public and private modifiers.
Referring to Elements in an Array
When you build an array you will also need to ensure that each element of the array has a starting value. This is called initializing an array. In the counter program, I initialized the array in the constructor:
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
numbers[0] = "zero"; numbers[1] = "one"; numbers[2] = "two"; numbers[3] = "three"; numbers[4] = "four";
} // end form1
The program assigns a different string value to each element of the array. Because numbers is defined as an array of strings, it can be referred to only with braces and an integer index, as shown in the preceding code. Also, notice that array indices start at 0, not at 1. The numbers array has five elements, but those elements are numbered 0 to 4, not 1 to 5, as you might expect.
Trap When you declare an array, you are determining the number of elements in the array, not the value of the largest index. If you create an array of 10 elements, the last one is element 9. C# currently does not allow you to change this behavior.
Working with Arrays
Arrays are a powerful feature in every programming language but even more useful in C#. This is because arrays are a type of object in C#. Like other objects, arrays have methods and properties. When you understand some of these characteristics of the array class, you can do many interesting things with arrays.
Using the Array Demo Program to Explore Arrays
The Array Demo program featured in Figure 8.5 puts the array class through its paces, showing off some interesting capabilities. The program features a list box control for displaying the array (lstOutput), a pair of option buttons (optSorted and optUnsorted) for determining whether the array is sorted, and a button (btnForEach) for demonstrating the foreach loop. Notice that the search button (btnSearch) and its associated text box (txtSearch) are disabled. The user can see them, but they are not currently functional. This is because the searching operation I’ll be demonstrating works only with sorted arrays. When the array is sorted, I’ll make these controls available to the user.
208
Figure 8.5: An array of programming language names is displayed in a list box. The array is not in any particular order.
Building the Languages Array
The Array Demo program is (not surprisingly) closely related to an array. For lack of anything more interesting, I chose to create an array of programming language names. Because I use the array throughout the program, it is declared at the class level:
string[] languages = { "Java",
"Basic",
"Pascal",
"C#",
"Perl",
};
string[] sortedLangs = new string[5]; showUnsorted();
If you examine the code, you will see that I created the array a little differently than in the Counter program. If you know exactly what elements are going to go in the array when you create it, you can “preload” the array, as I did in this example. Notice the use of braces to indicate the beginning and end of the array definition. Also, because arrays can be large, I chose to put each element on a different line of the code listing.
The sortedLangs variable is another string array of five elements. This array will hold the sorted version of the languages array.
The last line calls a method that will show the unsorted version of the array in the list box. The details of that method are explained in the next section.
Sorting the Array
When you have an array of data, you usually need to sort it. Sorting an array by hand can be difficult. Computer science instructors love to drone on endlessly about the subject. In C#, however, you usually don’t have to worry about the details of sorting because the array class already has an efficient sort method built in. Figure 8.6 shows the array after it has been sorted.
209
Figure 8.6: When the user chooses the sort option, the array appears in alphabetical order. Trick The array is invisible to the user. Arrays are data structures stored in the computer’s
memory. For the sake of demonstration, I’ve copied the array over to the list box so that you can see what’s going on “under the hood.”
The user can choose the sorted or unsorted view of the array via the option buttons. Option buttons, as you recall, are handy when only one out of a group of choices should be selected at a time. I added code to the default event of the option buttons to manage the array sorting.
Creating the ShowUnsorted() Method
Because the unsorted array needs to be displayed at the beginning of the program and whenever the unsorted option is selected, I decided to make it a method:
private void showUnsorted(){
//displays the array in the list box in its default state lstOutput.Items.Clear(); lstOutput.Items.AddRange(languages);
} //end showUnsorted
The ShowUnsorted() method begins by clearing the list box. You might expect the list box class to have a Clear() method (I expected that, anyway). It doesn’t, exactly. Instead, the Clear() method belongs to the Items property, which is an instance of the Listbox.ObjectCollection class. Although this seems complex, it’s actually a good thing because the ObjectCollection class is a handy class with neat features for adding elements to a list box, clearing the elements from the list box, and more. Figure 8.7 shows the help screen for this class.
210
Figure 8.7: The methods of the Array object make it easy to work with, especially if you are working with some kind of array.
Specifically, the Clear() method is used to clear all elements from the list box, and the AddRange() method is used to copy an entire array to the list box. If you want to add only one element at a time, use the Add() method instead. As you can see, the list box control is like a visual wrapper around an array. It’s easy to copy array values to the list box and get an array from the list.
Handling the Unsorted Option
When the user clicks the unsorted option, the optUnsorted_CheckChanged() method is automatically called. The code for this method is very straightforward:
private void optUnsorted_CheckedChanged(object sender, System.EventArgs e) {
btnSearch.Enabled = false; txtSearch.Enabled = false; showUnsorted();
} // end optUSorted
If the array is unsorted, the search method will not work, so I disabled the searching controls. Doing this is a good idea because it prevents the user from getting an error. When the searching controls are turned off, the method calls the showUnsorted() method, which copies the original (unsorted) languages array to the list box.
Handling the Sort Option
If the user chooses to sort the array, an event handler of the optSorted object does the job:
private void optSorted_CheckedChanged(object sender, System.EventArgs e) {
languages.CopyTo(sortedLangs,0);
Array.Sort(sortedLangs);
211
lstOutput.Items.Clear();
lstOutput.Items.AddRange(sortedLangs); btnSearch.Enabled = true; txtSearch.Enabled = true;
} // end optSorted
Because the user might want the original array again, I decided to sort a copy of the original. The languages variable is an array, and the array class has a CopyTo() method. This method takes two parameters. First, it needs the name of an array to copy to. Also, it needs to know which element to start with. The target array should have the same type as the original and should have at least as many elements as the source array. In this case, I called the sorted array sortedLangs. The Array.Sort() method provides an easy way to sort the array alphabetically. After the array was sorted, I cleared out the list box and copied the sortedLangs array to it.
The user should be allowed to search the array now because it is sorted, so I enabled the button and text box for searching.
Trick If it bugs you to have elements on the screen that are visible but not available to the user, you can make them completely visible and invisible by manipulating the Visible property instead of the Enabled property. Some argue that leaving controls visible but disabled gives the user a clue that searching the array is possible, but not in the program’s current state.
Searching for an Element
If an array is large, searching through it to find where a particular element is in the array can be very helpful. Although the arrays used in this demo are not large enough to need this functionality, it is still useful, especially because the Array object has a very nice search method built in, as illustrated in Figure 8.8.
Figure 8.8: The user can search for an element to see where it is in the array.
Searching efficiently for elements in an array can be surprisingly difficult, especially if the array contains hundreds or thousands of elements. One of the most powerful types of search algorithms is the binary search. It works only on sorted arrays but can quickly find where a value is in even very large arrays. This binary algorithm is the one implemented in the BinarySearch() method. Searching for a value in the Array Demo program might seem trivial because the underlying array has only five elements. Searching and sorting arrays are much more critical operations when the array is larger, but these operations work identically on smaller arrays, too.
212
The search operation happens when the user clicks the Search button:
private void btnSearch_Click(object sender, System.EventArgs e) {
int theIndex; string message;
theIndex = Array.BinarySearch(sortedLangs, 0,sortedLangs.Length, txtSearch.Text);
if (theIndex < 0){ message = "not found.";
}else {
message = sortedLangs[theIndex]; message += " is at position "; message += theIndex.ToString();
}// end if MessageBox.Show(message);
}// end btnSearch
The method has two variables. theIndex stores the results of the search, and message holds a message to the user regarding the success or failure of the search.
I used the BinarySearch method of the Array class to search for the contents of the txtSearch text box in the sortedLangs array. The BinarySearch method also requires a starting number and length. I specified that the search should start at element 0 and continue for the length of the array. If the search value is not found, the algorithm returns a negative value, so I tested for the not found condition. If the result of the search is negative, I inform the user that the search was not successful. If the result is positive, the program returns the location of the value in the array.
Trap Note that the elements are counted beginning with 0. Even though Basic is the first item in the sorted array (at least, to human reasoning), it is reported as element number 0.
Using Foreach with Arrays
You learned how to use the foreach loop in Chapter 3, "Loops and Strings: The Pig Latin Program." However, my explanation of the loop in that chapter is weak because the foreach loop is closely related to arrays, which you hadn’t learned yet. Figure 8.9 illustrates part of what happens when the user clicks the forEach button.
213