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

Interacting with Text Files and Controlling ListBox and ComboBox in C# - Prof. Mark G. Ter, Study notes of Computer Science

An overview of working with text files using c#, focusing on file structures, reading and writing data, and interacting with listbox and combobox controls. It covers topics like binary files, text files, streams, and various methods for handling listbox and combobox items.

Typology: Study notes

Pre 2010

Uploaded on 08/07/2009

koofers-user-7mn
koofers-user-7mn 🇺🇸

10 documents

1 / 18

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Introduction to Computer Programming Using C#
10-2
An Overview of File Structures
Whenever a program terminates, all of the data the program has collected in the computer's
memory is lost. In order to keep information on a semi-permanent basis, the program needs to
transfer that information to some type of external storage, such as a disk file.
When data is transferred to a file, the computer programmer has two format choices. The data
can be stored in its internal binary form, or it can be converted to a textual format. When the file
is recorded in binary form, it's referred to as a binary file. If instead the data is converted to a
textual format, the file is referred to as a text file.
As a general rule, binary files are more efficient than text files. They require less space and less
processing time, since binary format is a more compact way to represent numeric data, and the
overhead associated with conversion between binary and text format is eliminated. On the other
hand, text files are often more convenient, since they can be loaded directly into other software
packages that allow the data to be examined and manipulated. For example, most spreadsheet
programs can import data from a text file directly, but can't readily import an arbitrary binary file.
Because of their more general applicability, we'll focus our attention on text files.
Accessing a Text File
In order to use a file within a program, several basic steps are required. First, you need to include
the C# namespace System.IO in your application by adding it to the using clauses at the
beginning of your application:
using System.IO;
Next, you have to declare one or more file variables, and associate each with an actual external
device. Finally, you need to initialize each of the files for either input or output. Once all of these
steps have been carried out, the actual processing can begin.
In C#, text files are associated with streams. In this context, the term stream refers to a sequence
of bytes that are being transferred to or from an external device. When data is to be transmitted to
your program, you use a variable of type StreamReader, while the type StreamWriter is used
when you want to send data from your program.
In order to access a stream, you need to first associate the stream with a physical file on the
computer. In some situations, you want to provide the file name directly:
StreamReader input;
...
input = new StreamReader("c:\\datafolder\\inputdata.txt");
Notice how, in this example, it was necessary to double the backslash symbols that are normally
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12

Partial preview of the text

Download Interacting with Text Files and Controlling ListBox and ComboBox in C# - Prof. Mark G. Ter and more Study notes Computer Science in PDF only on Docsity!

10-2 Introduction to Computer Programming Using C#

An Overview of File Structures

Whenever a program terminates, all of the data the program has collected in the computer's memory is lost. In order to keep information on a semi-permanent basis, the program needs to transfer that information to some type of external storage, such as a disk file.

When data is transferred to a file, the computer programmer has two format choices. The data can be stored in its internal binary form, or it can be converted to a textual format. When the file is recorded in binary form, it's referred to as a binary file. If instead the data is converted to a textual format, the file is referred to as a text file.

As a general rule, binary files are more efficient than text files. They require less space and less processing time, since binary format is a more compact way to represent numeric data, and the overhead associated with conversion between binary and text format is eliminated. On the other hand, text files are often more convenient, since they can be loaded directly into other software packages that allow the data to be examined and manipulated. For example, most spreadsheet programs can import data from a text file directly, but can't readily import an arbitrary binary file. Because of their more general applicability, we'll focus our attention on text files.

Accessing a Text File

In order to use a file within a program, several basic steps are required. First, you need to include the C# namespace System.IO in your application by adding it to the using clauses at the beginning of your application:

using System.IO;

Next, you have to declare one or more file variables, and associate each with an actual external device. Finally, you need to initialize each of the files for either input or output. Once all of these steps have been carried out, the actual processing can begin.

In C#, text files are associated with streams. In this context, the term stream refers to a sequence of bytes that are being transferred to or from an external device. When data is to be transmitted to your program, you use a variable of type StreamReader , while the type StreamWriter is used when you want to send data from your program.

In order to access a stream, you need to first associate the stream with a physical file on the computer. In some situations, you want to provide the file name directly:

StreamReader input; ... input = new StreamReader("c:\datafolder\inputdata.txt");

Notice how, in this example, it was necessary to double the backslash symbols that are normally

Chapter 10: Interacting with Text Files (^) 10-

included in file paths under Windows. Recall that the backslash symbol is used as an escape symbol in C# for specifying special characters, such as tabs and new lines ( \t and \n , respectively) in a string. Because of this reserved usage, you need to prefix a backslash that is to be included in a string with another backslash. Alternatively, C# allows you to define a verbatim string by placing the symbol @ ahead of the string’s definition. In verbatim strings, you can embed the special characters, such as tabs and new lines, directly in the body of the string. If you precede an explicit file name with the @ symbol, it’s no longer necessary to double the backslashes:

