- •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
Figure 9.6: In the Dungeon Editor, you can change the values of the screen elements.
The editor is designed along the same general lines as the game program but is designed for building and editing adventures rather than playing them. Each game is designed as a series of rooms. A room has a name, a description, and links to as many as four other rooms. You can type the name of the room and its description directly into the appropriate text boxes and can choose the other rooms from the drop−down list boxes. You can move between rooms in the editor with the Next and Prev buttons.
Trick I’ve found that the easiest way to write an adventure game with this system is to start by entering all the room names first. When I come back to edit the rooms, all the other room names are available in the list boxes. Creating all the connections then becomes a simple process. Finally, I flesh out the story by adding the descriptive text.
That the editor and the game engine use a similar interface is handy because it speeds up the learning curve. You can safely assume that a user interested in creating or editing an adventure has already played at least one, so having the elements in familiar places makes learning the editor easy for a user.
Reading and Writing Text Files
Before you can write a program as involved as the Adventure Kit, you need to understand how computers work with files. Information in variables is very powerful, but variables are essentially references to memory. Most computer memory is volatile, which means that it can store values only while power is flowing through the computer. If you want to store values that live beyond one session at the computer, you need to be able to store information in files on a disk drive. Perhaps the simplest kinds of files are plain text files, which store information in pure ASCII form on the disk. These files are easy to work with, and they are universal. Nearly every computer made can store and load text files. This is why most Internet standards are based on the plain text format.
241
C# uses the concept of streams to manage files. Essentially, a file can be thought of as a continuous stream of data. Some streams specialize in providing data to the program. These are known as input streams. Other streams are used to store information to a drive system. These output streams specialize in sending data from the program to the drive system.
Exploring the File IO Program
The File IO program, displayed in Figure 9.7, is an example of simple input and output (collectively called IO) using input and output streams. The user interface of File IO has one new feature. So far in this book, most text boxes have displayed only one line of information. It’s possible to set up a text box to show multiple lines of data, using the Multiline property. This is useful when you want to display more than one line in a textbox. In the FileIO program, I show the entire file in a textbox, so the Multiline property makes the text much easier to read.
Figure 9.7: The File IO program has a large text box and buttons for saving and loading the file.
Importing the IO Namespace
The input and output features of C# are stored in a namespace called System.IO. Figure 9.8 shows the help system’s entry point into the System.IO namespace. The System.IO namespace has very useful classes. Table 9.1 describes a few of the more important classes in this namespace.
242
Figure 9.8: The System.IO namespace includes classes for input and output streams. Table 9.1: Significant Classes in the System.IO Namespace
Class |
Description |
File |
Features several methods for moving, copying, and testing a file (to see |
|
whether it exists, when it was created, what kind of access it allows) |
FileStream |
The basic file class, allows the author to open, close, read, and write to |
|
files, generally used for binary or random access data |
StreamReader |
A descendant of the FileStream class optimized for reading text−based |
|
information from a file |
StreamWriter |
A descendant of the FileStream class optimized for writing text−based |
|
information to a file |
Path |
Allows the programmer to create a valid file path from string data |
Directory |
Allows the programmer to create and manipulate directories |
Many other classes are available in the System.IO namespace, but the classes in Table 9.1 are a good starting point.
Any of your programs that will use File IO must import the System.IO namespace. The line looks like this:
using System.IO;
Trick I didn’t show you the rest of the code for the startup of the File IO program because, except for the event handlers, it is the default code generated by the designer. You can see the program in its entirety on the CD−ROM.
Writing to a Stream
The interesting parts of the File IO program happen in the event handlers of the two buttons. The Save button has code for writing the contents of the text box to a file stream:
243
private void btnSave_Click(object sender, System.EventArgs e) { StreamWriter sw = new StreamWriter("practice.txt"); sw.Write(txtEdit.Text);
sw.Close();
} // end btnSave
The btnSave() method is an event handler, which is automatically called when the user clicks btnSave. The method begins by creating an instance of the StreamWriter class. StreamWriter is optimized to write text files. It has a number of constructors, but the easiest requires simply the name of the file you want to write. The method then uses the Write() method of sw to write the text from the text box to the file. The last line of the method uses the Close() method to close access to the file.
Trap Forgetting to close files is common. If you make this mistake, the program will continue to run, but you will encounter a file access error the next time you try to open the same file—because it’s already open. This can be an ugly bug to track down because your program crashes not where the error occurs but the next time the program tries to access the file. Be sure to close every file after you’re done accessing it.
Writing to a text file in this manner is extremely simple. If you want, you can also write data one line at a time to the file. The StreamWriter class supports many of the same methods as the Console class—such as Write() and WriteLine()—so it isn’t difficult to use.
Reading from a Stream
Reading text from a file is much like writing to a file, except that you create an instance of the StreamReader class instead of the StreamWriter class. The code for btnLoad() in File IO demonstrates how to read the text from the file:
private void btnLoad_Click(object sender, System.EventArgs e) { StreamReader sr = new StreamReader("practice.txt"); txtEdit.Text = sr.ReadToEnd();
sr.Close();
} // end btnLoad
As you can see from the code listing, the StreamReader class is very easy to use. To read data from the stream, you use reading methods. The ReadLine() method works just like the ReadLine() method in the Console class. It reads from the stream until it encounters an end−of−line character. Often, you want to read the entire text of a file into a variable. The ReadToEnd() method quickly reads the entire text file.
In the File IO program, I decided to predetermine a file name. Letting the user choose a file name would be better, but this can be a dangerous exercise because you never know what the user will type. In the Dialog Demo program later in this chapter, I’ll show you how to let the user choose a file. Meanwhile, turn your attention to menus.
In the Real World
The text methods outlined here work fine for small text files without a lot of fancy formatting. These methods become more cumbersome when you are working with a large amount of data or when the data has very specific organization. In those situations, you might want more specialized storage techniques, such as the object serialization strategy described in the Serialization Demo program later in this chapter, the XML strategies described in Chapter 10, “Basic XML: The Quiz Maker,” or the database strategies described in Chapter 11, “Databases and ADO.NET: The Spy Database.”
244