input = new StreamReader(@"c:\datafolder\inputdata.txt");

When creating a visual interface for a C# application, you can allow the keyboard user to select a file to be associated with a stream, by means of either an OpenFileDialog or SaveFileDialog component. These dialog components are used to display a standard Windows Open or Save dialog box on the screen. The familiar Open dialog box is shown below, although the file and folder names that normally populate the dialog box have been erased to protect the innocent:

Notice how the initial file name shown in this box is “openFileDialog1.” By default, when you add an OpenFileDialog to your C# application, the component’s name is echoed in the FileName attribute. Interestingly, this same attribute is initially blank for the SaveFileDialog component. If you want a default file name to be specified, you can set this attribute to some different value, either at design time, or while your application is running.

Chapter 10: Interacting with Text Files (^) 10-

saveFileDialog1.FileName = ""; if (saveFileDialog1.ShowDialog() == DialogResult.OK) { outputStatus = new FileInfo(saveFileDialog1.FileName); output = outputStatus.CreateText(); } else { // The keyboard user selected Cancel }

In some contexts, you may want to add to the end of an existing output file, rather than replace that file with a new one. In this situation, you can initialize the output stream using the AppendText() method:

output = outputStatus.AppendText();

If you’re not sure, you can allow your program to test for the file’s existence. If it does exist, you can initialize it with the AppendText() method; otherwise, you can use CreateText() :

FileInfo outputStatus; StreamWriter output; ... saveFileDialog1.FileName = ""; if (saveFileDialog1.ShowDialog() == DialogResult.OK) { outputStatus = new FileInfo(saveFileDialog1.FileName); if (outputStatus.Exists) output = outputStatus.AppendText(); else { output = outputStatus.CreateText(); } } else { // The keyboard user selected Cancel }

Normally, C# takes care of cleaning up any variables that you might create when you’ve finished with them. With a stream, though, it’s important that you notify C# when you’re done using it. If you fail to do so, the stream may be left in an inconsistent state. Therefore, before leaving the program unit in which the stream is declared and accessed, be sure to Close() the stream:

10-6 Introduction to Computer Programming Using C#

input.Close(); output.Close();

Because Windows allows you to jump from task to task, it’s not usually good programming practice to maintain a connection to a stream for an extended period of time. In practice, you would normally connect to an input stream, read all of the information from that stream into some internal storage – perhaps an ArrayList – and then close the stream. For output streams, you should accumulate all of the information to be written to the stream, and then write it in one single shot. Alternatively, if it’s important that no information be lost if your application fails for some reason, you should initialize the stream in append mode, each time a new piece of output information becomes available, then transfer that data to the stream and close it.

Stream Input and Output

The most elementary operations on a stream are reading and writing of character strings. To retrieve the next line of text from the stream named input , and store it in the string inLine , you could use the directive:

inLine = input.ReadLine();

If there is no more data in the input stream, an empty (or null ) string will be generated. You can test for this explicitly:

inLine = input.ReadLine(); if (inLine == null) // there’s no more data in the stream

Since all of the lines in an input stream are normally read at the same time, it’s quite common to embed input stream processing in a loop, perhaps like this:

while ((inLine = input.ReadLine()) != null) { // process the contents of inLine } input.Close();

If a stream has been initialized for output, individual strings can be sent to the stream using the WriteLine() command:

output.WriteLine(nextLine);

10-8 Introduction to Computer Programming Using C#

FileInfo outputStatus; StreamWriter output;

outputStatus = new FileInfo(@"c:\MyFiles\ClassStats.txt"); if (outputStatus.Exists) { output = outputStatus.CreateText(); foreach (Student s in students) { output.WriteLine(s.getName()); output.WriteLine("" + s.getScore()); } output.Close(); }

Of course, there are many variants possible, depending on the desired format of the output file. In this example, the results were written on separate lines because that’s the easiest way to read the information back in from a C# application. If you were instead creating an output file that could be imported into a spreadsheet, you may want to place all of the information for one student on a single line of output, separated by commas or tabs:

output.WriteLine(s.getName() + "," + s.getScore()); or:

output.WriteLine(s.getName() + "\t" + s.getScore());

Handling Input Lines with Complex Organization

Quite often, it’s impractical to require that input files be organized so there is only one piece of information on each line. Many software products create text files in which each line of text holds all of the information for a single “record” of information, with the individual fields of the record separated by commas. For example, consider the following, which was clipped out of an Excel spreadsheet:

If I ask Excel to save this data, which represents the grades earned by a series of students on three exams administered during the semester, as a .csv, or comma-delimited file, it would appear like this:

Chapter 10: Interacting with Text Files (^) 10-

Adam Archer,83,79, Bonnie Baker,92,88, Carl Collins,78,71, Donna Drake,79,83,

If a C# program uses the ReadLine() instruction to input the data from this file, all of the information from a single line will be drawn in as a single string. Fortunately, C# provides a special String method, Split() , that can be used to break an input string like this into individual entries. To use this instruction, you first create a set of delimiters, and then use that list to break the line into an array, or collection, of strings:

// For this example, only the comma is expected to serve as // a delimiter. If there were more possible delimiters, you // could add them to this declaration, separating // the individual delimiters with commas

char[] delimiters = {','}; // recognized delimiter(s) string[] fields; // individual input fields

... input = inputStatus.OpenText(); while ((inputLine = input.ReadLine()) != null) { fields = inputLine.Split(delimiters);

// Now fields[0] holds the student name, while the // individual scores are in fields[1], fields[2], and // fields[3], in character-string form }

ListBox and ComboBox Controls

A ListBox is a Windows control that contains, potentially, several lines of text, along with scroll bars allowing the text to be scrolled up and down, if there are too many lines to show on the screen. List boxes are commonly used to show a list of possible options, from which the keyboard user is expected to make a selection.

In contrast, a ComboBox is a Windows control that combines a TextBox component coupled with a ListBox. The keyboard user can either enter text directly into the TextBox component of the ComboBox , or else select an entry from the pull-down ListBox that is associated with the ComboBox.

The following screen snapshot shows both a ListBox (on the left) and a ComboBox (on the right) that have been populated with a set of student names. Note that the mouse has been used to

Chapter 10: Interacting with Text Files (^) 10-

return name; } }

To populate the Items of a ListBox or ComboBox , you can use the Add() method:

listBox1.Items.Add(nextItem); comboBox1.Items.Add(nextItem);

The individual items in a ListBox or ComboBox can be accessed by subscripting, although it’s also necessary to explicitly specify the type of the item being accessed:

selectedStudent = (Student)listBox1.Items[chosen];

It should be noted that a subscript of 0 references the first element in the list of Items.

The SelectedIndex attribute of either a ListBox or ComboBox control is used to determine which (if any) of the strings displayed in the control is currently selected. When none of the strings are selected, this value is set to -1, but, as soon as you highlight one of the strings with the cursor, the value of SelectedIndex is set to indicate which entry has been selected. Again, the first entry in the Items list has an index value of 0. This attribute is writable, so you can either clear a selection at run-time, by setting the value of the SelectedIndex attribute to -1, or pre- select a specific entry by setting the value of the SelectedIndex attribute to the location of that entry.

Individual entries can be removed from the Items associated with a ListBox or ComboBox either by value or by position.

To delete a specific value from the Items list, you can use the Remove() method. For example, if the ListBox control named productList contains the entry that is currently stored in the variable target , you could use the instruction:

productList.Items.Remove(target);

Alternatively, if you know the position in which value to be removed is currently stored, you can instead use the RemoveAt() method. For example, to remove the currently highlighted entry from the ComboBox control named optionList , you might use this instruction:

if (optionList.SelectedIndex >= 0) optionList.Items.RemoveAt(optionList.SelectedIndex);

Many other tools are also available for working with these controls, but this should be enough to at least give you a sense of the potential usefulness of these controls.

10-12 Introduction to Computer Programming Using C#

Project Assignments

Project 10.1: Inventory Management

Your troublesome cousin Carla, who works for Lake Side Sales Company, has volunteered you to develop a simple inventory management system for her employers. As a first step, you’ve agreed to put together an inventory “browser” application. This program will allow its user to look at the inventory records for the various items that Lake Side stocks, and also allow users to add or delete inventory records, or adjust the list price or quantity on hand of individual items.

Step 1: Set Up the Basic Form

Your form will contain 4 Text Box controls, a ListBox , 5 Button s, several Label s, a Panel , and an OpenFileDialog component, arranged as shown below:

While it isn’t obvious, the Visible attribute of the Panel should be false , and the Sorted attribute of the ListBox should be set to true.

When the program starts up, the OpenFileDialog will be used to obtain the name of the inventory file from the keyboard user. The records from this file will then be read in, the data from these records will be placed in class variables, and those class variables will be added to the ListBox control’s Items attribute.

10-14 Introduction to Computer Programming Using C#

public int getItemNum() { return itemNum; } public string getDescription() { return description; } public double getPrice() { return listPrice; } public int getQuantity() { return qtyOnHand; }

Because the program is supposed to allow users to modify the list price and quantity on hand values, a couple more methods are required to modify these values:

public void setPrice(double price) { listPrice = price; } public void setQuantity(int qty) { qtyOnHand = qty; }

Last, but certainly not least, we need to re-define the ToString() method for the class in order to allow the item number fields to be displayed in the ListBox :

override public string ToString() { return "" + itemNum; }

Now all that’s missing is the closing brace for the class definition.

Step 3: Implement the Form’s Shown Event Handler

The first time a C# form is displayed on the screen, a Shown event will be generated. This is a perfect location to place the program instructions for initializing the ListBox. To prepare for this, first add a using System.IO directive to the start of your program. Next, create a Shown event

Chapter 10: Interacting with Text Files (^) 10-

handler for your form. At the start of this handler, you’ll need to add several variable declarations:

FileInfo inputStatus; StreamReader input; InventoryItem nextItem; string inLine; int itemNum; string description; double price; int quantity;

The actual event handler will then use the OpenFileDialog control to obtain the name of the inventory file from the keyboard user, and then transfer the data from this data file to the list box. To ensure that a file name is actually selected, and that the selected name is valid, you’ll want to place the ShowDialog() instruction for the dialog in a loop, like this:

do { openFileDialog1.FileName = ""; if (openFileDialog1.ShowDialog() != DialogResult.OK) { MessageBox.Show("Please select the inventory file!"); } else { // instructions for reading the input file will go here

} } while (true);

As it’s written, this loop will run forever. This is a fairly common usage in many programming languages; there will have to be instructions in the missing instructions, under the else statement, that provide an alternate exit – either a break or a return – that will get your program out of the loop. Assuming that this will occur, you can see that the loop will continue at least until the keyboard user hits the OK button in the OpenFileDialog control.

Actually, the initial instructions under the else statement will also test to ensure that the input file can actually be successfully opened:

inputStatus = new FileInfo(openFileDialog1.FileName); if (!inputStatus.Exists) { MessageBox.Show("The selected file wasn't found"); }

Chapter 10: Interacting with Text Files (^) 10-

**_Graphics Card

17 4201 Network Card

10_**

Once this file is in place, you should be able to run your program; after you select the input file, you should see the list of inventory numbers displayed in the ListBox control.

Step 5: Implement the Select Button

When the Select button is clicked, the keyboard user (hopefully) has first clicked on an entry in the ListBox. Assuming that this is the case, your program will need to fetch the corresponding InventoryItem from the ListBox , transfer the contents to the TextBox fields on the form, and set the Panel ’s Visible attribute to true. A few other touches will also be required to ensure that the program “behaves” normally.

First, at the very beginning of your program, just after the declaration of public partial class Form1 , you’ll need to declare a couple of variables – currentItem , of type InventoryItem , and newItem , of type bool ; newItem ’s initial value should be set to false.

Now you’re ready to define the event handler for the Select button. First, check to see if an item number was actually selected from the ListBox :

if (listBox1.SelectedIndex >= 0) {

Next, set the Enabled attributed of listBox1 to false (so the keyboard user can’t select a different item while this item is being displayed), after which you need to extract the selected item from the ListBox :

currentItem = (InventoryItem)listBox1.Items[listBox1.SelectedIndex];

Once this record has been retrieved from the ListBox , you should use the various get methods of the InventoryItem to retrieve the values from currentItem and transfer them to the TextBox controls on the form.

Finally, disable the Item Number and Description TextBox controls (so the keyboard user can’t change them), shift focus to the List Price TextBox , set the Panel ’s Visible attribute to true , and set the value of the variable newItem to false.

10-18 Introduction to Computer Programming Using C#

Step 6: Implement the New Item Button’s Handler

When the New Item button is clicked, your program needs to:

  • Clear and enable the four TextBox controls
  • Set focus to the Item Number TextBox
  • Set the Panel ’s Visible attribute to true
  • Set the value of variable newItem to true

All of the dirty work will be carried out in the OK button.

Step 7: Implement the OK Button’s Handler

When the OK button is clicked, the program needs to decide if a new inventory item is being defined, or if an existing item has been displayed, and possibly modified. First, declare four variables, corresponding to the fields of the inventory record – itemNum and qty , of type int , description , of type string , and price , of type double.

Now that these variables have been defined, you should test to see if the value of newItem is true or false ; if it’s true , you need to carry out these steps:

  • Retrieve the various values from the TextBox controls into the variables that you defined earlier
  • Create a new class variable containing these values:

currentItem = new InventoryItem(itemNum, description, price, qty);

  • Add the new inventory record to the ListBox

listBox1.Items.Add(currentItem);

If, on the other hand, the value of newItem is false , you need to carry out these steps:

  • Remove the existing item from the ListBox :

listBox1.Items.Remove(currentItem);

  • Extract the List Price and On Hand values from the TextBox controls, storing them in the variables price and qty.
  • Now transfer those values into the currentItem variable:

currentItem.setPrice(price); currentItem.setQuantity(OnHand);