Professional Documents
Culture Documents
0
Application Design
II
FunctionX Press
SUMARY
QUERYING A LIST.................................................................................................................................20
THE LANGUAGE INTEGRATED QUERY.....................................................................................................20
Introduction to Querying...................................................................................................................20
Introduction to LINQ.........................................................................................................................20
Selecting the Values...........................................................................................................................21
Using a Collection-Based Variable...................................................................................................23
Using a Criterion to Create a Sub-List..............................................................................................24
OPERATIONS ON QUERIES.......................................................................................................................27
Using Logical Conjunctions and Disjunctions.................................................................................27
Arranging the List..............................................................................................................................29
INFLUENCING A LINQ STATEMENT........................................................................................................31
Using the Primitive Types..................................................................................................................31
Using the String Class.......................................................................................................................32
LINQ AND CLASSES................................................................................................................................33
Using Built-In Classes.......................................................................................................................38
LINQ OPERATORS...................................................................................................................................38
Letting a Sub-List...............................................................................................................................38
Creating a new List............................................................................................................................40
EXPLORING THE LINQ........................................................................................................................42
THE IENUMERABLE GENERIC INTERFACE................................................................................................42
Using IEnumerable............................................................................................................................43
The Characteristics of IEnumerable..................................................................................................44
INTRODUCTION TO XML....................................................................................................................48
THE EXTENSIBLE MARKUP LANGUAGE..................................................................................................48
Overview of Files...............................................................................................................................48
Markup...............................................................................................................................................52
The Document Type Declaration (DTD)...........................................................................................52
Encoding Declaration........................................................................................................................52
Creating an XML File........................................................................................................................53
Practical Learning: Introducing XML...............................................................................................53
WRITING XML CODE..............................................................................................................................53
Writing XML Code Using XmlDocument..........................................................................................53
Practical Learning: Creating an XML Document.............................................................................54
Writing XML Code Using the Code Editor........................................................................................54
SAVING AN XML FILE............................................................................................................................55
Using the Wizard...............................................................................................................................55
Practical Learning: Creating the Root Tag.......................................................................................56
Saving a DOM Object........................................................................................................................56
OPENING AN XML FILE..........................................................................................................................57
An XML File in a Browser................................................................................................................57
Using a Style Sheet to Display an XML File in a Browser................................................................58
Programmatically Opening an XML File Using the DOM...............................................................59
Programmatically Reading an XML File..........................................................................................61
XML WELLFORMEDNESS........................................................................................................................64
Tag Creation......................................................................................................................................64
Practical Learning: Creating XML...................................................................................................65
Tag Names.........................................................................................................................................65
The Root.............................................................................................................................................66
THE STRUCTURE OF AN XML TAG.........................................................................................................69
Empty Tags........................................................................................................................................69
White Spaces......................................................................................................................................69
Nesting Tags......................................................................................................................................70
Practical Learning: Creating XML...................................................................................................70
Introduction to Querying
When using for or foreach loops on a list, you get the value or a range of
values inside of the loop. Once you exit the loop, the operation ends and you
cannot access the value(s) that was(were) isolated. If you want to get the
isolated value or an isolated list of values again, you would have to perform
the operation (create the loop), again. In some cases, you may want to
prepare and get one value, a few values, or a range of values for later use, or
to use over and over again. To do this, you would create a value or a list of
values and store that list in a variable, outside of any loop, then use the value
or the list of values when needed. As applied to the for or the foreach loop,
to perform this operation, you use a conditional statement that would
examine the list, look for the value(s), get that value or those values that
respond(s) to the condition. Any value(s) that respond(s) to the condition
is(are) then stored in the new list. This technique of examining an array is
referred to as querying.
Introduction to LINQ
To support the ability to query a list, you can use the Language Integrated
Query, abbreviated LINQ. To use LINQ in your application, you must include
the System.Core.dll assembly in your program. If you started your
application as an empty project:
On the main menu, you can click Project -> Add Reference...
In the Solution Explorer, you can right-click the name of the project and
click Add Reference...
In the Class View, you can right-click the name of the project and click
Add Reference...
In the .NET tab of the Add Reference dialog box, you can click System.Core
To query a list, you write a statement using words and operators of the LINQ.
If you have already used another query language, such as SQL, you
may be wondering about LINQ's case-sensitivity. Here is the difference.
Because the LINQ statements are written directly in the same sections
with the langue of your code, LINQ's case-sensitivity depends on that
language. For example, if you write your LINQ statement in a C#
application as we will do here or in a C++ application where the
language is case-sensitive, the LINQ's statement is case-sensitive and
must be in lowercase. If you write the statement in a case-insensitive
language such as Visual Basic or Pascal (such as CodeGear Delphi), you
can write the statement with the case of your choice.
The var keyword, the assignment operator "=", the from keyword, the in
keyword, the select keyword, and the semicolon are required.
The SubListName is a name of a new variable that will hold the list of values
produced by this operation.
The ValueHolder is the name of a variable that will be used to identify each
resulting member of this operation. This variable will be equivalent to getting
each member of the array that responds to a condition.
The List factor represents the name of the variable that you would have
created already. The List can be an array. Here is an example:
using System;
using System.Linq;
return 0;
}
}
To make the code easier to read, you can spread the select statement to
various lines. Here is an example:
using System;
using System.Linq;
return 0;
}
}
We mentioned that the List factor of our formula could be an array. It can
also be a collection-based variable; that is, a variable created from a
collection-based class. The collection class you use must implement the
IEnumerable generic interface. If you want, you can create your own class
that implements this interface but the .NET Framework provides a complete
set of classes that should suit every need. One of the built-in generic classes
of the .NET Framework is called List and you can easily use it to create a list
of values. Here is an example:
using System;
using System.Collections.Generic;
Numbers.Add(12.44);
Numbers.Add(525.38);
Numbers.Add(6.28);
Numbers.Add(2448.32);
Numbers.Add(632.04);
return 0;
}
}
After creating the collection, you can use the same LINQ formula we saw for
an array. Here is an example:
using System;
using System.Linq;
using System.Collections.Generic;
return 0;
}
}
This would produce the same result as seen earlier. Notice that, as always,
the var keyword does not indicate the type of variable it is dealing with.
As you can see, simply using a select statement as done above produces
the same list of values in the array. A criterion is a condition applied to a set
of values to find out which one(s) respond(s) to the condition or validate the
condition. When applied to an array, a criterion examines each member of the
array, finds out what member responds to it, if so, adds that member to the
from list.
return 0;
}
}
return 0;
}
}
To make the statement easier to read and less confusing, you should make it
a habit to isolate the groups of statements in parentheses:
using System;
using System.Linq;
return 0;
}
}
The above condition produced only one value because of the way the values
exist in our array. A querying operation can also produce more than one
value. Here is an example:
using System;
using System.Linq;
return 0;
}
}
Notice that the list includes only even numbers (those that are divisible by 2).
Operations on Queries
In Lesson 10, we saw that you could use logical conjunctions and
disjunctions to combine two or more Boolean expressions. These also are
available in LINQ. To do this, use the where statement to create the
expression as you see fit. Here is an expression that uses a logical disjunction
(&&) operation:
using System;
using System.Linq;
return 0;
}
}
Once again, remember that the use of parentheses makes it easier to read
the code and better understand it:
using System;
using System.Linq;
return 0;
}
}
Or better yet:
using System;
using System.Linq;
return 0;
}
}
When you create a list, you add the items in any order of your choice. For
example, if you register the students of a school, you enter their information
as it becomes available. In the same way, when you create a select
statement, the items are added to its list in the order they appear in the main
list. When treating the new list or when displaying it to the user, you may
want to arrange it in alphabetical, numerical, or in chronological order. To
support this operation, the LINQ provides the orderdy operator. To apply it,
write the operator before the select operation followed by the from list. Here
is an example:
using System;
using System.Linq;
If you apply the orderby operator simply followed by a variable, the list is
ordered alphabetically or numerically depending on the types of values in the
list. This is referred to as ascending. To re-enforce this, you can follow the
variable with the ascending keyword. Here is an example:
using System;
using System.Linq;
To arrange the list in reverse order, you can follow the variable name with the
descending keyword. Here is an example:
using System;
using System.Linq;
You can apply a where condition to the statement to select just a few values.
For example, to get a list of odd numbers arranged in numerical order, you
would write the statement as follows:
using System;
using System.Linq;
From what we have learned so far, the type of list produced by a LINQ
statement is primarily based on one of the data types we reviewed in Lesson
2 and in Lesson 3 (integers, double-precision numbers, strings, and date/time
values). In Lesson 17, we saw that the integer and numeric types are in fact
structures of the .NET Framework. As such, they are equipped with properties
and methods. In your LINQ statement, you can explore the characteristics of
those data types as you see fit.
If you create a string-based collection, you can use the properties and
methods of the String class to refine the list produced by your LINQ
statement. To do this, in the list produced by the where statement, you can
access any of the properties or you can call any desired method of the String
class using the period operator. For example, to get a list of names that start
with a certain letter, you can call the StartsWith() method as follows:
using System;
using System.Linq;
Or to get a list of names that end with a certain sub-string, you would call the
String.EndsWith() method. Here is an example:
using System;
using System.Linq;
In the same ways, to create a list of names that contain a certain sub-string,
you can call the String.Contains() method as follows:
using System;
using System.Linq;
Introduction
To create more effective LINQ statements, you can use many of the features
of the C# language we have studied in previous lessons. For example, instead
of using one of the primitive types to create your list as we have done so far,
you may want to use your own class. You can start by creating the class
normally as you see fit. Here is an example:
public class Person
{
public string FirstName;
public string LastName;
public char Gender;
Obviously before considering the class in your LINQ statement, you should
first create a collection variable that would hold its values. You can create the
list as an array. Once the list is ready, when formulating your LINQ
statement, use the from variable to access a member of the class using the
period operator. Here is an example:
using System;
using System.Linq;
In the same way, you can use any of the regular C# operators to produce
any result of your choice. For example, when studying strings, we saw that
you could use the + operator to combine strings. Here is an example:
using System;
using System.Linq;
There are two types of built-in classes you can use in your application when it
comes to LINQ. You can use any of the non-generic collection classes to
create a list of values. The other category is the generic collection classes.
LINQ Operators
Letting a Sub-List
We saw that you can get the result of a LINQ statement from the select
section. In reality, the select statement simply indicates that the result is
ready and it hands it to the other parts of the program. Instead of getting the
result directly from the select statement, you can first store it in a local LINQ
variable. This allows you to treat the result as a variable that you can then
manipulate before getting the final result.
To create a local variable in the LINQ statement, you can use the let
operator. You must use it before the select statement to hold the result. Here
is an example:
public class Program
{
static int Main(string[] args)
{
var Persons = from Pers
in People
let FullName = Pers.LastName + ", " +
Pers.FirstName
select FullName;
If you need a where condition but your let variable would be used only to
hold the final result, you can create that variable after the where statement.
Here is an example:
public class Program
{
In this case, you can create the let variable before the where statement and
you would get the same result:
using System;
using System.Linq;
To get the final result of a query, you may want to combine a few fields or
properties of each member of the result. For example, as we have seen so
far, you may want to combine the last and the first name of each result to
create a full name. Besides, or instead of, the let operator, you can use the
new operator to create such a combination.
To use the new operator, after the select keyword, type new followed by an
opening and a closing curly brackets. Inside the brackets, create an
expression as you see fit and assign it to a local variable in the curly brackets.
When accessing the result in your foreach loop, apply the period operator on
the foreach variable to access the new local variable. Here is an example:
public class Person
{
public string FirstName;
public string LastName;
public char Gender;
To make the statement easier to read, you can span it on various lines:
public class Program
{
static int Main(string[] args)
{
var Persons = from Pers
in People
select new
{
FullName = Pers.LastName +
", " +
Pers.FirstName
};
Introduction
using System;
using System.Linq;
From what we have learned so far, the only thing we know from this code is
that it gives us a list and we can display the values of this list to the console.
At times, we may want to get more information about some characteristics of
the result, not simply its values.
To assist you with exploring the characteristics of a LINQ statement, the .NET
Framework provides the IEnumerable interface.
Using IEnumerable
IEnumerable<string> Persons =
from Pers
This statement is the same as the previous except that the var keyword has
been replaced with IEnumerable<string> and it will produce the same
result we had earlier.
Console.WriteLine();
return 0;
}
}
Remember that you can still use the var keyword to declare the variable that
would hold the resulting list.
Console.WriteLine();
return 0;
}
}
There are 8 people in the list.
Press any key to continue . . .
Console.WriteLine();
Console.WriteLine("This list contains {0} men and {1}
women.",
Men, Women);
return 0;
}
}
Overview of Files
Employee
First Hourly
Last Name Date Hired
Name Salary
In Lesson 33, we saw how to create and save such a list. Here is an example
of performing these operations:
using System;
using System.IO;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public sealed class Employee
{
public string FirstName;
public string LastName;
public DateTime DateHired;
public double HourlySalary;
FileAccess.Write);
BinaryFormatter bfEmployees = new BinaryFormatter();
bfEmployees.Serialize(fsEmployees, lstEmployees);
fsEmployees.Close();
return 0;
}
}
When saving this file, we chose an extension (.mpl) at random. After saving
the values to a file, at one time, you may want to retrieve the values from
that list. Here is an example:
using System;
using System.IO;
using System.Collections;
[Serializable]
public sealed class Employee
{
public string FirstName;
public string LastName;
public DateTime DateHired;
public double HourlySalary;
}
FileAccess.Read);
BinaryFormatter bfEmployees = new BinaryFormatter();
ArrayList contractors =
(ArrayList)bfEmployees.Deserialize(fsEmployees);
fsEmployees.Close();
Console.WriteLine("======================================");
Console.WriteLine("==== Employees Records
===============");
foreach (Employee empl in contractors)
{
Console.WriteLine("--------------------------------------");
Console.WriteLine("Employee Name: {0}, {1}",
empl.LastName, empl.FirstName);
Console.WriteLine("Date Hired: {0:D}",
empl.DateHired);
Console.WriteLine("Hourly Salary: {0:C}",
empl.HourlySalary);
}
Console.WriteLine("======================================\n");
return 0;
}
}
When you create this type of file, you choose the programming environment
of your choice and save the file. You cannot open that file in just any
application. You must create and distribute the application to those who
want to be able to open a file created by your application. It could be useful
to create a type of file using any application of your choice and be able to
open that file using another type of application that you may not even know.
Introduction to XML
In this ebook, we will learn or use XML through the .NET Framework classes.
The particularity is that these classes are highly structured to take care of all
facets of XML without compromising the standards. In fact, the .NET
Framework classes are highly conform to the W3C standards in all areas.
To create an XML file, in the document, you type units of code using normal
characters of the English language. The XML document is made of units called
entities. These entities are spread on various lines of the document as you
judge them necessary and as we will learn. XML has strict rules as to how the
contents of the document should or must be structured.
Markup
The left angle bracket "<" and the right angle bracket ">" are required.
Inside of these symbols, you type a word or a group of words of your choice,
using regular characters of the English alphabet and sometimes non-readable
characters such as ?, !, or [. The combination of a left angle bracket "<", the
right angle bracket ">", and what is inside of these symbols is called a
markup. There are various types of markups we will learn.
<?xml version="1.0"?>
By default, an XML file created using Visual Studio 2005 specifies the version
as 1.0. Under the XML declaration line, you can then create the necessary
tags of the XML file.
Encoding Declaration
As mentioned already, the tags are created using characters of the alphabet
and conform to the ISO standard. This is known as the encoding declaration.
For example, most of the characters used in the US English language are
known as ASCII. These characters use a combination of 7 bits to create a
symbol (because the computer can only recognize 8 bits, the last bit is left for
other uses). Such an encoding is specified as UTF-8. There are other
standards such as UTF-16 (for wide, 2-Byte, characters).
Due to the high level of support of XML in the .NET Framework, there are
various ways you can create an XML file. The most common technique
consists of using a simple text editor. In Microsoft Windows, this would be
Notepad. An XML file is first of all a normal text-based document that has a
.xml extension. Therefore, however you create it, it must specify that
extension.
Many other applications allow creating an XML file or generating one from an
existing file. There are also commercial editors you can get or purchase to
create an XML file.
2. To save the application, on the Standard toolbar, click the Save All
button
To create XML code using XmlDocument, this class has a method called
LoadXml(). Its syntax is:
namespace CollegeParkAutoParts1
{
class Program
{
static int Main(string[] args)
{
XmlDocument docXML = new XmlDocument();
docXML.LoadXml("");
return 0;
}
}
}
In the next sections, we will see how to create an XML file with the Add New
Item dialog box. After creating the file and displaying it in the Code Editor,
you can start editing it. The Code Editor is equipped to assist you with various
options. Whenever you start typing, the editor would display one or more
options to you. Here is an example:
When different options are presented to you, you can press the arrow keys to
select an option and press Enter. You can also use the mouse to click an
Introduction
Probably the most common way to create an XML file in Microsoft Windows
consists of using Notepad or any other text editor. After opening the text
editor, you can enter the necessary lines of text. After creating the file, you
must save it. When saving it, you can include the name of the file in double-
quotes:
You can also first set the Save As Type combo box to All Files and then enter
the name of the file with the .xml extension.
To assist you with creating XML Files, Microsoft Visual C# includes an XML
File option in the Add New Item dialog box. After selecting this option, you
4. Click Add
The argument must be a valid filename and must include the .xml extension.
If you pass a string without backlashes, the file would be created in the same
Introduction
Whether you created an XML file or someone else did, you can open it easily
to view its contents. The easiest way to open an XML file is to use a text
editor, such as Notepad. Because the Code Editor has a friendlier appearance
and it is available to you, it is a better candidate. To open an XML file, on the
main menu, you can click File -> Open File..., locate the file, and click Open.
After creating an XML file, one way you can use it is to display it in a grid-
based window such as a spreadsheet. Another way you can display an XML
file is in a browser. To do this, if you see the file in Windows Explorer or in My
Documents, you can double-click it. Here is an example:
EmplNumber
{
display: block;
color: white;
font-family: Garamond, Georgia, 'Times New Roman' ,
Serif;
background-color: #990000;
}
FirstName
{
font-size: 10pt;
font-family: Verdana, Tahoma, Arial, Sans-Serif;
background-color: white;
}
LastName
{
font-size: 10pt;
font-family: Verdana, Tahoma, Arial, Sans-Serif;
background-color: white;
}
HourlySalary
{
font-size: 10pt;
color: #ff0066;
font-family: Verdana, Tahoma, Arial, Sans-Serif;
background-color: white;
display: block;
}
Then, in the first line of the XML file, you can add a line such as the following:
This version takes as argument the name or path of the file. Here is an
example of calling it:
using System;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
xmlDoc.Load("Videos.xml");
return 0;
}
}
}
In this case, the compiler would look for the file in the (Release) folder of the
current application. You can also provide a complete path to the file. Either
way, if the compiler doesn't find the file, it would throw a
FileNotFoundException exception. For this reason, it is cautious to first
check that the file exists before opening it. This can be done as follows:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
XmlDocument xmlDoc = new XmlDocument();
string strFilename = "Videos123.xml";
if (File.Exists(strFilename))
xmlDoc.Load(strFilename);
else
Console.WriteLine("The file {0} could not be
located",
strFilename);
return 0;
}
}
}
You can also use a Stream-based object to identify the file. Once the object is
ready, you can use the following version of the Load() method to open it:
public virtual void Load(Stream inStream);
namespace VideoCollection1
if (File.Exists(strFilename))
{
fsVideos = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
xmlDoc.Load(fsVideos);
}
else
Console.WriteLine("The file {0} could not be
located",
strFilename);
return 0;
}
}
}
Many of the XML files you encounter will have been created by someone else.
Still, because it is primarily a text document, you are expected to be able to
read any XML file and figure out its content, or at least most of it. As
mentioned already, you can open an XML file using a text editor such as
Notepad. After opening the file, you can start by checking the document
declaration, then move to other items.
Another way you can explore an XML file consists of programmatically reading
it. This is also referred to as parsing (the parser parses the document). To
support reading an XML file, the .NET Framework provides the abstract
XmlReader class as the ancestor of classes that can read an XML file. One of
the classes derived from XmlReader is called XmlTextReader. The
XmlTextReader class provides the ability to read the file from the left to the
right sides and from the top to the bottom sections. This class has very
important characteristics you must remember:
When using this method, pass the name of the file or its path as argument.
Here is an example:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
if (File.Exists(strFilename))
XmlTextReader rdrXml = new
XmlTextReader(strFilename);
else
Console.WriteLine("The file {0} could not be
located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
You can also identify a file using a Stream-based object. Once the object is
ready, you can pass it to the following constructor of the class:
public XmlTextReader(Stream input);
Here is an example:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
FileAccess.Read);
if (File.Exists(strFilename))
XmlTextReader rdrXml = new
XmlTextReader(fsVideos );
else
Console.WriteLine("The file {0} could not be
located",
strFilename);
fsVideos.Close();
Console.WriteLine();
return 0;
}
}
}
To actually read the file, the XmlTextReader is equipped with the Read()
method whose syntax is:
public override bool Read();
As you may suspect, this method only tells you that it successfully read an
item. It doesn't tell you what it read. As stated already, the XmlTextReader
scans a file in a left-right-top-down approach. When it has read something, it
returns true. If it didn't or couldn't read something, it returns false. Therefore,
you can call it to read an item. If it succeeds, it returns true. After reading
that item, you can call it again to move to the next item. If there is a next
item, it reads it and returns true. But, if there is no next item, the Read()
method would not be able to read it and it would return false. In other words,
you can ask the Read() method to continuously read the items as long as it
returns true. Once it cannot read an item, you can ask it to stop. To perform
this exercise, you can use either a while or a do...while loop. This would
be done as follows:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
FileStream fsVideos = new FileStream(strFilename,
FileMode.Open,
do {
// Read an item and return true
// Continue reading as long as ...
} while (rdrXml.Read() == true); // ... as long as
Read() returns true
// Once Read() returns false, STOP!!!
fsVideos.Close();
Console.WriteLine();
return 0;
}
}
}
XML Wellformedness
Tag Creation
After specifying the value of the markup, you must close it: this is a rule not
enforced in HTML but must be respected in XML to make it "well-formed". To
close a tag, use the same formula of creating a tag with the left angle bracket
"<", the tag, and the right angle bracket ">" except that, between < and the
tag, you must type a forward slash. The formula to use is:
<tag>some value</tag>
The item on the left side of the "some value" string, in this case <tag>, is
called the opening or start-tag. The item on the right side of the "some value"
string, in this case </tag>, is called the closing or end-tag. Like<tag> is a
markup, </tag> also is called a markup.
namespace CollegeParkAutoParts1
{
class Program
{
static int Main(string[] args)
{
XmlDocument docXML = new XmlDocument();
docXML.LoadXml("<?xml version=\"1.0\"
encoding=\"utf-8\"?>");
return 0;
}
}
}
Tag Names
When creating your tags, there are various rules you must observe with
regards to their names. Unlike HTML, XML is very restrictive with its rules. For
example, unlike HTML but like C/C++/C#, XML is case-sensitive. This means
that CASE, Case, and case are three different words. Therefore, from now on,
you must pay close attention to what you write inside of the < and the >
delimiters.
Besides case sensitivity, there are some rules you must observe when naming
the tags of your markups:
The name of a tag cannot start with xml, XML or any combination of X
(uppercase or lowercase), followed by M (uppercase or lowercase), and
followed by L (uppercase or lowercase)
In future sections, we will learn that, with some markups, you can include
non-readable characters between the angle brackets. In fact, you will need to
pay close attention to the symbols you type in a markup. We will also see
how some characters have special meaning.
The Root
Every XML document must have one particular tag that, either is the only tag
in the file, or acts as the parent of all the other tags of the same document.
This tag is called the root. Here is an example of a file that has only one tag:
<rectangle>A rectangle is a shape with 4 sides and 4 straight
angles</rectangle>
To correct this type of error, you can change one of the existing tags to act
as the root. Here is an example:
Alternatively, you can create a tag that acts as the parent for the other tags.
Here is an example:
<geometry><rectangle>A rectangle is a shape with 4 sides and 4
straight angles
</rectangle><square>A square is a rectangle whose 4 sides are
equal</square></geometry>
Empty Tags
We mentioned that, unlike HTML, every XML tag must be closed. We also saw
that the value of a tag was specified on the right side of the right angle
bracket of the start tag. In some cases, you will create a tag that doesn't
have a value or, may be for some reason, you don't provide a value to it.
Here is an example:
<dinner></dinner>
This type of tag is called an empty tag. Since there is no value in it, you may
not need to provide an end tag but it still must be closed. Although this
writing is allowed, an alternative is to close the start tag itself. To do this,
between the tag name and the right angle bracket, type an empty space
followed by a forward slash. Based on this, the above line can be written as
follows:
<dinner />
White Spaces
In the above example, we typed various items on the same line. If you are
creating a long XML document, although creating various items on the same
line is acceptable, this technique can make it (very) difficult to read. One way
you can solve this problem is to separate tags with empty spaces. Here is an
example:
<title>The Distinguished Gentleman</title> <director>Jonathan
Lynn</director> <length>112 Minutes</length>
Yet a better solution consists of typing each item on its own line. This would
make the document easier to read. Here is an example:
<title>The Distinguished Gentleman</title>
<director>Jonathan Lynn</director>
All these are possible and acceptable because the XML parser doesn't
consider the empty spaces or end of line. Therefore, to make your code
easier to read, you can use empty spaces, carriage-return-line-feed
combinations, or tabs inserted in various sections. All these are referred to as
white spaces.
Nesting Tags
Most XML files contain more than one tag. We saw that a tag must have a
starting point and a tag must be closed. One tag can be included in another
tag: this is referred to as nesting. A tag that is created inside of another tag is
said to be nested. A tag that contains another tag is said to be nesting.
Consider the following example:
<Smile>Please smile to the camera</Smile>
<English>Welcome to our XML Class</English>
<French>Bienvenue à notre Classe XML</French>
In this example, you may want the English tag to be nested in the Smile tag.
To nest one tag inside of another, you must type the nested tag before the
end-tag of the nesting tag. For example, if you want to nest the English tag in
the Smile tag, you must type the whole English tag before the </Smile> end
tag. Here is an example:
<Smile>Please smile to the camera<English>Welcome to our XML
Class</English></Smile>
To make this code easier to read, you can use white spaces as follows:
<smile>Please smile to the camera
<English>Welcome to our XML Class</English>
</smile>
When a tag is nested, it must also be closed before its nesting tag is closed.
Based on this rule, the following code is not valid:
<Smile>Please smile to the camera
<English>Welcome to our XML Class
</Smile>
</English>
The rule broken here is that the English tag that is nested in the the Smile tag
is not closed inside the Smile tag but outside.
1. To apply the concept of nesting XML tags, change the Parts.xml file as
follows:
namespace CollegeParkAutoParts1
{
class Program
{
static int Main(string[] args)
{
XmlDocument docXML = new XmlDocument();
docXML.LoadXml("<?xml version=\"1.0\"
encoding=\"utf-8\"?>" +
"<Employees><Employee>" +
"<EmplNumber>48-705</EmplNumber>" +
"<FirstName>John</FirstName>" +
"<LastName>Cranston</LastName>" +
"<HourlySalary>16.48</HourlySalary>"
+
"</Employee><Employee>" +
"<EmplNumber>22-688</EmplNumber>" +
"<FirstName>Annie</FirstName>" +
"<LastName>Loskar</LastName>" +
"<HourlySalary>12.50</HourlySalary>"
+
"</Employee><Employee>" +
"<EmplNumber>85-246</EmplNumber>" +
"<FirstName>Bernie</FirstName>" +
"<LastName>Christo</LastName>" +
"<HourlySalary>22.52</HourlySalary>"
+
docXML.Save("Employees.xml");
return 0;
}
}
}
5. Open Windows Explorer and display the contents of the folder of the
current project.
Notice the presence of the parts.xml and the Employees.xml files
An XML Node
<Format>DVD</Format>
<Rating>R</Rating>
</Video>
<Video>
<Title>Her Alibi</Title>
<Director>Bruce Beresford</Director>
<Length>94 Mins</Length>
<Format>DVD</Format>
<Rating>PG-13</Rating>
</Video>
<Video>
<Title>Chalte Chalte</Title>
<Director>Aziz Mirza</Director>
<Length>145 Mins</Length>
<Format>DVD</Format>
<Rating>N/R</Rating>
</Video>
</Videos>
An XML file appears as an upside-down tree: it has a root (in this case
<Videos>), it can have branches (in this case <Video>), and it can have
leaves (an example in this case is <Title>). As we have seen so far, all of
these objects are created using the same technique: a tag with a name (such
as <Title>) and an optional value. Based on their similarities, each of these
Elements Fundamentals
Introduction
In the previous lesson, we saw that every XML file must have a root and we
mentioned that you could call the XmlDocument.DocumentElement
property to access it. This property is of type XmlElement and, to access it,
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
Console.WriteLine("{0}", elm);
}
else
Console.WriteLine("The file {0} could not be
located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
if (File.Exists(strFilename))
{
XmlTextReader rdrXml = new
XmlTextReader(strFilename);
do {
switch (rdrXml.NodeType)
{
case XmlNodeType.Element:
break;
}
}while (rdrXml.Read());
}
else
Console.WriteLine("The file {0} could not be
located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
7. Access the main folder of the current project and, inside of it, open a
sub-folder of the same name (it should be opened already). In the sub-
folder of the same name, open the bin sub-folder followed by the
8. Click Save
The name of an element is the string that represents the tag. For example, in
<Director>, the word Director is the name of the element. An element must
have at least a start-tag. All of the tags we have seen so far were created as
elements. When creating your elements, remember to follow the rules we
defined for names.
The XmlElement class is equipped with the Name property that can be used
to identify an existing element. Here is an example of accessing it:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
Console.WriteLine();
return 0;
}
}
}
Notice that Videos is returned as the name of the root element of the file. If
calling the Read() method of an XmlTextReader object to scan a file, when
you get to an element, you can find out its Name identity by accessing it.
Here is an example:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
XmlTextReader rdrXml = new
XmlTextReader(strFilename);
do {
switch (rdrXml.NodeType)
{
case XmlNodeType.Element:
Console.WriteLine("{0}",
rdrXml.Name);
break;
}
}while (rdrXml.Read());
}
else
Console.WriteLine();
return 0;
}
}
}
The value of an element is the item displayed on the right side of the start-
tag. It is also called the text of the element. In the case of
<Director>Jonathan Lynn</Director>, the "Jonathan Lynn" string is the
value of the Director element. To support the text or value of an element, the
XmlElement class is equipped with the Value property.
While the value of one element can be a number, the value of another
element can be a date. Yet another element can use a regular string as its
value. Consider the following example:
<?xml version="1.0" encoding="utf-8" ?>
<Employees>
<Employee>
<FullName>Lydia Thomason</FullName>
<Salary>25.64</Salary>
<DepartmentID>1</DepartmentID>
</Employee>
<Employee>
Notice that the Salary elements contain numbers that look like currency
values and the DepartmentID elements use an integer as value.
If you are using an XmlTextReader object to scan a file, when the Read()
method gets to an element, you can find out what its value is by accessing
this property. Here is an example:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
XmlTextReader rdrXml = new
XmlTextReader(strFilename);
do {
switch (rdrXml.NodeType)
{
case XmlNodeType.Text:
Console.WriteLine("{0}",
rdrXml.Value);
break;
}
}while (rdrXml.Read());
}
else
Console.WriteLine("The file {0} could not be
located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
namespace CollegeParkAutoParts2
{
class Program
{
static int Main(string[] args)
{
FileStream fsCPAP = null;
string strFilename = "makes.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
fsCPAP = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
XmlTextReader rdrXml = new
XmlTextReader(fsCPAP);
do
{
switch (rdrXml.NodeType)
{
case XmlNodeType.Text:
Console.WriteLine("Make: {0}",
rdrXml.Value);
break;
Console.WriteLine();
return 0;
}
}
}
Empty Elements
An element may not have a value but only a name. Consider the following
example:
<?xml version="1.0" encoding="utf-8"?>
<Videos>
<Video>
<Title>The Distinguished Gentleman</Title>
<Director>Jonathan Lynn</Director>
</Video>
</Videos>
In this case, the Video element doesn't have a value. It is called an empty
element. When a tag is empty, the Value property of its XmlElement object
would return an empty value. Consider the following code:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
Console.WriteLine();
return 0;
}
}
}
Because the Videos node doesn't have its own value, its Value property
returns an empty string.
Besides these obvious types of values, you may want to display special
characters as values of elements. Consider the following example:
<?xml version="1.0" encoding="utf-8" ?>
<Employees>
<Employee>
<FullName>Sylvie <Bellie> Aronson</FullName>
<Salary>25.64</Salary>
<DepartmentID>1</DepartmentID>
</Employee>
<Employee>
<FullName>Bertrand Yamaguchi</FullName>
<Salary>16.38</Salary>
<DepartmentID>4</DepartmentID>
</Employee>
</Employees>
If you try using this XML document, for example, if you try displaying it in a
browser, you would, receive an error:
Code Symbol Code Symbol Code Symbol Code Symbol Code Symbol
There are still other codes to include special characters in an XML file.
3. To save the file, on the main menu, click File -> Save models.xml As...
4. Access the main folder of the current project and, inside of it, open a
sub-folder of the same name (it should be selected already). In the sub-
folder of the same name, open the bin sub-folder followed by the
Release sub-folder. Click Save
namespace CollegeParkAutoParts2
{
class Program
{
static int Main(string[] args)
{
FileStream fsCPAP = null;
string strFilename = "models.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
fsCPAP = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
XmlTextReader rdrXml = new
XmlTextReader(fsCPAP);
Console.WriteLine();
return 0;
}
}
}
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
Console.WriteLine("{0}", elm.InnerText);
}
else
Console.WriteLine("The file {0} could not be
located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
Notice that this property produces all values of the children of a node in one
block. We already saw how to access each value of the children of a node by
calling the XmlTextReader.Read() method and get its Text.
If you want to get a node, its markup, its child(ren) and its(their) markup(s),
you can access its XmlNode.OuterXml property which is declared as follows:
public virtual string OuterXml{get};
Here is an example:
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
Console.WriteLine("{0}", elm.OuterXml);
}
else
Console.WriteLine("The file {0} could not be
located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
If you want only the markup(s) of the child(ren) excluding the parent, access
its XmlNode.InnerXml property which is declared as follows:
public virtual string InnerXml{get};
Here is an example:
Introduction
using System;
using System.IO;
namespace VideoCollection
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
XmlNodeList lstVideos = elm.ChildNodes;
Console.WriteLine();
return 0;
}
}
}
You can also use the Count property in a for loop to visit the members of
the collection.
namespace VideoCollection
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
XmlNodeList lstVideos = elm.ChildNodes;
Console.WriteLine(lstVideos[2]);;
}
else
Console.WriteLine("The file {0} could not be
located",
strFilename);
Console.WriteLine();
return 0;
}
}
}
You can also use the Item() method to get the same result. Using a for
loop, you can access each node and display the values of its children as
follows:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
XmlNodeList lstVideos = elm.ChildNodes;
Console.WriteLine();
return 0;
}
}
}
namespace VideoCollection
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
XmlNodeList lstVideos = elm.ChildNodes;
Console.WriteLine();
return 0;
}
Not all nodes have children, obviously. For example, the Title node of our
Videos.xml file doesn't have children. To find out whether a node has
children, check its HasChildNodes Boolean property that is declared as
follows:
public virtual bool HasChildNodes{get};
If a node is a child, to get its parent, you can access its ParentNode
property.
The children of a nesting node are also recognized by their sequence. For our
Videos.xml file, the first line is called the first child of the DOM. This would
be:
<?xml version="1.0" encoding="utf-8"?>
After identifying or locating a node, the first node that immediately follows it
is referred to as its first child. In our Videos.xml file, the first child of the first
Video node is the <Title>The Distinguished Gentleman</Title> element. The
first child of the second Video> node is <Title>Her Alibi</Title>.
In the .NET Framework, the first child of a node can be retrieved by accessing
the XmlNode.FirstChild property declared as follows:
public virtual XmlNode FirstChild{get};
In the following example, every time the parser gets to a Video node, it
displays the value of it first child:
using System;
using System.IO;
using System.Xml;
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elm = xmlDoc.DocumentElement;
XmlNodeList lstVideos = elm.ChildNodes;
Console.WriteLine();
return 0;
}
}
}
In this example, we started our parsing on the root node of the document. At
times, you will need to consider only a particular node, such as the first child
of a node. For example, you may want to use only the first child of the root.
To get it, you can access the FirstChild property of the DocumentElement
object of the DOM. Once you get that node, you can then do what you judge
necessary. In the following example, only the values of the child nodes of the
first child of the root are displayed:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection
{
class Program
{
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlNode node =
xmlDoc.DocumentElement.FirstChild;
XmlNodeList lstVideos = node.ChildNodes;
Console.WriteLine();
return 0;
}
}
}
namespace VideoCollection
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
// Locate the root node and
// get a reference to its first child
XmlNode node =
xmlDoc.DocumentElement.FirstChild;
// Create a list of the child nodes of
// the first node under the root
XmlNodeList lstVideos = node.ChildNodes;
Console.WriteLine();
return 0;
}
}
}
namespace VideoCollection
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
// Locate the root node and
// get a reference to its first child
XmlNode node =
xmlDoc.DocumentElement.FirstChild;
// Create a list of the child nodes of
Console.WriteLine();
return 0;
}
}
}
As opposed to the first child, the child node that immediately precedes the
end-tag of the parent node is called the last child. To get the last child of a
node, you can access its XmlNode.LastChild property that is declared as
follows:
public virtual XmlNode LastChild{get};
The child nodes that are nested in a parent node and share the same level
are referred to as siblings. Consider the above file: Director, CastMembers,
Obviously, to get a sibling, you must first have a node. To access the sibling
of a node, you can use its XmlNode.NextSibling property, which is declared
as follows:
public virtual XmlNode NextSibling{get};
Fundamental Operations
Introduction
So far, to create an XML element, we were directly typing in a file. When such
a file has been created and saved, it is ready to be processed. Here is an
example of a file named Videos.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Videos>
<Title>The Distinguished Gentleman</Title>
</Videos>
In some applications, you will want the user to provide you with the
necessary value(s) to create an element. Fortunately, XmlDocument, the
XmlNode, and the XmlElement classes provide all the necessary properties
and methods to perform the routine operations of an XML file, an element,
or a node. The operations include locating a node, adding a new element, or
deleting a node.
7. Access the main folder of the current project and, inside of it, open a
sub-folder of the same name (it should be opened already). In the sub-
folder of the same name, open the bin sub-folder followed by the
Release sub-folder. Click Save
10. To save the file, on the main menu, click File -> Save models.xml As...
11. Access the main folder of the current project and, inside of it, open a
sub-folder of the same name (it should be selected already). In the sub-
folder of the same name, open the bin sub-folder followed by the
Release sub-folder. Click Save
Using this method, to create a new element, call it and pass it the name of
the element. For example, imagine you want to add a new Title element to
the above file. You would start with code as follows:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elmNew =
xmlDoc.CreateElement("Title");
}
Console.WriteLine();
return 0;
}
}
}
In order to add the new element to the file, you must specify its position in
the tree: whether it would be the first or the last node, whether you want to
position it before or after a node of your choice. For example, if you want to
add a new Title element to the above file, it would be considered a child of
the root, that is, a child of the XmlDocument.DocumentElement property. In
the previous lesson, we learned how to get a reference to the root node.
To support the positions of existing nodes, the XmlNode class, which is the
ancestor of all XML nodes of the .NET Framework, provides various
appropriate methods. One of these methods is AppendChild(), which is used
to add an element as the last child of its parent. The syntax of the
XmlNode.AppendChild() method is:
When calling this method, pass the XmlNode object you had previous created.
After adding the node, if you want the file to keep it, you should save it. Here
is an example:
using System;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
Console.WriteLine();
return 0;
}
}
}
If you want the element to have a value, the XmlDocument class provides the
CreateTextNode() method. This method returns an XmlText value. The
syntax of this method is:
public virtual XmlText CreateTextNode(string text);
This method takes as argument the string that would constitute the value of
the element. Before calling it, you should have used the
XmlNode.AppendChild() method to create a node. Calling this method on
the LastChild node of the one that called the AppendChild() would specify
the value of the new node. Here is an example:
using System;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
xmlDoc.Save(strFilename);
}
Console.WriteLine();
return 0;
}
}
}
Notice that the root, Videos, has a repetitive child named Video. This Video
child has its own child named Title. Imagine that you want to add a new
Video node that has a child. To do this, first create an empty Video node as
a child of the root. We learned earlier how to do that:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
Console.WriteLine();
return 0;
}
}
}
After creating the new child of the root, initialize the grand child with the
desired name (the name doesn't have to be one of the existing names) and a
value (which is optional if you don't want the new node to have a value).
Once the new node is ready, append it as the last child of the root. If this
new node has a value, append its XmlText object as the LastChild of the
LastChild of the root. Here is an example of how you would do this:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
elmRoot = xmlDoc.DocumentElement;
elmNew = xmlDoc.CreateElement("Title");
XmlText txtVideo = xmlDoc.CreateTextNode("Her
Alibi");
elmRoot.LastChild.AppendChild(elmNew);
elmRoot.LastChild.LastChild.AppendChild(txtVideo);
xmlDoc.Save(strFilename);
}
Console.WriteLine();
return 0;
}
}
}
To this:
<?xml version="1.0" encoding="utf-8"?>
<Videos>
<Video>
<Title>The Distinguished Gentleman</Title>
</Video>
<Video>
<Title>Basic Instinct</Title>
</Video>
<Video>
<Title>Her Alibi</Title>
</Video>
</Videos>
<Format>DVD</Format>
<Rating>R</Rating>
</Video>
<Video>
<Title>Her Alibi</Title>
<Director>Bruce Beresford</Director>
<Length>94 Mins</Length>
<Format>DVD</Format>
<Rating>PG-13</Rating>
</Video>
</Videos>
The root, Videos, has a child named Video. The Video node has many child
nodes. By now, we know how to add a child to the root. We also saw how to
add a grand child with value to the root. To had many (grand) children to a
node, first build the node, add it to the root, then continuously add the
necessary nodes, one at a time, including its name and its optional value. This
would be done as follows:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
elmRoot = xmlDoc.DocumentElement;
elmNew = xmlDoc.CreateElement("Title");
elmRoot.LastChild.LastChild.AppendChild(txtVideo);
elmNew = xmlDoc.CreateElement("Director");
txtVideo = xmlDoc.CreateTextNode("Roland
Emmerich");
elmRoot.LastChild.AppendChild(elmNew);
elmRoot.LastChild.LastChild.AppendChild(txtVideo);
elmNew = xmlDoc.CreateElement("Length");
txtVideo = xmlDoc.CreateTextNode("124 Minutes");
elmRoot.LastChild.AppendChild(elmNew);
elmRoot.LastChild.LastChild.AppendChild(txtVideo);
elmNew = xmlDoc.CreateElement("Format");
txtVideo = xmlDoc.CreateTextNode("DVD");
elmRoot.LastChild.AppendChild(elmNew);
elmRoot.LastChild.LastChild.AppendChild(txtVideo);
elmNew = xmlDoc.CreateElement("Rating");
txtVideo = xmlDoc.CreateTextNode("PG-13");
elmRoot.LastChild.AppendChild(elmNew);
elmRoot.LastChild.LastChild.AppendChild(txtVideo);
xmlDoc.Save(strFilename);
}
Console.WriteLine();
return 0;
}
}
}
Using the same approach, you can add children to children of children, and so
on.
1. To give the user the ability to create a new car make, change the
Program.cs file as follows:
using System;
using System.Xml;
namespace CollegeParkAutoParts3
{
public static class Program
{
public static void CreateNewMake()
{
string strNewMake = "";
docXMLFile.DocumentElement.LastChild.AppendChild(txtXML);
2. To give the user the ability to add a new car model, create the following
function in the file:
using System;
using System.Xml;
namespace CollegeParkAutoParts2
{
public static class Program
{
public static void CreateNewMake()
{
. . . No Change
}
if (indexNewModel >= 0)
docXMLFile.DocumentElement.AppendChild(elmXML);
docXMLFile.DocumentElement.LastChild.AppendChild(txtXML);
docXMLFile.Save("models.xml");
}
}
namespace CollegeParkAutoParts2
{
public static class Program
{
public static void CreateNewMake()
{
. . . No Change
}
Console.WriteLine("=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=");
Console.WriteLine("=-= College Park Auto-Parts =-
=");
Console.WriteLine("=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=");
do
{
switch (mnuChoice)
{
case '1':
CreateNewMake();
break;
case '2':
CreateNewModel();
break;
default:
break;
}
Console.WriteLine();
} while((mnuChoice == '1') ||
(mnuChoice == '2'));
Console.WriteLine("\nThank you!");
return 0;
}
}
}
Makes
Dodge
Ford
Honda
Toyota
Models
Corolla
Dakota
Focus
Escort
Camry
Crown Victoria
Expedition
Integra
Neon
The above Videos.xml file had only one level under the root and no child
element of the root had children. Suppose you have the following version of
the file:
<?xml version="1.0" encoding="utf-8"?>
<Videos>
<Video>
<Title>The Distinguished Gentleman</Title>
<Director>Jonathan Lynn</Director>
<Length>112 Minutes</Length>
<Format>DVD</Format>
<Rating>R</Rating>
</Video>
<Video>
<Title>Her Alibi</Title>
<Director>Bruce Beresford</Director>
<Length>94 Mins</Length>
<Format>DVD</Format>
Imagine that you want to add a Video element. You have a choice of adding
one, more, or all child elements of the Video node. To perform this operation,
one solution you can use is to "build" all child elements of the Video element,
then add the node as a whole. To support this technique, we saw earlier that
the XmlNode.InnerXml property comprises a node, its markup, its children
and their markup. This means that you can create the child nodes with their
markup(s) as a string and assign that string to an XmlNode.InnerXml string.
To do this, you would need the set version of the InnerXml property. It is
declared as follows:
public virtual string InnerXml{get; set;}
Here is an example that adds a complete new Video node to the above XML
file:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlElement elmXML =
xmlDoc.CreateElement("Video");
string strNewVideo = "<Title>Other People's
Money</Title>" +
"<Director>Alan
Brunstein</Director>" +
"<Length>114
Minutes</Length>" +
"<Format>VHS</Format>" +
"<Rating>PG-
13</Rating>";
elmXML.InnerXml = strNewVideo;
xmlDoc.DocumentElement.AppendChild(elmXML);
xmlDoc.Save("Videos.xml");
}
Console.WriteLine();
Inserting an Element
Locating an Element
So far, we have been adding nodes quite randomly, that is, without much
precision. In some cases, you may want to perform an operation on an
existing and particular node. For example, you may want to change the value
of a node, you may want to add a new child node to an existing node, etc.
Before taking any of these actions, you must be able to locate or identify the
desired element.
To assist you with finding a node, the XmlDocument class is equipped with
the GetElementByTagName() method which is overloaded with two versions.
One of the syntaxes used is:
public virtual XmlNodeList GetElementsByTagName(string name);
This method takes as argument a string. The string must be the Name of a
node. If at least one node that holds that name exists in the file, this method
returns a collection of the nodes with that name. If there is no node with that
name, the collection is returned empty and there is no exception.
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
Console.WriteLine();
return 0;
}
}
}
Once you have a list of the nodes of a particular criterion, you can then act as
you see fit. For example, For example, you can look for a particular node that
holds a text of your choice. Here is an example:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
Imagine you want to add a list of actors of the Her Alibi video. The first action
to take is to locate the video, which you can do by calling the
XmlDocument.GetElementsByTagName() method applied to a collection of
nodes whose names are Video. From this list of nodes, you can look for the
node whose value is "Her Alibi". Once you have found this element, get a
reference to its parent. Then add the new node as the LastChild object of
its parent. This can be done as follows:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
Console.WriteLine();
return 0;
}
}
}
This code creates an empty element. If you want to create an element that
includes a value, create its text and add that text as the LastChild of its
parent. Here is an example:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
XmlText txtCatetory =
xmlDoc.CreateTextNode("Comedy");
elmParent.LastChild.AppendChild(txtCatetory);
// Save the file
xmlDoc.Save(strFilename);
}
}
}
Console.WriteLine();
return 0;
}
}
}
Using the same approach combined with what we learned about adding an
item, you can add a new element that itself has child nodes. Here is an
example:
using System;
using System.IO;
using System.Xml;
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
elmVideo.LastChild.LastChild.AppendChild(txtActor);
elmVideo.LastChild.LastChild.AppendChild(txtActor);
elmNew = xmlDoc.CreateElement("Actor");
txtActor = xmlDoc.CreateTextNode("Emmy
Rossum");
elmVideo.LastChild.AppendChild(elmNew);
elmVideo.LastChild.LastChild.AppendChild(txtActor);
elmNew = xmlDoc.CreateElement("Actor");
txtActor = xmlDoc.CreateTextNode("Dash
Mihok");
elmVideo.LastChild.AppendChild(elmNew);
elmVideo.LastChild.LastChild.AppendChild(txtActor);
Console.WriteLine();
return 0;
}
}
}
You can also insert one or more elements as children of an existing node after
locating that node. Here is an example:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
elmVideo.LastChild.AppendChild(elmNew);
// Specify the text of the new
node
elmVideo.LastChild.LastChild.AppendChild(txtActor);
elmVideo.LastChild.AppendChild(elmNew);
elmVideo.LastChild.LastChild.AppendChild(txtActor);
elmNew =
xmlDoc.CreateElement("Actor");
txtActor =
xmlDoc.CreateTextNode("William Daniels");
elmVideo.LastChild.AppendChild(elmNew);
elmVideo.LastChild.LastChild.AppendChild(txtActor);
Console.WriteLine();
return 0;
}
}
}
4. To save the file, on the main menu, click File -> Save parts.xml As...
5. Access the main folder of the current project and, inside of it, open a
sub-folder of the same name (you should be in that folder already). In
the sub-folder of the same name, open the bin sub-folder followed by
the Release sub-folder. Click Save
namespace CollegeParkAutoParts3
{
public static class Program
{
public static void CreateNewMake()
{
. . . No Change
}
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
=");
Console.WriteLine("New Car Part Summary");
elmXML.InnerXml = strNewPart;
docXML.DocumentElement.AppendChild(elmXML);
docXML.Save("Parts.xml");
}
Console.WriteLine("=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=");
Console.WriteLine("=-= College Park Auto-Parts =-
=");
Console.WriteLine("=o=o=o=o=o=o=o=o=o=o=o=o=o=o=o=");
do
{
try
{
Console.WriteLine("=-= Main Menu =-=");
Console.WriteLine("1 - Add New Car Make");
Console.WriteLine("2 - Add New Car Model");
Console.WriteLine("3 - Add New Part");
Console.WriteLine("0 - Exit");
Console.Write("Your Choice: ");
mnuChoice = char.Parse(Console.ReadLine());
switch (mnuChoice)
{
case '1':
CreateNewMake();
break;
case '2':
CreateNewModel();
break;
case '3':
AddNewPart();
break;
default:
break;
}
Console.WriteLine();
} while((mnuChoice == '1') ||
(mnuChoice == '2') ||
(mnuChoice == '3') );
Console.WriteLine("\nThank you!");
return 0;
}
}
}
Unit
Year Make Model Part Name
Price
2004 Dodge Neon Master Cylinder w/o ABS w/2 Wheel 102.95
Instead of simply adding a new node at the end of child nodes, you can
specify any other position you want. For example, you may want the new
node to precede an existing child node. To support this operation, the
XmlNode class provides the InsertBefore() method. Its syntax is:
The first argument of this method is the new node that will be added. The
second argument is the sibling that will succeed the new node. Consider the
following version of our Videos.xml file:
Imagine you want to create a new Category element below the Director
element whose name is Adrian Lyne. You can first get a list of videos. Inside
of each video, check the nodes and find out whether the video has a Director
node whose text is Adrian Lyne. Once you find that node, you can add the
new element after it. Here is an example:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
elmNew.InnerText = "Drama";
// Stop
break;
}
}
}
}
Console.WriteLine();
return 0;
}
}
}
In the same way, you can insert a new node after a child of a child (of a child
of a child of a child) of any node.
If you want to new node to be positioned after an existing child node, you
can call the XmlNode.InsertAfter() method. Its syntax is:
public virtual XmlNode InsertAfter(XmlNode newChild, XmlNode
refChild);
Node Removal
If you have a node you don't want or don't need anymore in the file, you can
delete it. To delete a node, the XmlNode class provides the RemoveChild()
method. Its syntax is:
public virtual XmlNode RemoveChild(XmlNode oldChild);
This method takes as argument the node to delete. If the node exists, it
would be deleted and the method would return it. If the node doesn't exist,
nothing would happen. To effectively use this method, you should first locate
the particular node you want to delete. You can look for it using any of the
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
string strFilename = "Videos.xml";
XmlDocument xmlDoc = new XmlDocument();
if (File.Exists(strFilename))
{
xmlDoc.Load(strFilename);
// Stop
break;
}
}
}
}
Console.WriteLine();
To delete all child nodes of a node, you can call the XmlNode.RemoveAll()
method. Its syntax is:
public virtual void RemoveAll();
When called, this method will remove all child nodes, if any, of their parent
node.
Fundamentals of Attributes
Introduction
When studying XML elements we saw how they constituted the main objects
of an XML document. We also saw that an element could be nested inside of
another element. Instead of nesting an element, you can transform the
nested element into being part of the nesting element and thereby giving
away its element qualities. This is the basis of an attribute.
8. To save the file, on the main menu, click File -> Save continents.xml
As...
9. Access the main folder of the current project and, inside of it, open a
sub-folder of the same name (you should be in that folder already). In
the sub-folder of the same name, open the bin sub-folder followed by
the Release sub-folder. Click Save
Creating an Attribute
An attribute should have a value that can be used to distinguish it. To specify
the name of an attribute, assign a value as a string to its name. Imagine you
have an ISBN element as a child of a Video element as follows:
<Video>
<ISBN>0-7888-1623-3</ISBN>
</Video>
In this case, since ISBN is simply a child of the Video element, you can
change the ISBN element to become an attribute of the Video element as
follows:
<Video ISBN="0-7888-1623-3">
While a certain element may have an attribute, a sibling element with the
same name may not have an attribute or may have a completely different
type of attribute. Here is an XML file with attributes in some elements:
<?xml version="1.0" encoding="utf-8" ?>
<Videos>
<Video ISBN="0-7888-1623-3">
<Title Screenplay="Marty Kaplan">The Distinguished
Gentleman</Title>
<Director>Jonathan Lynn</Director>
<Actors>
</Actors>
<Length>112 Minutes</Length>
<Format>DVD</Format>
<Rating>R</Rating>
</Video>
<Video>
<Title WrittenBy="Charlie Peter">Her Alibi</Title>
<Director>Bruce Beresford</Director>
<Length>94 Mins</Length>
<Format>DVD</Format>
<Rating>PG-13</Rating>
</Video>
</Videos>
We also saw that we could close an element locally as follows: <Video />. If
you create an attribute in an empty element, you can also close it by typing
the indicative forward slash before the right angle bracket and after an empty
space. Here is an example:
<Video ISBN="0-7888-1623-3" />
The first argument is the name of the new attribute and the second argument
will be its text. Before adding an attribute, you should first identify its parent
element. Here is an example that adds an attribute to the root element:
using System;
using System.IO;
using System.Xml;
namespace VideoCollection
{
public static class Exercise
{
if (File.Exists(strFilename))
{
// Open the XML file
docXML.Load(strFilename);
From the above Videos.xml file, this code would result in:
<?xml version="1.0" encoding="utf-8"?>
<Videos FileDesc="Personal Video Collection">
<Video ISBN="0-7888-1623-3">
<Title Screenplay="Marty Kaplan">The Distinguished
Gentleman</Title>
<Director>Jonathan Lynn</Director>
<Actors>
</Actors>
<Length>112 Minutes</Length>
<Format>DVD</Format>
<Rating>R</Rating>
</Video>
<Video>
<Title WrittenBy="Charlie Peter">Her Alibi</Title>
<Director>Bruce Beresford</Director>
<Length>94 Mins</Length>
<Format>DVD</Format>
<Rating>PG-13</Rating>
</Video>
</Videos>
namespace VideoCollection
{
public static class Exercise
{
private static void CreateAttribute()
{
string strFilename = "Videos.xml";
XmlDocument docXML = new XmlDocument();
if (File.Exists(strFilename))
{
// Open the XML file
docXML.Load(strFilename);
docXML.Save("Videos.xml");
}
}
From the above Videos.xml file, this code would result in:
<?xml version="1.0" encoding="utf-8"?>
<Videos FileDesc="Personal Video Collection">
<Video ISBN="0-7888-1623-3">
<Title Screenplay="Marty Kaplan">The Distinguished
Gentleman</Title>
<Director>Jonathan Lynn</Director>
<Actors>
</Actors>
<Length>112 Minutes</Length>
<Format>DVD</Format>
<Rating>R</Rating>
</Video>
<Video ISBN="0-7907-3900-3">
<Title WrittenBy="Charlie Peter">Her Alibi</Title>
<Director>Bruce Beresford</Director>
<Length>94 Mins</Length>
<Format>DVD</Format>
<Rating>PG-13</Rating>
</Video>
</Videos>
namespace CountriesStatistics1
{
public static class Program
{
private static void CreateContinent()
{
if (File.Exists(strFilename))
{
string strContinent = null;
try
{
fsStatistics = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlDocContinents.Load(fsStatistics);
}
finally
{
fsStatistics.Close();
}
xmlDocContinents.CreateElement("Continent");
xmlDocContinents.DocumentElement.AppendChild(xmlNewContinent);
Once an attribute has been created, to identify the element it belongs to, you
can access its XmlAttribute.OwnerElement property. This property
produces an XmlElement value.
Attribute Removal
If an element has an attribute you don't want or that you don't need
anymore, you can delete that attribute. You have various options, two are
available through the XmlElement class.
When calling this method, pass the attribute object as argument. If the
attribute exists, it would be removed and the method would return the
deleted attribute. If the attribute doesn't exist, nothing would happen.
Introduction
So far, we have used only one attribute per element. Fortunately, you can
create as many attributes as you judge necessary in an element. To do this,
type the name of each attribute, assign it a double-quoted string and
separate the attribute from the next with an empty space. Here is an example
of an element with different attributes:
<Video ISBN="0-7888-1623-3" ScreenRatio="Standard"
SoundtrackAvailable="True" />
2. To save the project, on the Standard toolbar, click the Save All button
7. To save the file, on the main menu, click File -> Save continents.xml
As...
8. Access the main folder of the current project and, inside of it, open a
sub-folder of the same name (you should be in that folder already). In
the sub-folder of the same name, open the bin sub-folder followed by
the Release sub-folder. Click Save
Access to an Attribute
To access an attribute by its position in the collection, you can use the
XmlNamedNodeMap.Item() method.
In the first video, the name of the screenplay writer is stored at index 1. In
the second video, the name of the screenplay writer is stored at index 0. In
this case, it may not be a good item to use the index to locate an attribute.
Fortunately, the second version of the overloaded
XmlAttributeCollection.ItemOf[] property has the following syntax:
With this version, you can explicitly specify the name of the attribute that you
want.
namespace CountriesStatistics2
{
public static class Program
{
if (File.Exists(strFilename))
{
string strContinent = null;
try
{
fsWorldStats = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlWorldStats.Load(fsWorldStats);
}
finally
{
fsWorldStats.Close();
}
xmlWorldStats.GetElementsByTagName("Continent");
attr.Attributes["Population"].InnerText);
}
}
}
Attribute Addition
Whether using its index or name, after accessing an attribute, you can
manipulate it as you see fit. For example, you can change or delete it using
the same techniques we saw to perform on an individual attribute.
As mentioned already, the attributes are stored as a list. Because you have
complete access to this list and the positions of its attributes, when creating
or adding a new attribute, you can specify the position the new attribute
should have in the collection. To create an attribute as the first in an element,
you can call the XmlAttributeCollection.Prepend() method. Its syntax
is:
public virtual XmlAttribute Prepend(XmlAttribute node);
Another technique you can use consists of locating an attribute first. Once
you have one, to create a new attribute before it, you can call the
XmlAttributeCollection.InsertBefore() method. Its syntax is:
To add a new attribute after the current one, you can call the
XmlAttributeCollection.InsertAfter() method. Its syntax is:
To add an attribute at the end of the list of attributes of an element, you can
call the XmlAttributeCollection.Append() method. Its syntax is:
public virtual XmlAttribute Append(XmlAttribute node);
namespace CountriesStatistics2
{
if (File.Exists(strFilename))
{
try
{
fsWorldStats = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlWorldStats.Load(fsWorldStats);
}
finally
{
fsWorldStats.Close();
}
xmlWorldStats.GetElementsByTagName("Continent");
Console.WriteLine("\n===================================");
Console.WriteLine(" =-= Continents =-=");
Console.WriteLine("===================================");
Console.WriteLine("Name\tArea\t\tPopulation");
Console.WriteLine("===================================");
foreach (XmlNode attr in lstContinents)
{
Console.WriteLine("{0}\t{1}\t{2}",
attr.Attributes["Name"].InnerText,
attr.Attributes["Area"].InnerText,
attr.Attributes["Population"].InnerText);
Console.WriteLine("-----------------------------------");
}
}
}
if (File.Exists(strFilename))
{
try
{
fsContinents = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlDocContinents.Load(fsContinents);
}
finally
{
fsContinents.Close();
}
}
xmlDocContinents.DocumentElement.AppendChild(xmlNewContinent);
switch (choice)
{
case 1:
ShowContinents();
break;
case 2:
CreateNewContinent();
break;
}
Console.WriteLine();
return 0;
}
}
}
===================================
=-= Continents =-=
===================================
Name Area Population
===================================
===================================
=-= Continents =-=
===================================
Name Area Population
===================================
Africa 30,065,000 807,419,000
-----------------------------------
Europe 9,938,000 730,916,000
-----------------------------------
North America 24490000 514600000
-----------------------------------
4. To allow the user to create a new country, change the file as follows:
using System;
using System.IO;
using System.Xml;
if (File.Exists(strFilename))
{
try
{
fsWorldStats = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlWorldStats.Load(fsWorldStats);
}
finally
{
fsWorldStats.Close();
}
xmlWorldStats.GetElementsByTagName("Continent");
Console.WriteLine("\n===================================");
Console.WriteLine(" =-= Continents =-=");
Console.WriteLine("===================================");
Console.WriteLine("Name\tArea\t\tPopulation");
Console.WriteLine("===================================");
foreach (XmlNode attr in lstContinents)
{
Console.WriteLine("{0}\t{1}\t{2}",
attr.Attributes["Name"].InnerText,
attr.Attributes["Area"].InnerText,
attr.Attributes["Population"].InnerText);
Console.WriteLine("-----------------------------------");
}
}
}
if (File.Exists(strFilename))
{
try
{
fsContinents = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlDocContinents.Load(fsContinents);
}
finally
{
fsContinents.Close();
}
}
xmlDocContinents.DocumentElement.AppendChild(xmlNewContinent);
if (File.Exists(strFilename))
{
try
{
fsContinents = new FileStream(strFilename,
FileMode.Open,
FileAccess.Read);
// Open the XML file
xmlDocContinents.Load(fsContinents);
}
finally
{
fsContinents.Close();
}
}
xmlDocContinents.GetElementsByTagName("Continent");
xmlDocContinents.CreateElement("Country");
elmNewCountry.SetAttribute("CountryName", strCountry);
lstContinents[i].AppendChild(elmNewCountry);
break;
}
}
}
}
do
{
Console.WriteLine(" =-= Main Menu =-=");
Console.WriteLine("1 - Display Continents");
Console.WriteLine("2 - Create New Continent");
Console.WriteLine("3 - Create New Country");
Console.WriteLine("0 - Quit");
Console.Write("Your Choice? ");
choice = int.Parse(Console.ReadLine());
switch (choice)
{
case 1:
ShowContinents();
break;
Console.WriteLine();
return 0;
}
}
}
===================================
=-= Continents =-=
===================================
Name Area Population
===================================
Africa 30,065,000 807,419,000
-----------------------------------
Europe 9,938,000 730,916,000
-----------------------------------
North America 24490000 514600000
-----------------------------------
Enter a new continent: Asia
Enter the area of the continent: 43810582
Enter the population of the continent: 3902404193
===================================
=-= Continents =-=
===================================
Name Area Population
===================================
Africa 30,065,000 807,419,000
-----------------------------------
Europe 9,938,000 730,916,000
-----------------------------------
North America 24490000 514600000
-----------------------------------
Asia 43810582 3902404193
===================================
=-= Continents =-=
===================================
Name Area Population
===================================
Africa 30,065,000 807,419,000
-----------------------------------
Europe 9,938,000 730,916,000
-----------------------------------
North America 24490000 514600000
-----------------------------------
Asia 43810582 3902404193
-----------------------------------
Enter the desired continent: Europe
Enter the name of the country: Italy
Enter the area of the country: 301230
Enter the population of the country: 58751711
Enter the capital of the country: Rome
Enter the Internet code of the country: it
=-= Main Menu =-=
1 - Display Continents
2 - Create New Continent
3 - Create New Country
0 - Quit
Your Choice? 0
Attribute Removal
Using the list of attributes of an element, you can delete one or all attributes
of an element. Since the attributes are stored in a collection, you can locate
the undesired attribute by its index and then delete it. To do this, you can call
the XmlAttributeCollection.RemoveAt() method. Its syntax is:
public virtual XmlAttribute RemoveAt(int i);
This method expects the index of the attribute that needs to be removed. As
mentioned for the XmlAttributeCollection.ItemOf indexed property, to
efficiently use this RemoveAt() method, you should know the exact index of
the attribute, otherwise, you may access and therefore delete the wrong
attribute. An alternative is to explicitly identify the attribute you want to
delete. To do this, you can call the XmlAttributeCollection.Remove()
method. Its syntax is:
public virtual XmlAttribute Remove(XmlAttribute node);
Introduction
To differentiate the various nodes that belong to an XML file, they are
classified by their category. As mentioned earlier, the types of node are listed
in the XmlNodeType enumerator.
Comments
Between <!-- and -., any text in that section is considered a comment and
you can include anything you want. Both sections of the comment use two
dashes, not more, not less. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<Videos>
<Video>
<!-- In this collection, we will keep each title "as i"
-.
<Title>The Distinguished Gentleman</Title>
<Director>Jonathan Lynn</Director>
<Length>112 Minutes</Length>
<Format>DVD</Format>
<Rating>R</Rating>
</Video>
CDATA
Except for comments, the parser is used to "scan" the whole XML file to
analyze it. Every tag is then interpreted. As we mentioned already, the value
of each tag can be displayed in a browser between its opening and its
closing tag, and the browser uses different font styles to make a distinction.
When creating some tags and some sections of the file, you may want the
parser to consider those particular tags and sections as regular text. That is,
you may want the parser to treat a certain tag and its value as if it were
regular text even though it is created as an XML file.
To prevent the parser from interpreting a tag regularly but to treat that tag
and its value as regular text, you can create it in a CDATA section. To do this,
create a section that starts with <![CDATA[, followed by anything you want,
and ending with ]]>. The formula used is:
<![CDATA[ Blah Blah Blah ]]>
Between <![CDATA[ and ]]>, you can type anything, including one or more
normal XML tags. Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<Videos>
<![CDATA[<VideoCollection>Personal Collection of
Movies</VideoCollection>]]>
<Video>
<Title>The Distinguished Gentleman</Title>
<Director>Jonathan Lynn</Director>
<Length>112 Minutes</Length>
<Format>DVD</Format>
<Rating>R</Rating>
</Video>
<Video>
<Title>Her Alibi</Title>
<Director>Bruce Beresford</Director>
<Length>94 Mins</Length>
<Format>DVD</Format>
<Rating>PG-13</Rating>
</Video>
</Videos>
To programmatically create a
CDATA section, you can call the
XmlDocument.CreateCDataSection() method. Its syntax is:
This method receives the content of the CDATA section as argument. If the
method succeeds, which it usually does, it returns an XmlCDataSection
value.
XML Serialization
Thanks to its flexibility and platform independent way of dealing with values,
XML is always a prima candidate for value serialization. Unlike strict object
serialization, but like the techniques of file processing we reviewed earlier,
XML considers the value members of an object, such as its fields and
properties, for serialization. This means that XML doesn't allow serializing an
A Set of Data
Introduction
An item that is part of a list is called datum, with the plural being data, but
data is also used for singular. The group of items, or data, that makes up a
list is referred to as a set of data.
If you are planning to use a DataSet object from more than one method or
event, you can declare it globally, that is, in the class of a form. Here is an
example:
using System;
using System.Data;
public VideoCollection()
{
dsVideoCollection = new DataSet();
}
}
When creating a set of data, you can name it. This would allow you to refer
to the list later on by its formal name. To create such a set, you can use the
second constructor whose syntax is:
public DataSet(string dataSetName);
This constructor takes as argument the formal name of the set. The name
can be anything but it must respect the rules of names of the C++ language.
Here is an example:
using System;
using System.Data;
public VideoCollection()
{
dsVideoCollection = new DataSet("Videos");
}
}
Tables Fundamentals
Introduction to Tables
Imagine you have a list of movie directors and you want to group their names
into a list. Here is an example:
Rob Reiner, Jonathan Lynn, Bruce Beresford, Jonathan Demme, Adrian Lyne
This is a one-dimensional list like a simple array. While working on this list,
you may decide to create a video collection and make the above items into a
formal list. A typical movie provides such information as its length, its rating,
the year it was released, etc. To create such a list, you would group items by
categories. One category may contain the titles of the videos. Another
category may contain the names of the directors, and so on.
To better organize a list, you may create each category, then enter the value of
each category that corresponds to a particular video. Here is an example:
138
A Few Good Men Rob Reiner 1992 VHS R
Minutes
120
Fatal Attraction Adrian Lyne 1987 VHS R
Minutes
129
The Manchurian Candidate Jonathan Demme 2004 DVD R
Minutes
namespace VideoCollection1
{
public class Video
{
public DataSet dsVideoCollection;
public Video()
{
dsVideoCollection = new DataSet("Videos");
}
}
}
Creating a Table
public VideoCollection()
{
dsVideoCollection = new DataSet("Videos");
If you are planning to refer to the table from more than one method, you
should declare it globally. Here is an example:
using System;
using System.Data;
public VideoCollection()
{
dsVideoCollection = new DataSet("Videos");
The name of the DataTable variable is required when creating a table. This
name will be used by you and the compiler to identify the table. In some
cases, you may want the table to hold an object name that you would want
to use later as we will see with some methods. To provide a formal name to a
table when creating it, you can use the second constructor of the DataTable
class. Its syntax is:
public DataTable(string tableName);
public VideoCollection()
{
dsVideoCollection = new DataSet("Videos");
public VideoCollection()
{
dsVideoCollection = new DataSet("Videos");
Introduction
The tables that belong to a DataSet object are stored in a property called
Tables. The DataSet.Tables property is an object of type
DataTableCollection. The DataTableCollection is a class that provides
everything you need to add, locate, or manage any table that belongs to a
DataSet object.
public VideoCollection()
{
dsVideoCollection = new DataSet("Videos");
tblRatings = dsVideoCollection.Tables.Add("Ratings");
tblActors = dsVideoCollection.Tables.Add("Actors");
tblFormats = dsVideoCollection.Tables.Add("Formats");
}
coll.ShowTables();
Console.WriteLine();
return 0;
You can use this approach to identity a table and then perform a desired
operation on it.
This method can be used to add a new table that uses the default name.
Here is an example:
using System;
using System.Data;
public VideoCollection()
{
dsVideoCollection = new DataSet("Videos");
tblRatings = dsVideoCollection.Tables.Add();
}
}
If this is the first table added to the collection, it would be named Table1. The
second version of the DataTableCollection.Add() method uses the
following syntax:
public virtual void Add(DataTable table);
public VideoCollection()
{
dsVideoCollection = new DataSet("Videos");
tblRatings = dsVideoCollection.Tables.Add();
}
}
This second version of the method requires that you create a DataTable
object first and the table probably has a name. Alternatively, if you want to
add a table using its formal name, you can use the third version of this
method. Its syntax is:
public virtual DataTable Add(string name);
This version works like the first except that, instead of the default name (such
as Table1, Table2, etc), it lets you specify the desired name of the new table.
Here are examples:
using System;
using System.Data;
public VideoCollection()
{
dsVideoCollection = new DataSet("Videos");
tblRatings = dsVideoCollection.Tables.Add();
tblActors = dsVideoCollection.Tables.Add("Actors");
tblFormats = dsVideoCollection.Tables.Add("Formats");
}
}
Instead of adding one table at a time, you can create a list of tables and then
add it to the DataSet.Tables collection. To support this operation, the
DataTableCollection is equipped with the AddRange() method. Its syntax
is:
public void AddRange(DataTable[] tables);
public Video()
{
dsVideoCollection = new DataSet("Videos");
tblRatings =
dsVideoCollection.Tables.Add("Ratings");
tblActors = dsVideoCollection.Tables.Add("Actors");
tblFormats =
dsVideoCollection.Tables.Add("Formats");
}
}
}
After creating the tables that are part of an application, before performing
any operation on a table, you must first retrieve its reference. This can be
done by locating the particular desired table from the collection.
To use this property, enter the object name of the table in the square
brackets of the DataTableCollection[] property. Here is an example:
using System;
using System.Data;
public VideoCollection()
{
dsVideoCollection = new DataSet("Videos");
tblRatings = dsVideoCollection.Tables.Add();
tblActors = dsVideoCollection.Tables.Add("Actors");
tblFormats = dsVideoCollection.Tables.Add("Formats");
}
}
DataTable tbl =
coll.dsVideoCollection.Tables["Directors"];
Instead of locating a table by its name, you can use its index from the
collection. To do this, you can use the second version of the
DataTableCollection[] property. Its syntax is:
using System;
using System.Data;
public VideoCollection()
{
dsVideoCollection = new DataSet("Videos");
tblRatings = dsVideoCollection.Tables.Add();
tblActors = dsVideoCollection.Tables.Add("Actors");
tblFormats = dsVideoCollection.Tables.Add("Formats");
}
}
If you provide an index below or beyond the number of tables in the set, the
compiler would throw an IndexOutOfRangeException exception. To avoid
this, you can request the index of the table. To do this, call the
DataTableCollection.IndexOf() method. It is overloaded in two versions.
One of the versions takes as argument the variable name of the table. The
syntax of this method is:
public virtual int IndexOf(DataTable table);
public VideoCollection()
{
dsVideoCollection = new DataSet("Videos");
tblRatings = dsVideoCollection.Tables.Add();
tblActors = dsVideoCollection.Tables.Add("Actors");
tblFormats = dsVideoCollection.Tables.Add("Formats");
}
coll.LocateTable();
return 0;
}
}
Instead of using the variable name of the table, you can locate it using its
formal name. To do this, call the following version of the IndexOf() method:
When the tables of a DataSet have been created, you can get their list as an
array using the DataTableCollection.List property. This property returns
an ArrayList type of list.
This method expects the object name of a table as argument. If the table
exists in the collection, this method returns true. Here is an example:
using System;
using System.Data;
public VideoCollection()
{
dsVideoCollection = new DataSet("Videos");
tblRatings = dsVideoCollection.Tables.Add();
tblActors = dsVideoCollection.Tables.Add("Actors");
tblFormats = dsVideoCollection.Tables.Add("Formats");
}
}
if( coll.dsVideoCollection.Tables.Contains("Actors") )
Console.WriteLine("The Actors table exists");
else
Console.WriteLine();
if
(coll.dsVideoCollection.Tables.Contains("VideoTypes"))
Console.WriteLine("The VideoTypes table exists");
else
Console.WriteLine("The VideoTypes table does not
exist");
Console.WriteLine();
return 0;
}
}
1. To show a list of the tables in the DataSet object, change the Video.cs
file as follows:
using System;
using System.Data;
namespace VideoCollection1
{
public class Video
{
public DataSet dsVideoCollection;
public Video()
{
dsVideoCollection = new DataSet("Videos");
tblRatings =
dsVideoCollection.Tables.Add("Ratings");
tblActors = dsVideoCollection.Tables.Add("Actors");
tblFormats =
dsVideoCollection.Tables.Add("Formats");
}
namespace VideoCollection1
{
class Program
{
static int Main(string[] args)
{
Video vdo = new Video();
vdo.ShowTables();
Console.WriteLine();
return 0;
}
}
}
Deleting a Table
If you happen to have a table you don't need anymore or whose role is
undefined in your application, you can delete that table. This operation is
supported by the DataTableCollection.Remove() method that is
overloaded with two versions. To delete a table using its variable declared
name, you can use the following version:
public void Remove(DataTable table);
This version expects the name that was used to declare the DataTable
object. If the table exists in the DateSet.Tables collection, it would be
deleted. Here is an example:
using System;
using System.Data;
dsVideoCollection.Tables.Remove(tblVideoCategories);
Console.WriteLine();
coll.ShowTables();
Console.WriteLine();
return 0;
}
}
This method expects the formal name of the table as argument. If a table
exists under that name, it would be deleted. Here is an example:
using System;
using System.Data;
dsVideoCollection.Tables.Remove("Categories");
Console.WriteLine();
coll.ShowTables();
Console.WriteLine();
return 0;
}
}
If the table exists in the collection, it may not allow the user to delete it. To
find out whether a table can be deleted, call the
DataTableCollection.CanRemove() method. Its syntax is:
namespace VideoCollection1
{
public class Video
{
public DataSet dsVideoCollection;
public Video()
{
dsVideoCollection = new DataSet("Videos");
tblRatings =
dsVideoCollection.Tables.Add("Ratings");
DeleteTable("Ratings");
Console.WriteLine();
ShowTables();
Console.WriteLine();
DeleteTable("Types");
Console.WriteLine();
ShowTables();
Console.WriteLine();
}
}
}
Calling this method would remove all DataTable objects of the DataSet.
Introduction
138
A Few Good Men Rob Reiner 1992 1 R
Minutes
120
Fatal Attraction Adrian Lyne 1987 1 R
Minutes
129
The Manchurian Candidate Jonathan Demme 2004 2 R
Minutes
using System.Data;
namespace VideoCollection2
{
public class Video
{
private DataSet dsVideoCollection;
public Video()
{
dsVideoCollection = new DataSet("VideoCollection");
using System;
namespace VideoCollection2
{
public class Program
{
static int Main(string[] args)
{
Video vdo = new Video();
vdo.ShowTables();
return 0;
}
}
}
6. To save the file, on the Standard toolbar, click the Save All button
Creating a Column
To create a column, you can first declare a variable of type DataColumn. The
DataColumn class is equipped with five constructors. The default constructor
allows you to create a column without giving details. Here is an example:
using System;
using System.Data;
If you are planning to reference the column from more than one method, you
should declare it at a class level. Here is an example:
public VideoCollection()
{
colCategoryID = new DataColumn();
}
}
To distinguish them, each column must have a specific and unique name. The
name of a column allows you and the compiler to identify a particular
column. The name must follow the rules of variables in C#. To specify the
object name of a column, when creating it, you can use the second
constructor whose syntax is:
public DataColumn(string name);
public VideoCollection()
{
colCategoryID = new DataColumn("CategoryID");
}
}
public VideoCollection()
{
colCategoryID = new DataColumn("CategoryID");
Introduction
To make a column part of a table, you must add it to the table's collection of
columns. The DataColumnCollection class is equipped with a method called
Add() that allows you to add a column to the table.
When called, this create creates a new column and return it. The compiler
would assign a default name to the column. If this is the first column, it would
be named Column1. If it is the second column, it would be named Column2,
and so on. You can still specify or change the name of a column created with
the above version of the Add() method. To do this, assign the desired string
to the DataColumn.ColumnName. Here is an example:
using System;
using System.Data;
public VideoCollection()
If you want to specify the name of the new column when calling the
DataColumnCollection.Add() method, use the following version:
This method takes as argument the name of the new column and returns that
new column. Here is an example:
using System;
using System.Data;
public VideoCollection()
{
colCategoryID = new DataColumn("CategoryID");
colCategory = new DataColumn();
colCategory.ColumnName = "Category";
public VideoCollection()
{
colCategoryID = new DataColumn("CategoryID");
colCategory = new DataColumn();
colCategory.ColumnName = "Category";
namespace VideoCollection2
{
public class Video
{
private DataSet dsVideoCollection;
public Video()
{
dsVideoCollection = new DataSet("VideoCollection");
dsVideoCollection.Tables.Add(tblActors);
Instead of adding one column (at a time) to a table, you can first create an
array of columns and add that array to the collection of columns. To do this,
you can call the DataColumnCollection.AddRange() method. Its syntax is:
public void AddRange(DataColumn[] columns);
public VideoCollection()
{
dsVideoCollection = new DataSet("Video");
dtVideos = new DataTable("Video");
dtVideos.Columns.AddRange(colVideos);
dsVideoCollection.Tables.Add(dtVideos);
}
}
If you create an application that allows the user to enter some values for the
above list of videos, you would wish the user enter the right type of data
under each column. To assist you with, the DataColumn class allows you to
specify an appropriate or desired data type for each column. Just as done in
other regular applications, the data types of a table allow its columns to
accept or reject inappropriate values. Although we saw that the name was
the most important aspect of a column, in reality, a data type is also required.
To supports data types for a column, the DataColumn class relies on the
following .NET Framework structures we have used in previous lessons:
Boolean, Byte , Char, DateTime, Decimal, Double, Int16, Int32, Int64,
SByte, Single, String, TimeSpan, UInt16, UInt32, and UInt64. The
DataColumn class can also support an array of Byte values, as in Byte[], for
a column.
When creating a new column, if you don't specify its data type, it is assumed
to be a string and the string data type is automatically applied to it. To
specify the data type of a column, you have two main alternatives. When
declaring a column, to specify its data type, you can initialize the DataColumn
variable using the third constructor of the class. Its syntax is:
public DataColumn(string columnName, Type dataType);
To specify a column's data type, select one from the Type class of the System
namespace by calling the Type.GetType() method. The GetType() method
is overloaded with three versions. The first version has the following syntax:
public static Type GetType(string typeName);
This method expects as argument a valid data type defined in the .NET
Framework. The data type must be retrieved from the Type class of the
System namespace. The name of the data type must be qualified with a
period operator. Here is an example:
public VideoCollection()
{
colCategoryID = new DataColumn("CategoryID",
Type.GetType("System.Int32"));
}
}
public VideoCollection()
{
colCategoryID = new DataColumn("CategoryID",
Type.GetType("System.Int32"));
Remember that there are various techniques you can use to create a column
by specifying its name and its data type.
1. To create columns with data types and specify the data types of existing
columns, change the Video.cs file as follows:
using System;
using System.Data;
namespace VideoCollection2
{
public class Video
{
public Video()
{
dsVideoCollection = new DataSet("VideoCollection");
Type.GetType("System.DateTime"));
tblActors.Columns.Add(colDateOfBirth);
dsVideoCollection.Tables.Add(tblActors);
Type.GetType("System.String"));
tblVideos.Columns.Add(colDirector);
Type.GetType("System.String"));
tblVideos.Columns.Add(colLength);
Type.GetType("System.Int16"));
tblVideos.Columns.Add(colFormat);
Type.GetType("System.Byte"));
dsVideoCollection.Tables.Add(tblVideos);
}
Columns Maintenance
Introduction
You are probably now familiar with the relationships among the data set, the
table and the columns. Just in case:
1. A table belongs to a data set and not the contrary. Also, you can create
and use a data set without creating a table
When using the information stored in a table we will learn when studying
records, sometimes you will need to identify the table that owns a particular
column you are accessing. This information can be provided by the Table
property of the DataColumn class.
Identifying a Column
namespace VideoCollection2
{
public class Video
{
private DataSet dsVideoCollection;
public Video()
{
dsVideoCollection = new DataSet("VideoCollection");
Type.GetType("System.DateTime"));
tblActors.Columns.Add(colDateOfBirth);
dsVideoCollection.Tables.Add(tblActors);
dsVideoCollection.Tables.Add(tblVideos);
}
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("Video Collection - Tables");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("Video Collection - {0} Columns",
table);
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
2. give the user the ability to choose, access the Program.cs file and
change it as follows:
using System;
do
{
try
{
Console.WriteLine("\nWhat do you want to
do?");
Console.WriteLine("1. Show the tables");
Console.WriteLine("2. Show the columns of a
table");
Console.WriteLine("0. Quit");
Console.Write("Your Choice: ");
answer = char.Parse(Console.ReadLine());
Console.WriteLine("=========================\n");
}
catch (FormatException)
{
Console.WriteLine("Invalid Choice!");
}
switch (answer)
{
case '1':
vdo.ShowTables();
break;
case '2':
Console.WriteLine("Here are the
available tables");
vdo.ShowTables();
try
{
Console.Write("Enter the table whose columns you want to
review: ");
choiceTable =
char.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("Invalid
answer!");
}
if (choiceTable == '1')
vdo.ShowColumns("Actors");
else if (choiceTable == '2')
default:
break;
}
} while((answer == '1') ||
(answer == '2'));
return 0;
}
}
}
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Video Collection - Tables
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
1. Actors
2. Videos
----------------------------
Deleting Columns
If you happen to have an undesired column in a table, you can delete it. To
perform this operation, the DataColumnCollection class provides the
Remove() method. This method is overloaded in two versions. One of them
uses the following syntax:
public void Remove(string name);
This method expects the name of a column as argument. If the table has that
column, the column would be deleted. Here is an example:
using System;
using System.Data;
namespace VideoCollection
{
public static class Program
{
static DataSet dsVideos;
Type.GetType("System.String"));
tblVideos.Columns.Add(colDirector);
Type.GetType("System.String"));
tblVideos.Columns.Add(colLength);
Type.GetType("System.Int16"));
tblVideos.Columns.Add(colFormat);
Type.GetType("System.Byte"));
tblVideos.Columns.Add(colRating);
dsVideos.Tables.Add(tblVideos);
}
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("Video Collection - Tables");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("Video Collection - {0} Columns",
table);
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
int i = 1;
DataTable tbl = dsVideos.Tables["Video"];
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("Video Collection\nColumns of the
Video table");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
tbl.Columns.Remove("Length");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("Video Collection\nColumns of the
Video table");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
i = 1;
foreach (DataColumn col in tbl.Columns)
Console.WriteLine("{0}. {1}", i++,
col.ColumnName);
Console.WriteLine("----------------------------");
return 0;
}
}
}
namespace VideoCollection
{
public static class Program
{
. . . No Change
int i = 1;
DataTable tbl = dsVideos.Tables["Video"];
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("Video Collection\nColumns of the
Video table");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
if (tbl.Columns.Contains("Length"))
{
tbl.Columns.Remove("Length");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-
=");
Console.WriteLine("Video Collection\nColumns of
the Video table");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-
=");
i = 1;
foreach (DataColumn col in tbl.Columns)
Console.WriteLine("{0}. {1}", i++,
col.ColumnName);
Console.WriteLine("----------------------------");
}
Even if the table contains that column, it may not allow the column to be be
deleted. For this reason, you should first check that the table allows that the
column be deleted. To assist you with checking this, the
DataColumnCollection class is equipped with the CanRemove() method. Its
syntax is:
public bool CanRemove(DataColumn column);
The columns of a table are arranged in an indexed list with the first (the most
left) column at index 0, the second (from left) at index 1, and so on. To
delete a column based on its index, you can call the
DataColumnCollection.RemoveAt() method. Its syntax is:
The index of the column is passed to this method. When calling this method,
make sure you pass a valid index that is an integer greater than or equal to 0
but less than the DataColumnCollection.Count - 1. Here is an example:
using System;
using System.Data;
namespace VideoCollection
{
public static class Program
{
. . . No Change
int i = 1;
DataTable tbl = dsVideos.Tables["Video"];
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("Video Collection\nColumns of the
Video table");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
tbl.Columns.RemoveAt(4);
i = 1;
foreach (DataColumn col in tbl.Columns)
Console.WriteLine("{0}. {1}", i++,
col.ColumnName);
Console.WriteLine("----------------------------");
return 0;
}
}
}
After this method has been called, all columns from the table are deleted.
Introduction to Records
In our description of tables, we saw that a table was made of one or various
columns that represented some categories of data. Here is an example of a
table with a few columns:
using System;
using System.Data;
namespace VideoCollection
dsVideos.Tables.Add(tblVideos);
}
return 0;
}
}
}
After creating such a table and its columns, you (actually the user) can enter
values in the table to make it a valuable list. Filling up a table with values is
referred to as data entry.
2. To save the application, on the Standard toolbar, click the Save All
button
To support the various records that belong to a table, the DataTable class is
equipped with a property called Rows. The DataTable.Rows property is an
When performing data entry and while doing it on a record, the record has a
status that can be identified by the DataRow.RowState property which is a
value based on the DataRowState enumerator.
Before adding a new record to a table, you must let the table know. This is
done by calling the DataTable.NewRow() method. Its syntax is:
public DataRow NewRow();
namespace VideoCollection
{
public static class Program
{
. . . No Change
Data Entry
Introduction
namespace VideoCollection
{
public static class Program
{
. . . No Change
rowVideo[0] = "GT-682";
rowVideo[1] = "A Few Good Men";
rowVideo[2] = "Rob Reiner";
rowVideo[3] = "138 Minutes";
rowVideo[4] = 1992;
rowVideo[5] = "R";
}
After specifying the value(s) of the column(s), you must add it (them) to the
table. To do this, you must call the Add() method of the
DataRowCollection class. This method is overloaded with two versions. One
of the versions uses the following syntax:
public void Add(DataRow row);
This method expects the name of the record as argument, which would be
the value returned by a previous call to the DataTable.NewRow() method.
Here is an example:
namespace VideoCollection
{
public static class Program
{
. . . No Change
rowVideo[0] = "GT-682";
rowVideo[1] = "A Few Good Men";
rowVideo[2] = "Rob Reiner";
rowVideo[3] = "138 Minutes";
rowVideo[4] = 1992;
rowVideo[5] = "R";
tblVideos.Rows.Add(rowVideo);
}
When the record has been added to the table, the record has a status of
DataRowState.Added.
Here is an example:
using System;
using System.Data;
namespace VideoCollection
{
public static class Program
{
. . . No Change
tblVideos.Rows.Add(arrRecord);
}
namespace VideoCollection
{
public static class Program
{
. . . No Change
tblVideos.Rows.Add(rowVideo);
}
After you have created a table and its columns but before adding any row,
the number of the table's record is set to 0. Every time you add a new record,
the number of records is incremented by 1. To get the number of records that
a table contains, access the Count property of its DataRowCollection. The
Count property is inherited from the InternalDataCollectionBase class,
which is the parent of many collection classes.
Introduction
When the application closes, unfortunately, all the information created while
the application was running is lost. While the first goal of an application is to
create one or more lists used to organize information, probably the essence of
an information-based or a data-based application is to preserve information
created when using the application and be able to retrieve that information
the next time the application runs, without re-creating it.
Of course, there are various ways you can save the information created in an
application. As the DataSet class is equipped with all the necessary features
used to create and manage one or more lists of an application, it also
provides a very high level of saving the information stored in its lists.
Once a new record has been created or when the lists of the data set have
been populated with information, you can save the changes and store them
to a computer file. By default, the DataSet class is equipped to save its lists
as XML. To support this, it is equipped with the WriteXml() method that is
overloaded with various versions. One of the versions of this method uses the
following syntax:
public void WriteXml(string fileName);
This method takes as argument the name of the new file or its path. When
providing this argument, make sure you add the .xml extension to the file
name. This method does two things: it checks the existence of the file and it
saves it. If the file you provided is not found in the path, this method creates
it and writes the record(s) to it. If the file exists already, this method opens it,
finds its end, and appends the new data at the end. This makes the method
very useful and friendly.
namespace VideoCollection
{
public static class Program
{
static DataSet dsVideos;
Type.GetType("System.String"));
tblVideos.Columns.Add(colDirector);
Type.GetType("System.String"));
tblVideos.Columns.Add(colLength);
Type.GetType("System.Int16"));
tblVideos.Columns.Add(colYear);
Type.GetType("System.String"));
tblVideos.Columns.Add(colRating);
rowVideo[0] = "GT-682";
rowVideo[1] = "A Few Good Men";
rowVideo[2] = "Rob Reiner";
rowVideo[3] = "138 Minutes";
rowVideo[4] = 1992;
rowVideo[5] = "R";
tblVideos.Rows.Add(rowVideo);
dsVideos.WriteXml(strDirectory + @"\videos.xml");
}
return 0;
}
}
}
If you want to control whether the file should be created from scratch,
instead of passing the name of the file to this method, first create a stream
using a Stream-derived class such as FileStream. This allows specifying the
necessary options using the FileMode, FileAccess, and FileShare
properties. Once the stream is ready, pass it to the WriteXml() method
because it is also overloaded with the following syntax:
public void WriteXml(Stream stream);
Here is an example:
using System;
using System.IO;
using System.Data;
namespace VideoCollection
{
public static class Program
{
. . . No Change
FileMode.Create,
FileAccess.Write);
object[] rowVideo = { "MM-258", "Fatal Attraction",
"Adrian Lyne",
"120 Minutes", 1987, "R" };
tblVideos.Rows.Add(rowVideo);
dsVideos.WriteXml(fsVideos);
fsVideos.Close();
}
return 0;
}
}
}
If you want the file to be formatted as text, you can use the following version
of the method:
public void WriteXml(TextWriter writer);
If you prefer to use an XmlWriter variable to manage the file, use the
following version of the method:
public void WriteXml(XmlWriter writer);
Obviously to use this method, you must first define an XmlWriter type of
variable.
1. To create a new class, on the main menu, click Project -> Add Class...
namespace CollegeParkAutoParts4
string strDirectory;
string strFilename;
public Inventory()
{
colPartNumber = new DataColumn("PartNumber",
Type.GetType("System.Int32"));
colYear = new DataColumn("Year",
Type.GetType("System.Int32"));
colMake = new DataColumn("Make",
Type.GetType("System.String"));
colModel = new DataColumn("Model",
Type.GetType("System.String"));
colPartName = new DataColumn("PartName",
Type.GetType("System.String"));
colPartPrice = new DataColumn("PartPrice",
Type.GetType("System.Double"));
if (!dirInfo.Exists)
dirInfo.Create();
}
if (File.Exists(strFilename))
dsStoreItems.ReadXml(strFilename);
do
{
try
{
Console.WriteLine("What type of item do you
want to add");
Console.WriteLine("1. An auto part (for a car or
an engine)");
Console.WriteLine("2. Another type of item,
" +
"not for a specific car");
Console.WriteLine("0. Stop");
Console.WriteLine("Enter the following pieces of
information");
Console.Write("Your Choice: ");
typeOfItem = int.Parse(Console.ReadLine());
if (typeOfItem == 1)
{
Random rndPartNumber = new Random();
iPartNumber = rndPartNumber.Next(100000,
999999);
try
{
Console.Write("Car Year:
");
year =
int.Parse(Console.ReadLine());
}
try
{
Console.Write("Unit Price:
");
unitPrice =
double.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("Invalid unit
price");
}
Console.WriteLine("\nHere is a summary
of " +
"the part to be added");
Console.WriteLine("--------------------------------");
Console.WriteLine("Part Number: {0}",
iPartNumber);
Console.WriteLine("Year: {0}",
year);
Console.WriteLine("Make: {0}",
strMake);
Console.WriteLine("Model: {0}",
strModel);
Console.WriteLine("Part Name: {0}",
strPartName);
Console.WriteLine("Unit Price: {0:C}",
unitPrice);
Console.WriteLine("--------------------------------");
dsStoreItems.WriteXml(strFilename);
}
else
Console.WriteLine("The part will not
be " +
"added to the
database");
}
else if (typeOfItem == 2)
{
Random rndPartNumber = new Random();
iItemNumber = rndPartNumber.Next(100000,
999999);
Console.Write("Item/Description: ");
strItemName = Console.ReadLine();
try
{
Console.Write("Unit Price: ");
unitPrice =
double.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("Invalid unit price");
}
Console.WriteLine("--------------------------------");
Console.WriteLine("Item Number: {0}",
iItemNumber);
Console.WriteLine("Name/Descr: {0}",
strItemName);
Console.WriteLine("Unit Price: {0:C}",
unitPrice);
Console.WriteLine("--------------------------------");
dsStoreItems.WriteXml(strFilename);
}
else
Console.WriteLine("The part will not be
" +
"added to the database");
}
}
catch (FormatException)
{
Console.WriteLine("Invalid Menu Selection");
}
} while (typeOfItem == 1 || typeOfItem == 2);
}
namespace CollegeParkAutoParts4
{
class Program
{
static int Main(string[] args)
{
Inventory item = new Inventory();
item.CreateStoreItem();
Console.WriteLine();
return 0;
}
}
}
To open the data saved from a list, the DataSet class provides the
ReadXml() method that is overloaded with various versions. One of the
versions of this method uses the following syntax:
public XmlReadMode ReadXml(string fileName);
This method takes as argument the name of an existing XML file or its path.
The method opens the file and provides the XML formatting as it was done
when the file was saved. Here is an example of calling this method:
using System;
using System.IO;
using System.Data;
namespace VideoCollection
{
public static class Program
{
static DataSet dsVideos;
Type.GetType("System.String"));
tblVideos.Columns.Add(colDirector);
Type.GetType("System.String"));
tblVideos.Columns.Add(colLength);
Type.GetType("System.Int16"));
tblVideos.Columns.Add(colYear);
Type.GetType("System.String"));
tblVideos.Columns.Add(colRating);
dsVideos.Tables.Add(tblVideos);
tblVideos.Rows.Add(rowVideo);
dsVideos.WriteXml(strDirectory + @"\videos.xml");
}
return 0;
}
}
}
Although this method can read any XML file, if you use it to open a file that
was saved by someone else or another application and you want to use it in
your application, you should be familiar with the names of its nodes. If it
contains names that are not "registered" or recognized by your DataSet
object, the lists that compose your application may not be able to read it, not
because the list was not formatted right, but because the lists of your
application would be holding different names.
If the file was saved using a Stream-based class, you can pass a stream to
the method based on the following syntax:
public XmlReadMode ReadXml(Stream stream);
In the same way, the method provides an equivalent version for the
TextWriter and the XmlWriter versions:
When retrieving the content of the XML file, if you want it delivered as text,
call the DataSet.GetXml() method. Its syntax is:
public string GetXml();
Once a file has been opened, you can explore its content. The most obvious
operation related to opening a data set consists of viewing its records.
When a user has created a record, the data set that holds the information is
considered to have been modified because, obviously, it doesn't have the
same information or the same records it had when the application was
launched. You, as the programmer, have the option of accepting the changes
or rejecting them. To accept the changes, call the
DataSet.AcceptChanges() method. Its syntax is:
If you don't want the changes to take effect, you can reject them by calling
the DataSet.RejectChanges() method. Its syntax is:
public virtual void RejectChanges();
This method can be called to dismiss whatever changes where made on the
records of the list(s).
Locating a Record
Before performing any operation on a record, you must be able to locate it.
That is, you must be able to identify a record among the various records of a
table. To locate a record in the DataTable.Rows collection, the
DataRowCollection class has an indexed property that is defined as follows:
When you pass an index to this property, the compiler would check whether
the record exists. If a record with that index exists, its DataRow value is
produced.
namespace VideoCollection
{
public static class Program
{
. . . No Change
Console.WriteLine("Video Collection");
Console.WriteLine("================================");
foreach (DataRow row in tblVideos.Rows)
{
foreach (DataColumn col in tblVideos.Columns)
{
Console.WriteLine("{0}", row[col]);
}
Console.WriteLine("--------------------------------");
}
}
return 0;
}
}
}
The DataRow class itself is equipped with an indexed property that allows you
to access the value stored in a particular column. For example, you can use a
for loop to visit each column by its index. Once you get to a column, you can
then use the indexed property of a row to access the value stored under that
column. Here are examples:
using System;
using System.IO;
using System.Data;
namespace VideoCollection
{
public static class Program
{
. . . No Change
Console.WriteLine("================================");
Console.WriteLine("Video Collection");
Console.WriteLine("================================");
for (int i = 0; i < tblVideos.Rows.Count; i++)
{
DataRow row = tblVideos.Rows[i];
Console.WriteLine("Shelf #: {0}",
tblVideos.Rows[i]["ShelfNumber"]);
Console.WriteLine("Title: {0}",
tblVideos.Rows[i]["Title"]);
Console.WriteLine("Director: {0}",
tblVideos.Rows[i]["Director"]);
Console.WriteLine("Length: {0}",
tblVideos.Rows[i]["Length"]);
Console.WriteLine("Year: {0}",
tblVideos.Rows[i]["Year"]);
Console.WriteLine("Rating: {0}",
tblVideos.Rows[i]["Rating"]);
Console.WriteLine("--------------------------------");
return 0;
}
}
}
Locating a Value
The Distinguished
Jonathan Lynn 112 Minutes R
Gentleman
The "A Few Good Men" string is a value of the Title column. In the same way,
1992 is a value of the Year column. In some circumstances, you will need to
locate a particular value in order to perform an operation on it. You can start
by locating the record you need and return its DataRow object. To know the
table that the record belongs to, access its DataRow.Table property. This
property is declared as follows:
public DataTable Table {get;}
To locate the value that a record holds under a particular column, the
DataRow class had an indexed property that is overloaded with various
versions (actually six, but at this time we are interested in the first three
only). One of the versions of this property uses the following syntax:
public object this[string columnName] {get; set;}
To use this property, pass the object name of the column in the square
brackets. Here are examples:
using System;
using System.IO;
using System.Data;
namespace VideoCollection
{
public static class Program
{
. . . No Change
Console.WriteLine("================================");
Console.WriteLine("Video Collection");
Console.WriteLine("================================");
for (int i = 0; i < tblVideos.Rows.Count; i++)
{
DataRow row = tblVideos.Rows[i];
Console.WriteLine("Shelf #: {0}",
tblVideos.Rows[i][colShelfNumber]);
Console.WriteLine("Title: {0}",
tblVideos.Rows[i][colTitle]);
Console.WriteLine("Director: {0}",
tblVideos.Rows[i][colDirector]);
Console.WriteLine("Length: {0}",
tblVideos.Rows[i][colLength]);
Console.WriteLine("Year: {0}",
tblVideos.Rows[i][colYear]);
Console.WriteLine("Rating: {0}",
tblVideos.Rows[i][colRating]);
Console.WriteLine("--------------------------------");
}
}
return 0;
}
}
}
Instead of using the index of a column, you can also locate a value using the
variable name of its column. To do this, you can use the following syntax of
the DataRow indexed property:
public object this[DataColumn column] {get; set;}
This property expects the object name of the column passed in its square
brackets. We saw earlier how to use this version of the property. Here are
examples, using foreach:
using System;
using System.IO;
using System.Data;
namespace VideoCollection
{
Console.WriteLine("================================");
Console.WriteLine("Video Collection");
Console.WriteLine("================================");
foreach (DataRow row in tblVideos.Rows)
{
Console.WriteLine("Shelf #: {0}",
row["ShelfNumber"]);
Console.WriteLine("Title: {0}",
row["Title"]);
Console.WriteLine("Director: {0}",
row["Director"]);
Console.WriteLine("Length: {0}",
row["Length"]);
Console.WriteLine("Year: {0}", row["Year"]);
Console.WriteLine("Rating: {0}",
row["Rating"]);
Console.WriteLine("--------------------------------");
}
}
return 0;
}
}
}
The third option you have is to identify the column by its index. To do this,
use the following syntax of the DataRow indexed property:
public object this[int columnIndex] {get; set;}
namespace VideoCollection
{
Console.WriteLine("================================");
Console.WriteLine("Video Collection");
Console.WriteLine("================================");
for (int i = 0; i < tblVideos.Rows.Count; i++)
{
DataRow row = tblVideos.Rows[i];
Console.WriteLine("Shelf #: {0}",
tblVideos.Rows[i][0]);
Console.WriteLine("Title: {0}",
tblVideos.Rows[i][1]);
Console.WriteLine("Director: {0}",
tblVideos.Rows[i][2]);
Console.WriteLine("Length: {0}",
tblVideos.Rows[i][3]);
Console.WriteLine("Year: {0}",
tblVideos.Rows[i][4]);
Console.WriteLine("Rating: {0}",
tblVideos.Rows[i][5]);
Console.WriteLine("--------------------------------");
}
}
return 0;
}
}
}
namespace VideoCollection
{
public static class Program
{
. . . No Change
Console.WriteLine("================================");
Console.WriteLine("Video Collection");
Console.WriteLine("================================");
foreach (DataRow row in tblVideos.Rows)
{
Console.WriteLine("Shelf #: {0}", row[0]);
Console.WriteLine("Title: {0}", row[1]);
Console.WriteLine("Director: {0}", row[2]);
Console.WriteLine("Length: {0}", row[3]);
Console.WriteLine("Year: {0}", row[4]);
Console.WriteLine("Rating: {0}", row[5]);
Console.WriteLine("--------------------------------");
}
}
return 0;
}
}
}
2. To allow the user to display the store inventory, change the file as
follows:
using System;
using System.IO;
using System.Xml;
using System.Data;
namespace CollegeParkAutoParts1
{
public class Inventory
{
// These are the columns of the AutoParts table
private DataColumn colPartNumber;
private DataColumn colYear;
try
{
Console.Write("Unit Price:
");
unitPrice =
double.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("Invalid unit
price");
}
Console.WriteLine("--------------------------------");
dsStoreItems.WriteXml(strFilename);
}
else
Console.WriteLine("The part will not
be added to the database");
}
// For the same logic for other store items
// The items in this section can be anything
else if (typeOfItem == 2)
{
Random rndPartNumber = new Random();
iItemNumber = rndPartNumber.Next(100000,
999999);
Console.Write("Item/Description: ");
strItemName = Console.ReadLine();
try
{
Console.WriteLine("\nHere is a summary
of the part to be added");
Console.WriteLine("--------------------------------");
Console.WriteLine("Item Number: {0}",
iItemNumber);
Console.WriteLine("Name/Descr: {0}",
strItemName);
Console.WriteLine("Unit Price: {0:C}",
unitPrice);
Console.WriteLine("--------------------------------");
dsStoreItems.WriteXml(strFilename);
}
else
Console.WriteLine("The part will not
be added to the database");
}
}
catch (FormatException)
{
Console.WriteLine("Invalid Menu Selection");
}
} while (typeOfItem == 1 || typeOfItem == 2);
}
Console.WriteLine("================================");
Console.WriteLine(" College Park Auto Parts");
Console.WriteLine(" Store Inventory");
Console.WriteLine(" Car Parts");
Console.WriteLine("================================");
foreach (DataRow part in tblAutoParts.Rows)
{
Console.WriteLine("Part #: {0}",
part["PartNumber"]);
Console.WriteLine("Car Year: {0}",
part["Year"]);
Console.WriteLine("Make: {0}",
part["Make"]);
Console.WriteLine("Model: {0}",
part["Model"]);
Console.WriteLine("Part Name: {0}",
part["PartName"]);
Console.WriteLine("Unit Price: {0:C}",
part["PartPrice"]);
Console.WriteLine("--------------------------------");
}
Console.WriteLine("================================");
Console.WriteLine(" Other Store Items");
Console.WriteLine("================================");
foreach (DataRow item in tblStoreItems.Rows)
{
Console.WriteLine("Item #: {0}",
item["ItemNumber"]);
Console.WriteLine("Name/Description: {0}",
item["ItemName"]);
Console.WriteLine("Unit Price: {0:C}",
item["ItemPrice"]);
Console.WriteLine("--------------------------------");
}
}
}
}
}
4. To allow the user to decide about the action to take when the application
comes up, change the file as follows:
using System;
Console.WriteLine("================================");
Console.WriteLine(" College Park Auto Parts");
Console.WriteLine("================================");
do
{
try
{
Console.WriteLine("What do you want to
do?");
Console.WriteLine("1. Add New Store Item");
Console.WriteLine("2. View Inventory");
Console.WriteLine("0. Quit");
Console.Write("Your Selection? ");
choice = char.Parse(Console.ReadLine());
if (choice == '1')
inv.CreateStoreItem();
else if (choice == '2')
inv.ShowInventory();
}
catch (FormatException)
{
Console.WriteLine("Unrecognizable Menu
Selection");
}
} while ((choice == '1') || (choice == '2'));
Console.WriteLine();
return 0;
}
}
}
Records Maintenance
Introduction
Once a table has been filled with records, you can perform maintenance
operations on it such as changing some records or removing others.
Editing a record consists of changing one of the values of the record under a
particular column. There are various ways you can do this. For a console
application, the general steps you can (we will) follow are:
1. Make sure the table has at least one column that can be used to
uniquely identify each record. For example, when creating a table for
employees, you can assign a unique employee number to each staff member.
The same would go for students. If you are creating a table for a collection of
items, such as a book or a video collection, a commercial store that sells items
such as auto parts, make sure each item has a certain value that is unique to it,
such as a shelf number or a store number
2. Before editing a record, make the user aware of the existing values. You
can do this by displaying the records of the database
3. Request a value of the unique column from the user. For a table that
contains employees information, you can ask the user to enter the employee
number of the record to edit. The same would be for a book or video collection,
a commercial store that sells items, etc
4. After the user has indicated the record that will be modified, display the
particular values of that record
5. Asks the user to specify what particular column will receive the change
In the previous lesson, we saw that you could isolate a record based on the
object names of the columns such as Director or Title for a table of videos.
Once you have identified a column for a record, you can assign the desired
value. Here are examples:
using System;
using System.IO;
using System.Xml;
using System.Data;
using System.Collections;
namespace VideoCollection3
{
public class VideoCollection
{
public DataSet dsVideos;
public VideoCollection()
{
CreateCollection();
strDirectory = @"C:\Programs\Video Collection";
strFilename = strDirectory + "\\" + "videos.xml";
dsVideos.Tables.Add(tblVideos);
}
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("Video Collection - Tables");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine("Video Collection - {0} Columns",
table);
Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
Console.WriteLine(
"Enter the following pieces of information about
the video");
Console.Write("Shelf Number: ");
ShelfNumber = Console.ReadLine();
if (File.Exists(strFilename))
{
xmlVideos.Load(strFilename);
dsVideos.ReadXml(strFilename);
Console.Write("Title: ");
Title = Console.ReadLine();
Console.Write("Director: ");
Director = Console.ReadLine();
Console.Write("Year Released: ");
Year = int.Parse(Console.ReadLine());
Console.Write("Length (ex 118mins): ");
Length = Console.ReadLine();
this.tblVideos.Rows.Add(rowVideo);
this.dsVideos.WriteXml(strFilename);
}
Console.WriteLine("========================================");
Console.WriteLine(" Video Collection");
Console.WriteLine("=========================================");
foreach (DataRow vdo in tblVideos.Rows)
{
Console.WriteLine("Shelf #: {0}",
vdo["ShelfNumber"]);
Console.WriteLine("Title: {0}",
vdo["Title"]);
Console.WriteLine("Director: {0}",
vdo["Director"]);
Console.WriteLine("(c) Year: {0}",
vdo["Year"]);
Console.WriteLine("Length: {0:C}",
vdo["Length"]);
Console.WriteLine("Rating: {0}",
vdo["Rating"]);
Console.WriteLine("-----------------------------------------");
}
}
}
Console.WriteLine("========================================");
Console.WriteLine(" Video Collection");
Console.WriteLine("=========================================");
foreach (DataRow vdo in tblVideos.Rows)
{
Console.WriteLine("Shelf #: {0}",
vdo["ShelfNumber"]);
Console.WriteLine("Title: {0}",
vdo["Title"]);
Console.WriteLine("Director: {0}",
vdo["Director"]);
Console.WriteLine("(c) Year: {0}",
vdo["Year"]);
Console.WriteLine("Length: {0:C}",
vdo["Length"]);
Console.WriteLine("Rating: {0}",
vdo["Rating"]);
Console.WriteLine("-----------------------------------------");
}
Console.WriteLine(str);
if( str == strShelfNumber )
{
//rowVideo = vdo;
found = true;
Console.WriteLine("\n-----------------------------------------")
;
Console.WriteLine("Here is the video");
Console.WriteLine("1. Title: {0}",
vdo["Title"]);
Console.WriteLine("2. Director: {0}",
vdo["Director"]);
Console.WriteLine("3. (c) Year: {0}",
vdo["Year"]);
Console.WriteLine("4. Length: {0}",
vdo["Length"]);
Console.WriteLine("5. Rating: {0}",
Console.WriteLine("-----------------------------------------");
strTitle = (string)vdo["Title"];
strDirector = (string)vdo["Director"];
iYear = (int)vdo["Year"];
strLength = (string)vdo["Length"];
strRating = (string)vdo["Rating"];
switch (col)
{
case 1:
vdo["ShelfNumber"] =
strShelfNumber;
Console.Write("Enter the new
video title: ");
strTitle = Console.ReadLine();
vdo["Title"] = strTitle;
vdo["Director"] = strDirector;
vdo["Year"] = iYear;
vdo["Length"] = strLength;
vdo["Rating"] = strRating;
this.dsVideos.WriteXml(strFilename);
break;
case 2:
vdo["ShelfNumber"] =
strShelfNumber;
vdo["Title"] = strTitle;
Console.Write("Enter the new
director of the video: ");
strDirector =
Console.ReadLine();
vdo["Director"] = strDirector;
vdo["Year"] = iYear;
vdo["Length"] = strLength;
vdo["Rating"] = strRating;
this.dsVideos.WriteXml(strFilename);
break;
case 3:
vdo["ShelfNumber"] =
strShelfNumber;
vdo["Title"] = strTitle;
vdo["Director"] = strDirector;
Console.Write("Enter the right year
released of the video: ");
this.dsVideos.WriteXml(strFilename);
break;
case 4:
vdo["ShelfNumber"] =
strShelfNumber;
vdo["Title"] = strTitle;
vdo["Director"] = strDirector;
vdo["Year"] = iYear;
Console.Write("Enter the new
length of the video: ");
strLength = Console.ReadLine();
vdo["Length"] = strLength;
vdo["Rating"] = strRating;
this.dsVideos.WriteXml(strFilename);
break;
case 5:
vdo["ShelfNumber"] =
strShelfNumber;
vdo["Title"] = strTitle;
vdo["Director"] = strDirector;
vdo["Year"] = iYear;
vdo["Length"] = strLength;
Console.Write("Enter the right
rating for the video: ");
strRating = Console.ReadLine();
vdo["Rating"] = strRating;
this.dsVideos.WriteXml(strFilename);
break;
}
return;
}
}
if (found == false)
{
Console.WriteLine("No video with that shelf
number was found");
return;
}
}
}
}
}
Deleting Records
If you happen to have a record you don't need or don't find necessary in a
table, you can remove that record from the table. To start, you must establish
what record you want to delete. Once again, you would need a way to uniquely
identify a record. For our video collection, you can use the shelf number
column. Once you have located the undesired record, you can delete it.
To assist you with removing a record, the DataRow class is equipped with a
method named Delete. Its syntax is simply:
public void Delete();
This method must be called by the record that wants to be deleted. Here is an
example:
using System;
using System.IO;
using System.Xml;
using System.Data;
using System.Collections;
namespace VideoCollection3
{
public class VideoCollection
{
. . . No Change
dsVideos.ReadXml(strFilename);
Console.WriteLine("=========================================");
foreach (DataRow vdo in tblVideos.Rows)
{
Console.WriteLine("Shelf #: {0}",
vdo["ShelfNumber"]);
Console.WriteLine("Title: {0}",
vdo["Title"]);
Console.WriteLine("Director: {0}",
vdo["Director"]);
Console.WriteLine("(c) Year: {0}",
vdo["Year"]);
Console.WriteLine("Length: {0:C}",
vdo["Length"]);
Console.WriteLine("Rating: {0}",
vdo["Rating"]);
Console.WriteLine("-----------------------------------------");
}
if (str == strShelfNumber)
{
found = true;
Console.WriteLine("\n-----------------------------------------")
;
Console.WriteLine("Here is the video you
want to delete");
Console.WriteLine("1. Title: {0}",
vdo["Title"]);
Console.WriteLine("2. Director: {0}",
vdo["Director"]);
Console.WriteLine("3. (c) Year: {0}",
vdo["Year"]);
Console.WriteLine("4. Length: {0}",
vdo["Length"]);
Console.WriteLine("5. Rating: {0}",
vdo["Rating"]);
Console.WriteLine("-----------------------------------------");
return;
}
}
if (found == false)
{
Console.WriteLine("No video with that shelf
number was found");
return;
}
}
}
}
}
Besides the DataRow class, the DataRowCollection class provides its own
means of deleting a record from a table. To delete a record, you can call the
DataRowCollection.Remove() method. Its syntax is:
This method takes as argument a DataRow object and checks whether the table
contains it. If that record exists, it gets deleted, including all of its entries for
each column. Here is an example:
using System;
using System.IO;
using System.Xml;
using System.Data;
using System.Collections;
namespace VideoCollection3
{
public class VideoCollection
{
. . . No Change
dsVideos.ReadXml(strFilename);
Console.WriteLine("========================================");
Console.WriteLine(" Video Collection");
Console.WriteLine("=========================================");
foreach (DataRow vdo in tblVideos.Rows)
{
Console.WriteLine("Shelf #: {0}",
vdo["ShelfNumber"]);
Console.WriteLine("Title: {0}",
vdo["Title"]);
Console.WriteLine("Director: {0}",
vdo["Director"]);
Console.WriteLine("(c) Year: {0}",
vdo["Year"]);
Console.WriteLine("Length: {0:C}",
vdo["Length"]);
Console.WriteLine("Rating: {0}",
vdo["Rating"]);
Console.WriteLine("-----------------------------------------");
}
if (str == strShelfNumber)
{
found = true;
Console.WriteLine("\n-----------------------------------------")
;
Console.WriteLine("Here is the video you
want to delete");
Console.WriteLine("1. Title: {0}",
vdo["Title"]);
Console.WriteLine("2. Director: {0}",
vdo["Director"]);
Console.WriteLine("3. (c) Year: {0}",
vdo["Year"]);
Console.WriteLine("4. Length: {0}",
vdo["Length"]);
Console.WriteLine("-----------------------------------------");
return;
}
}
if (found == false)
{
Console.WriteLine("No video with that shelf
number was found");
return;
}
}
}
}
}
This method takes as argument the index of the record you want to delete. If a
record with that index exists, it would be deleted.
Introduction
In the database world, a relationship is a link that exists between two objects,
mainly tables, so that data can flow from one object to another. A relationship
can do even more than that: it can be used to check the accuracy of
information from one object to another, it can be used to update the
information in one object when related information in another object has been
changed.
Remember that whenever you are dealing with a group of records, also called a
set of records, or a set of data, or a data set, you need an object that can
"translate" the values of your records into values that are data-oriented. The
object used to take care of this aspect is implemented through the DataSet
class. In this case, since we want to address relationships among tables, we will
need a data set object to manage such links.
Table Preparation
Imagine that you are creating a list of employees in a mid-size to large company
and want to categorize them by their employment status. You can start by creating
a list of the employees:
Bertha Um Corporate
This is a classic table. There are two common ways you can create a table. You
can generate a table from a database, or you can use the DataTable class that
allows you to manually create a table. Here is an example:
using System;
using System.Xml;
class Exercise
{
static void Main()
{
DataSet dsEmployment = new DataSet();
DataTable dtEmployees = new DataTable("Employees");
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["FirstName"] = "Paul";
drEmplRecord["LastName"] = "Banack";
drEmplRecord["Department"] = "IT/IM";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["FirstName"] = "Helene";
drEmplRecord["LastName"] = "Casson";
drEmplRecord["Department"] = "Accounting";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["FirstName"] = "Anselme";
drEmplRecord["LastName"] = "Thomas";
drEmplRecord["Department"] = "Public Rel";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["FirstName"] = "Bertha";
drEmplRecord["LastName"] = "Colson";
drEmplRecord["Department"] = "Corporate";
dtEmployees.Rows.Add(drEmplRecord);
dsEmployment.Tables.Add(dtEmployees);
Console.WriteLine("============+===============+==============="
);
Console.WriteLine("============+===============+===============\
n");
}
}
To associate each employee with a department, you can first create a table for
the departments. Here is an example:
using System;
using System.Xml;
using System.Data;
class Exercise
{
static void Main()
{
DataSet dsEmployment = new DataSet();
DataTable dtEmployees = new
DataTable("Employees");
System.Type.GetType("System.String"));
dtEmployees.Columns.Add(dcEmployees[0]);
dcEmployees[1] = new DataColumn("LastName",
System.Type.GetType("System.String"));
dtEmployees.Columns.Add(dcEmployees[2]);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["FirstName"] = "Paul";
drEmplRecord["LastName"] = "Banack";
drEmplRecord["Department"] = "IT/IM";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["FirstName"] = "Helene";
drEmplRecord["LastName"] = "Casson";
drEmplRecord["Department"] = "Accounting";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["FirstName"] = "Anselme";
drEmplRecord["LastName"] = "Thoma";
drEmplRecord["Department"] = "Public Relations";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["FirstName"] = "Bertha";
drEmplRecord["LastName"] = "Um";
drEmplRecord["Department"] = "Corporate";
dtEmployees.Rows.Add(drEmplRecord);
System.Type.GetType("System.String"));
dtEmplStatus.Columns.Add(dcEmployment);
drEmployment = dtEmplStatus.NewRow();
drEmployment["EmplStatus"] = "Part Time";
dtEmplStatus.Rows.Add(drEmployment);
drEmployment = dtEmplStatus.NewRow();
drEmployment["EmplStatus"] = "Contractor";
drEmployment = dtEmplStatus.NewRow();
drEmployment["EmplStatus"] = "Intern";
dtEmplStatus.Rows.Add(drEmployment);
dsEmployment.Tables.Add(dtEmplStatus);
dsEmployment.Tables.Add(dtEmployees);
Console.WriteLine("================+===============+============
===");
Console.WriteLine("First Name\t|Last Name\t|
Department");
Console.WriteLine("----------------
+---------------+---------------");
foreach(DataRow row in
dsEmployment.Tables["Employees"].Rows)
Console.WriteLine("{0}\t\t|{1}\t\t|{2}",
row["FirstName"],
row["LastName"],
row["Department"]);
Console.WriteLine("================+===============+============
===\n");
Console.WriteLine("=================");
Console.WriteLine("Employment Status");
Console.WriteLine("-----------------");
foreach(DataRow row in
dsEmployment.Tables["EmploymentStatus"].Rows)
Console.WriteLine("{0}",
row["EmplStatus"]);
Console.WriteLine("=================");
Console.WriteLine();
}
}
=================
Employment Status
-----------------
Full Time
Creating a Relationship
In our first table, to uniquely identify each record, we can create a column
called EmployeeID and add an incremental number to each record. In the same
way, a column used to identify each department in the second table of our
example can be called EmploStatusID. The tables would then be created as
follows:
using System;
using System.Xml;
using System.Data;
class Exercise
{
static void Main()
{
DataSet dsEmployment = new
DataSet("Employment");
DataTable dtEmployees = new
DataTable("Employees");
System.Type.GetType("System.Int32"));
dtEmployees.Columns.Add(dcEmployees[0]);
dcEmployees[1] = new DataColumn("FirstName",
System.Type.GetType("System.String"));
dtEmployees.Columns.Add(dcEmployees[1]);
dcEmployees[2] = new DataColumn("LastName",
System.Type.GetType("System.String"));
dtEmployees.Columns.Add(dcEmployees[2]);
dcEmployees[3] = new DataColumn("Department",
System.Type.GetType("System.String"));
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["EmployeeID"] = "2";
drEmplRecord["FirstName"] = "Paulin";
drEmplRecord["LastName"] = "Banack";
drEmplRecord["Department"] = "IT/IM";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["EmployeeID"] = "3";
drEmplRecord["FirstName"] = "Helene";
drEmplRecord["LastName"] = "Casson";
drEmplRecord["Department"] = "Accounting";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["EmployeeID"] = "4";
drEmplRecord["FirstName"] = "Anselme";
drEmplRecord["LastName"] = "Thomas";
drEmplRecord["Department"] = "Public Relations";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["EmployeeID"] = "5";
drEmplRecord["FirstName"] = "Bertha";
drEmplRecord["LastName"] = "Colson";
drEmplRecord["Department"] = "Corporate";
dtEmployees.Rows.Add(drEmplRecord);
System.Type.GetType("System.Int32"));
dtEmplStatus.Columns.Add(dcEmployment[0]);
dcEmployment[1] = new DataColumn("EmplStatus",
System.Type.GetType("System.String"));
dtEmplStatus.Columns.Add(dcEmployment[1]);
drEmployment = dtEmplStatus.NewRow();
drEmployment["EmplStatusID"] = "3";
drEmployment["EmplStatus"] = "Contractor";
dtEmplStatus.Rows.Add(drEmployment);
drEmployment = dtEmplStatus.NewRow();
drEmployment["EmplStatusID"] = "4";
drEmployment["EmplStatus"] = "Intern";
dtEmplStatus.Rows.Add(drEmployment);
dsEmployment.Tables.Add(dtEmplStatus);
dsEmployment.Tables.Add(dtEmployees);
Console.WriteLine("===+=============+===============+===========
======");
Console.WriteLine("ID | First Name\t | Last Name\t
| Department");
Console.WriteLine("---+-------------+---------------
+-----------------");
foreach(DataRow row in
dsEmployment.Tables["Employees"].Rows)
Console.WriteLine(" {0} | {1}\t | {2}\t |
{3}",
row["EmployeeID"],
row["FirstName"],
row["LastName"],
row["Department"]);
Console.WriteLine("===+=============+===============+===========
======\n");
Console.WriteLine("===+===================");
Console.WriteLine("ID | Employment Status");
Console.WriteLine("---+-------------------");
foreach(DataRow row in
dsEmployment.Tables["EmploymentStatus"].Rows)
Console.WriteLine(" {0} | {1}",
row["EmplStatusID"],
row["EmplStatus"]);
Console.WriteLine("===+===================");
Console.WriteLine();
}
}
===+===================
ID | Employment Status
---+-------------------
1 | Full Time
2 | Part Time
3 | Contractor
4 | Intern
===+===================
As mentioned already, this type of field is used to uniquely identify each record
of a table. Therefore, it is based on this field that a table can be related to
another. To actually create the relationship, in our example, to associate each
employee to a department, the table that holds the list of employees must have
a field that represents the corresponding department from the Departments
table and you must create such a new column. The most important rule you
must observe is that this new field must have the same data type as the
column that uniquely identifies each department in the other table. This field in
the Departments table is referred to as the Primary Key. The new column
created in the Employees table is referred to as the Foreign Key because this
column acts only as an "ambassador". In the strict sense, it doesn't belong to
the table in which it is created and in fact, its values should/must not be
changed by its hosting table.
After creating the foreign key column, the relationship is not automatically
applied between both tables, since neither the compiler nor the database
engine (if you were working on a database) is aware of the role of this new
field. To create a relationship between two DataTable objects, the Microsoft
.NET Framework provides the DataRelation class. As this is a small class, its
main role is to join two tables.
The first argument allows you to specify a name for the relationship.
The second argument must identify the primary key column of the table that
would supply the values. In our example, this would be the primary key of the
Departments table.
This indicates that you should first define and identify the columns that would
be used in the relationship. Based on this description, the relationship can be
created as follows:
using System;
using System.Xml;
using System.Data;
class Exercise
{
static void Main()
{
DataSet dsEmployment = new
DataSet("Employment");
DataTable dtEmployees = new
DataTable("Employees");
System.Type.GetType("System.Int32"));
dtEmployees.Columns.Add(dcEmployees[0]);
dcEmployees[1] = new DataColumn("FirstName",
System.Type.GetType("System.String"));
dtEmployees.Columns.Add(dcEmployees[1]);
dcEmployees[2] = new DataColumn("LastName",
System.Type.GetType("System.String"));
dtEmployees.Columns.Add(dcEmployees[2]);
dcEmployees[3] = new DataColumn("Department",
System.Type.GetType("System.String"));
dtEmployees.Columns.Add(dcEmployees[3]);
dcEmployees[4] = new DataColumn("EmplStatusID",
System.Type.GetType("System.Int32"));
dtEmployees.Columns.Add(dcEmployees[4]);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["EmployeeID"] = "3";
drEmplRecord["FirstName"] = "Helene";
drEmplRecord["LastName"] = "Casson";
drEmplRecord["Department"] = "Accounting";
drEmplRecord["EmplStatusID"] = "2";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["EmployeeID"] = "4";
drEmplRecord["FirstName"] = "Anselme";
drEmplRecord["LastName"] = "Thomas";
drEmplRecord["Department"] = "Public Rel";
drEmplRecord["EmplStatusID"] = "1";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["EmployeeID"] = "5";
drEmplRecord["FirstName"] = "Bertha";
drEmplRecord["LastName"] = "Colson";
drEmplRecord["Department"] = "Corporate";
drEmplRecord["EmplStatusID"] = "4";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["EmployeeID"] = "6";
drEmplRecord["FirstName"] = "Renée";
drEmplRecord["LastName"] = "Bright";
drEmplRecord["Department"] = "IT/IM";
drEmplRecord["EmplStatusID"] = "3";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["EmployeeID"] = "7";
drEmplRecord["FirstName"] = "Jeanne";
drEmplRecord["LastName"] = "Tristan";
drEmplRecord["Department"] = "Corporate";
drEmplRecord["EmplStatusID"] = "1";
dtEmployees.Rows.Add(drEmplRecord);
drEmplRecord = dtEmployees.NewRow();
drEmplRecord["EmployeeID"] = "8";
drEmplRecord["FirstName"] = "Sandrine";
drEmplRecord["LastName"] = "Holland";
drEmplRecord["Department"] = "Public Rel";
drEmplRecord["EmplStatusID"] = "4";
dtEmployees.Rows.Add(drEmplRecord);
System.Type.GetType("System.Int32"));
dtEmplStatus.Columns.Add(dcEmployment[0]);
dcEmployment[1] = new DataColumn("EmplStatus",
System.Type.GetType("System.String"));
dtEmplStatus.Columns.Add(dcEmployment[1]);
drEmployment = dtEmplStatus.NewRow();
drEmployment["EmplStatusID"] = "2";
drEmployment["EmplStatus"] = "Part Time";
dtEmplStatus.Rows.Add(drEmployment);
drEmployment = dtEmplStatus.NewRow();
drEmployment["EmplStatusID"] = "3";
drEmployment["EmplStatus"] = "Contractor";
dtEmplStatus.Rows.Add(drEmployment);
drEmployment = dtEmplStatus.NewRow();
drEmployment["EmplStatusID"] = "4";
drEmployment["EmplStatus"] = "Intern";
dtEmplStatus.Rows.Add(drEmployment);
dsEmployment.Tables.Add(dtEmplStatus);
dsEmployment.Tables.Add(dtEmployees);
DataColumn colParent =
dsEmployment.Tables["EmploymentStatus"].Columns["EmplStatusID"];
DataColumn colChild =
dsEmployment.Tables["Employees"].Columns["EmplStatusID"];
DataRelation drEmployeeStatus =
new DataRelation("EmployeeStatus",
colParent, colChild);
dsEmployment.Relations.Add(drEmployeeStatus);
Console.WriteLine("===+===================");
Console.WriteLine("ID | Employment Status");
Console.WriteLine("---+-------------------");
foreach(DataRow row in
dsEmployment.Tables["EmploymentStatus"].Rows)
Console.WriteLine("===+=============+===============+===========
====+=============");
Console.WriteLine("ID | First Name\t | Last Name\t
| Department\t | Empl Status");
Console.WriteLine("---+-------------+---------------
+---------------+-------------");
foreach(DataRow row in
dsEmployment.Tables["Employees"].Rows)
{
int iRow =
int.Parse(row["EmplStatusID"].ToString());
DataRow curRecord =
dsEmployment.Tables["EmploymentStatus"].Rows[iRow-1];
ADO Fundamentals
Introduction to Databases
A database is a project that holds one or more lists of items. There can be
other issues involved, such as how the data would be made available to the
users, what computer(s) would access the data, what types of users would
access the database. The database could reside in one computer and used by
one person. A database can also be stored in one computer but accessed by
different computers on a network. Another database can be created and
stored in a server to be accessed through the Internet. These and other
related scenarios should be dealt with to create and distribute the database.
Microsoft JET
Microsoft ActiveX Data Object Extensions for Data Definition Language and
Security abbreviated ADOX, is an addition to ADO. It can be used to create
and manage a database, providing some of the same operations as ADO but
also some operations not possible in ADO.
Based on its flexibility, you can use the .NET Framework to create and
manage Microsoft JET databases. The .NET Framework is a group of many
libraries under one name. When creating a project, you choose what libraries
you would use, based on your goal, to perform the necessary tasks. If you
are using a visual environment, you can "visually" reference the library. Based
on this, to create an application that uses the ADO library, you can add its
reference in the Solution Explorer.
Introduction
To get a database, you can either use one that exists already or you can
create your own. ADO by itself doesn't provide the means to create a
database. To create one, you can use the Microsoft ActiveX Data Objects
Extensions for Data Definition Language and Security, abbreviated ADOX.
Before using ADOX, you must reference it in your C# project. To do this, on
the main menu of Microsoft Visual C#, you can click Project -> Add
Reference... As an alternative, in the Solution Explorer, you can right-click the
name of the project and click Add References...
In the COM tab of the Add Reference dialog box, locate the Microsoft ADO
Ext. 2.8 for DDL and Security:
using System;
return 0;
}
}
After declaring the class, you can initialize it using the new operator:
using System;
return 0;
}
}
Database Creation
return 0;
}
}
The Provider
The first part of the connection string is called the provider. It is software that
handles the database. To specify it, assign the desired name to the provider
key. Here is an example:
return 0;
}
}
There are various providers in the database industry. One of them is Microsoft
SQL Server and it is represented by SQLOLEDB. If you want to create a
Microsoft SQL Server database, specify this provider. Here is an example:
using System;
When creating this type of database, there are some other pieces of
information you must provide in the connection string.
If you are creating a database, the second part of the connection string can
be used to specify the path and the name of the database. This section must
start with the Data Source key and assigned the path that consists of the
drive and the folder(s). After the last folder, the name of the database must
have the .mdb extension. For example, to create a database called Exercise1
that would reside in a folder called Programs on the C: drive, you can specify
the connection string as follows:
using System;
catADO.Create("Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb'");
Console.WriteLine("A new Microsoft JET database named "
+
"Exercise1.mdb has been created");
return 0;
}
}
Instead of directly passing a string to the Create() method, you can first
declare a string variable, initialize it with the necessary provider/data
source, and then pass that string variable to the Create() method. Here is
an example:
using System;
To proceed, click the Add button. This would launch a wizard. In the first
page of the Create New Data Source wizard, click Microsoft Access Driver
(*.mdb):
After entering the necessary information and selecting the desired database,
you can click OK twice.
Referencing ADO
And click OK. This would add the ADO reference to your project.
Introduction
return 0;
}
}
Opening a Connection
After declaring and initializing the Connection object, you can then open the
connection. To support this, the Connection interface (the
ConnectionClass class) is equipped with a method named Open. The syntax
of the Connection.Open method is:
public void _Connection.Open(string ConnectionString,
string UserID,
As you can see, this method takes four arguments and all of them are
required.
One of the expressions you can specify in the connection string is the name
of the provider. To do this, type Provider= followed by the provider you are
using. For most databases we will create or use here, the provider will be
Microsoft.JET.OLEDB.4.0. This means that our connection string can start
with:
using System;
using ADODB;
string strConnection=
"Provider=Microsoft.Jet.OLEDB.4.0;". . .
return 0;
}
}
You can also include the value of the provider in single-quotes to delimit it.
The second part of the connection string specifies the data source. To provide
this information, you can assign the path and name of the database to the
Data Source attribute. Here is an example:
using System;
using ADODB;
string strConnection =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb';";
return 0;
}
}
It is important to note that the content of the connection string differs from
one provider to another. If you were working on a Microsoft SQL Server
database, your connection string would be different from the above done for
a Microsoft JET database. For example, if you were working on an MSDE or a
Microsoft SQL Server database, the provider would be SQLOLEDB.
After creating the connection string, you can then pass it to the
Connection.Open() method as the first argument. Here is an example:
using System;
using ADODB;
string strConnection =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb';";
conDatabase.Open(strConnection, );
return 0;
}
}
When creating your database, if you are working in a secure environment and
the database requires authentication, you may need to provide login
credentials, which include a username and a password. Normally, these
properties are mostly applied if you are working on a Microsoft SQL Server
database.
To specify the login credentials when accessing the database, you can pass
the second and the third arguments to the Open() method of the
Connection class. If you don't have this information, you can pass each
argument as an empty string. Here is an example:
using System;
string strConnection =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb';";
string strConnection =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb';";
After creating a connection to a database, you can specify what you want to
do on the database. One of the most common operations you can perform is
to submit a statement to it (the connection). This is also equivalent to
executing the statement.
string strConnection =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb';";
return 0;
}
}
Closing a Connection
conADO.Close();
return 0;
}
}
try
{
string strConnection =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb';";
return 0;
}
}
Table Creation
Introduction
When studying data sets, we defined a database as one or more lists. A list
in a database is called a table. The idea is that a table is an arrangement of
the categories of information stored in a list and a table makes it easy to
locate and manage the records of a list. To better explore lists, you should
know how a table organizes its value.
First Alternate
Last Name Main Subject
Name Subject
Notice that the first names are grouped in a common category, so are the last
names and so on. This makes it easy to locate a category and possibly a
value.
Table Creation
The CREATE and TABLE keywords must be used to create a table. The Name
factor specifies the name of the new table.
After the CREATE TABLE expression, you must enter a name for the table.
The name of a table can be very flexible. This flexibility can be overwhelming
and confusing. To avoid these, there are suggestions and conventions we will
apply when naming our tables:
The name of a table will start with a letter. In most cases, the name will
start in uppercase
Because we believe that a table represents a list of items, its name will
be in plural. Examples are Students, Employees, Products
In most cases, we will avoid including space in a name; but if we do, the
name of a table will be included between [ and ]
Here is an example:
using System;
using ADODB;
return 0;
}
}
After formulating the expression that creates the table, you can pass it to the
Execute() method of a Connection variable. This would be done as follows:
using System;
using ADODB;
try
{
object objAffected;
string strStatement = "CREATE TABLE Persons...";
string strConnection =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb';";
Besides the CREATE TABLE expression followed by a name, there are other
issues related to creating a table. We will review more details in future
lessons.
Table Maintenance
Deleting a Table
Replace the TableName factor of our formula with the name of the table you
want to delete. Here is an example:
using System;
using ADODB;
try
{
object objAffected;
string strStatement = "DROP TABLE Persons";
string strConnection =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb';";
Columns Fundamentals
Introduction
We saw that a table was used to organize the values of a list by using
categories of information. Here is an example:
First Years of
Last Name Main Class
Name Experience
Comp
Jones Celestine 10
Sciences
Column Creation
To create the columns of a table, on the right side of the name, type an
opening and a closing parentheses. In the parentheses of the CREATE TABLE
TableName() expression, the formula of creating a column is:
ColumnName DataType Options
Notice that there is only space that separates the sections of the formula.
This formula is for creating one column. If you want the table to have more
than one column, follow this formula as many times as possible but separate
the sections with colons. This would be done as follows:
CREATE TABLE TableName(Column1 DataType1 Options1,
Column2 DataType2 Options2,
Column_n DataType_n Options_n)
In the next sections, we will review the factors of this formula. To create a
table in ADO, you can pass the whole statement to the Execute() method of
the Connection class.
Characteristics of a Column
Introduction
The name of a column will start with a letter. In most cases, the name
will start in uppercase
In most cases, we will avoid including space in a name but if we do, the
name of the column will be included between [ and ]
When creating the table, set the name of the column in the ColumnName
placeholder of our formula. Here is an example:
CREATE TABLE Students(FullName, DataType Options)
try
{
object objAffected;
string strStatement = "CREATE TABLE
Customers(FirstName char, " +
"LastName varchar);";
string strConnection =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb';";
Each one of the char, string, or varchar data types would produce the
same effect. A column with the string, the char, or the varchar data type
allows any type of value made of any character up to 255 symbols. If you
want the column to hold longer text, specify its data type as Memo, NOTE, or
LONGTEXT. Such a column can hold any type of text, any combination of
characters, and symbols, up to 64000 characters. Here are examples:
try
{
object objAffected;
string strStatement = "CREATE TABLE
Employees(FullName String, " +
"LongTimeGoals LongText);";
string strConnection =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb';";
try
{
object objAffected;
string strStatement = "CREATE TABLE Contractors(" +
Byte and Integer1: If you want a column to hold natural numbers, you
can specify its data type as Byte or Integer1. This is suited for a column
that will hold small numeric values not to exceed 255. Here are examples:
using System;
using ADODB;
try
{
object objAffected;
string strStatement = "CREATE TABLE
EmploymentStatus(" +
"StatusID Byte,
" +
"Category
Integer1);";
string strConnection =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb';";
Short and Integer2: If you want the column to hold larger numbers that
can exceed 255, specify its data type as SHORT or INTEGER2.
Long: If the column will hold small to very large numbers, specify its data
type as INT, INTEGER, INTEGER4 or Long.
using System;
using ADODB;
try
{
object objAffected;
string strStatement = "CREATE TABLE Students(" +
"FullName varchar, "
+
"Height Single, " +
"Weight Numeric, " +
"GPA Double);";
string strConnection =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb';";
conADO.Open("Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source='C:\\Programs\\Exercise1.mdb'",
"", "", 0);
strCreate = "CREATE TABLE Customers(" +
"FullName Text, " +
"WeeklyHours Double, " +
"HourlySalary Money, " +
"WeeklySalary Currency);";
conADO.Execute(strCreate, out obj, 0);
Console.WriteLine("A table named Customers has been added
to the database");
conADO.Close();
return 0;
}
}
Date and Time: If you are creating a column whose values would consist of
date, time, or both date and time, specify its data type as DATE or DATETIME.
Here are examples:
using System;
using ADODB;
conADO.Open("Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb'", "", "", 0);
strCreate = "CREATE TABLE Teachers(" +
return 0;
}
}
Binary: The binary data type can let a column accept any type of data but it
is equipped to interpret the value. For example, it can be used to receive
hexadecimal numbers. To specify this when creating a column, set its data
type to either BINARY or VARBINARY.
Image: If you are creating a column that will hold external documents, such
as pictures, formatted (from Microsoft Word for example), or spreadsheet,
etc, specify its data type to one of the following: IMAGE, OLEOBJECT,
LONGBINARY, or GENERAL.
Column Maintenance
Introduction
After a table with one or more columns has been created, you can add a new
column to it. To add a new column, after the ALTER TABLE statement and
the name of the table, include an ADD COLUMN expression using the following
formula:
ALTER TABLE TableName
ADD COLUMN ColumnName DataType
The ColumnName factor must be a valid name for the new column and you
must follow the rules for naming columns. The data type must be one of
those we reviewed. Here is an example that adds a new string-based column
named CellPhone to a table named Employees:
conADO.Open("Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb'", "", "", 0);
strStatement = "ALTER TABLE Employees ADD COLUMN
CellPhone string;";
conADO.Execute(strStatement, out obj, 0);
conADO.Close();
return 0;
}
}
Deleting a Column
To delete a column, start with the ALTER TABLE expression followed by the
name of the table. After the ALTER TABLE TableName expression, follow it
with a DROP COLUMN expression using this formula:
ALTER TABLE TableName DROP COLUMN ColumnName;
Replace the ColumnName factor of our formula with the name of the
undesired column. Here is an example:
using System;
using ADODB;
conADO.Open("Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\Exercise1.mdb'", "", "", 0);
strStatement = "ALTER TABLE Employees DROP COLUMN
Comments;";
conADO.Execute(strStatement, out obj, 0);
conADO.Close();
return 0;
}
}
Introduction
So far, we have learned how to create a database and how to create a table.
Here are the database and the table we will use:
using System;
using ADODB;
try
{
catPeople.Create("Provider=Microsoft.Jet.OLEDB.4.0;"
+
"Data
Source='C:\\Programs\\People.mdb';");
Console.WriteLine("A new Microsoft JET database
named " +
"People.mdb has been created");
conPeople.Open("Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\People.mdb'",
"", "", 0);
return 0;
}
}
After creating a table and its column(s), you can populate the database with
data. Data entry consists of filling a table with the necessary values. A series
of values that corresponds to same levels of columns is called a row or a
record.
Before performing data entry on a table, you must know how the table is
structured, the sequence of its columns, the type of data that each column is
made of. To enter data in a table, you start with the INSERT combined with
the VALUES keywords. The statement uses the following syntax:
INSERT TableName VALUES(Column1, Column2, Column_n)
Alternatively, or to be more precise, you can specify that you are entering
data in the table using the INTO keyword between the INSERT keyword and
the TableName factor. This is done with the following syntax:
INSERT INTO TableName VALUES(Column1, Column2, Column_n)
The VALUES keyword indicates that you are ready to list the values of the
columns. The values of the columns must be included in parentheses. Specify
the value of each column in the parentheses that follow the VALUES keyword:
Date and Time Values: If the column was created for a date or a time data
type, you should/must use an appropriate formula with the year represented
by 2 or 4 digits. You should also include the date in single-quotes. If you want
to specify the year with 2 digits, use the formula:
'yy-mm-dd'
Or
'yy/mm/dd'
You can use the dash symbol "-" or the forward slash "/" as the date
separator. An alternative to representing a year is with 4 digits. In this case,
you would use the formulas:
'yyyy-mm-dd'
Or
'yyyy/mm/dd'
The most common technique of performing data entry requires that you know
the sequence of columns of the table in which you want to enter data. With
this subsequent list in mind, enter the value of each field in its correct
position.
During data entry on adjacent fields, if you don't have a value for a numeric
field, you should type 0 as its value. For a string field whose data you don't
have and cannot provide, type two single-quotes to specify an empty field.
Here is an example:
try
{
conPeople.Open("Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\People.mdb'", "", "", 0);
conPeople.Execute("INSERT INTO Persons(FirstName,
LastName, Gender) " +
"VALUES('James', 'Carlton',
'Male');", out obj, 0);
Console.WriteLine("A new record has been created in
the Persons table");
}
finally
{
conPeople.Close();
}
return 0;
}
}
The adjacent data entry requires that you know the position of each column.
The SQL provides an alternative that allows you to perform data entry using
the name of a column instead of its position. This allows you to provide the
values of fields in any order of your choice.
To perform data entry at random, you must provide a list of the columns of
the table in the order of your choice. You can either use all columns or
provide a list of the same columns but in your own order. Here is an example:
using System;
using ADODB;
try
{
conPeople.Open("Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\People.mdb'", "", "", 0);
conPeople.Execute("INSERT INTO Persons(LastName,
Gender, FirstName) " +
"VALUES('Germain', 'Male',
'Ndongo');", out obj, 0);
Console.WriteLine("A new record has been created in
the Persons table");
}
finally
{
conPeople.Close();
}
return 0;
}
}
You don't have to provide data for all columns, just those you want, in the
order you want. To do this, enter the names of the desired columns on the
right side of the name of the table, in parentheses. The syntax used would
be:
INSERT TableName(ColumnName1, Columnname2, ColumnName_n)
VALUES(ValueFormColumnName1, ValueFormColumnName2,
ValueFormColumnName_n);
When performing data entry, you can expect the user to skip any column
whose value is not available and move to the next. In some cases, you may
require that the value of a column be specified before the user can move on.
If you are creating a column and if you want to let the user add or not add a
value for the column, type the NULL keyword on the right side of the data
type. If you want to require a value for the column, type NOT NULL. Here are
examples:
using System;
using ADODB;
catADOX.Create("Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\VideoCollection.mdb';");
Console.WriteLine("A new Microsoft JET database named
VideoCollection.mdb " +
"has been created");
conVideos.Open("Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\VideoCollection.mdb'",
"", "", 0);
conVideos.Execute("CREATE TABLE Videos(" +
"VideoTitle STRING NOT NULL, " +
"Director STRING NULL, " +
"YearReleased SHORT, " +
"Rating BYTE NULL);",
out obj, 0);
Console.WriteLine("A new table named Videos has been
created");
conVideos.Close();
return 0;
}
}
In this case, when performing data entry, the user must always provide a
value for the VideoTitle column in order to create a record. If you omit to
specify the nullity of a field, it is assumed NULL; that's the case for the
YearReleased column of the above Videos table.
Auto-Increment
When we study relationships, we will see that, on a table, each record should
be uniquely identified. This should be the case even if many records seem to
have the same values for each column. We saw already that you can require
that the user provide a value for each record of a certain column. In some
cases, the user may not have the right value for a column but at the time, the
record would need to be created, even if it is temporary. To solve this type of
problem and many others, you can create a column that provides its own
value. On the other hand, to create a special column that can be used to
uniquely identify each record, you can apply an integer data type to it but ask
the database engine to automatically provide a numeric value for the column.
If you are creating the column, you can specify its data type as either
COUNTER or AUTOINCREMENT. Only one column of a table can have one of
these data types. Here is an example:
conVideos.Open("Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\VideoCollection.mdb'",
"", "", 0);
conVideos.Execute("CREATE TABLE Videos(" +
"ShelfNumber COUNTER, " +
"VideoTitle STRING NOT NULL, " +
"Director STRING NULL, " +
"YearReleased SHORT, " +
"Rating BYTE NULL);",
out obj, 0);
Console.WriteLine("A new table named Videos has been
created");
conVideos.Close();
return 0;
}
}
By default, when you apply the COUNTER or the AUTOINCREMENT data type,
when the user creates the first record, the field int the auto-incrementing
column receives a number of 1. If the user creates a second record, the auto-
incrementing value receives a number of 2, and so on. If you want, you can
make the first record receive a number other than 1. You can also make it
increment to a value other than 1. To apply this feature, the COUNTER and the
AUTOINCREMENT types use a seed as their parentheses:
COUNTER(x,y)
or
AUTOINCREMENT(x,y)
The x value represents the starting value of the records. The y value specifies
how much would be added to a value to get the next.
Fields Sizes
When reviewing the data types available for columns, we saw that some of
them could use a string-based data type, namely TEXT, CHAR, or VARCHAR. By
default, if you create a table and you set a column's data type to TEXT, CHAR,
or VARCHAR, it is made to hold 255 characters. If you want, you can control
conVideos.Open("Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\VideoCollection.mdb'",
"", "", 0);
conVideos.Execute("CREATE TABLE Videos(" +
"ShelfNumber COUNTER, " +
"VideoTitle STRING(120) NOT NULL,
" +
"Director VARCHAR(80) NULL, " +
"YearReleased SHORT, " +
"Rating TEXT(20) NULL);",
out obj, 0);
Console.WriteLine("A new table named Videos has been
created");
conVideos.Close();
return 0;
}
}
Default Values
To specify a default value, after the name and the data type of a column,
type DEFAULT and assign it the desired value, based on the data type. Here is
an example:
using System;
using ADODB;
conVideos.Open("Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data
Source='C:\\Programs\\VideoCollection.mdb'",
"", "", 0);
conVideos.Execute("CREATE TABLE Videos(" +
"ShelfNumber COUNTER, " +
"VideoTitle STRING(120) NOT NULL, "
+
"Director VARCHAR(80) NULL, " +
"YearReleased SHORT, " +
"Rating TEXT(20) NULL
Default='PG-13')",
out obj, 0);
Console.WriteLine("A new table named Videos has been
created");
conVideos.Close();
return 0;
}
}
Overview of Numbers
Introduction
To perform the basic algebraic and geometric operations in C#, you can use
methods of the Math class of the .NET Framework. As seen in the previous
lesson, you can also take advantage of Visual Basic's very powerful library of
functions. This library is one of the most extended set of functions of various
area of business mathematics.
class Program
{
static int Main()
{
short sNumber;
int iNumber;
double dNumber;
decimal mNumber;
return 0;
}
}
return 0;
}
}
To find out about the sign of a value or a numeric variable, you can call the
Math.Sign() method. It is overloaded in various versions whose syntaxes are:
public static int Sign(sbyte value);
public static int Sign(short value);
public static int Sign(int value);
public static int Sign(long value);
public static int Sign(sbyte value);
public static int Sign(double value);
public static int Sign(decimal value);
When calling this method, pass the value or the variable you want to
consider, as argument. The method returns:
0 if the argument is 0
return 0;
}
}
To get the integral part of a decimal number, the Math class can assist you
with the Trancate() method, which is overloaded in two versions whose
syntaxes are:
public static double Truncate(double d);
public static double Truncate(double d);
class Program
{
return 0;
}
}
If you have two numbers, you can find the minimum of both without writing
your own code. To assist you with this, the Math class is equipped with a
method named Min. This method is overloaded in various versions with each
version adapted to each integral or floating-point data type. The syntaxes
are:
public static byte Min(byte val1, byte val2);
public static sbyte Min(sbyte val1, sbyte val2);
public static short Min(short val1, short val2);
public static ushort Min(ushort val1, ushort val2);
public static int Min(int val1, int val2);
public static uint Min(uint val1, uint val2);
public static float Min(float val1, float val2);
public static long Min(long val1, long val2);
public static ulong Min(ulong val1, ulong val2);
public static double Min(double val1, double val2);
public static decimal Min(decimal val1, decimal val2);
class Program
{
static int Main()
{
int number1 = 8025;
int number2 = 73;
return 0;
}
}
class Program
{
static int Main()
{
int number1 = 8025;
int number2 = 73;
return 0;
}
}
Value Conversions
Implicit Conversions
Memory
Data Type Name
Size
As you can see, a value held by a Byte variable can fit in the memory
reserved for an int variable, which can be carried by a long variable. Thanks
to this, you can assign a Byte value to an int variable, or an int variable to a
long variable. Also, based on this, because the memory reserved for an int
class Program
{
static int Main()
{
int iNumber = 2445;
double dNumber = iNumber;
Explicit Conversions
class Program
{
static int Main()
{
int iNumber = 168;
short sNumber = iNumber;
class Program
{
static int Main()
{
int iNumber = 168;
short sNumber = (short)iNumber;
When performing explicit conversion, you should pay close attention to the
value that is being cast. If you want an integer value to be assigned to a
short variable, the value must fit in 16 bits, which means it must be between
-32768 and 32767. Any value beyond this range would proceed an
unpredictable result. Consider the following program:
using System;
class Program
{
static int Main()
{
int iNumber = 680044;
short sNumber = (short)iNumber;
In Lesson 6 and Lesson 17, we saw that each C# data type, which is
adapted from a .NET Framework structure, was equipped with a ToString()
method that could be used to convert its value to a String type. We didn't
address the possibility of converting a value from one primitive type to
another. To support the conversion of a value from one type to another,
the .NET Framework provides a class named Convert. This class is equipped
with various static methods; they are so numerous that we cannot review all
of them.
Remember that each primitive data type of the C# language is type-defined from
a .NET Framework structure as follows:
.NET
C# Data Type Name Framework
Structure
Unsigned Small
ushort UInt16
Integer
Single-Precision
float Single
Floating-Point
Double-Precision
double Double
Floating-Point
Extended Precision
decimal Floating-Point Decimal
Number
To adapt the Convert class to each C# data type, the class is equipped with
a static method whose name starts with To, ends with the .NET Framework
name of its structure, and takes as argument the type that needs to be
converted. Based on this, to convert a decimal number of a double type to a
number of int type, you can call the ToInt32() method and pass the
double variable as argument. Its syntax is:
Here is an example:
using System;
class Program
{
static int Main()
{
double dNumber = 34987.68D;
int iNumber = Convert.ToInt32(dNumber);
Arithmetic
Absolute Values
The decimal numeric system counts from negative infinity to positive infinity.
This means that numbers are usually negative or positive, depending on their
position from 0, which is considered as neutral. In some operations, the
number considered will need to be only positive even if it is provided in a
negative format. The absolute value of a number x is x if the number is
(already) positive. If the number is negative, its absolute value is its positive
equivalent. For example, the absolute value of 12 is 12, while the absolute
value of –12 is 12.
To get the absolute value of a number, the Math class is equipped with a
method named Abs, which is overloaded in various versions. Their syntaxes
are:
public static sbyte Abs(sbyte value);
public static short Abs(short value);
public static int Abs(int value);
public static float Abs(float value);
public static double Abs(double value);
public static long Abs(long value);
public static decimal Abs(decimal value);
This method takes the argument whose absolute value must be fond. Here is
an example:
using System;
class Program
{
static int Main()
{
int number = -6844;
To support the finding of a ceiling, the Math class is equipped with a method
named Ceiling that is overloaded with two versions whose syntaxes are:
public static double Ceiling(double a);
public static decimal Ceiling(decimal d);
class Program
{
static int Main()
{
double value1 = 155.55; double value2 = -24.06;
Besides the Math class, the Double structure provides its own implementation
of this method using the following syntax:
public static decimal Ceiling(decimal d);
To assist you with finding the floor of a number, the Math class provides the
Floor() method. It is overloaded in two versions whose syntaxes are:
The floor() method takes the considered value as the argument and returns
the integer that is less than or equal to Value. Here is an example:
using System;
class Program
{
static int Main()
{
double value1 = 1540.25;
double value2 = -360.04;
Instead of using the Math class, the Double structure also has a method to
find the floor of a decimal number. Its syntax is:
public static decimal Ceiling(decimal d);
To support this operation, the Math class is equipped with a method named
Pow whose syntax is
This method takes two arguments. The first argument, x, is used as the base
number to be evaluated. The second argument, y, also called the exponent,
will raise x to this value. Here is an example:
using System;
class Program
{
static int Main()
{
const double source = 25.38;
const double exp = 3.12;
The Exponential
You can calculate the exponential value of a number. To support this, the
Math class provides the Exp() method. Its syntax is:
public static double Exp (double d);
class Program
{
static int Main()
{
Console.WriteLine("The exponential of {0} is {1}",
709.78222656, Math.Exp(709.78222656));
return 0;
}
}
To calculate the natural logarithm of a number, you can call the Math.Log()
method. It is provides in two versions. The syntax of one is:
public static double Log(double d);
Here is an example:
using System;
class Program
{
static int Main()
{
double log = 12.48D;
return 0;
}
}
which is equivalent to
x = 10y
Here is an example:
using System;
class Program
return 0;
}
}
The variable whose logarithmic value will be calculated is passed as the first
argument to the method. The second argument allows you to specify a base
of your choice. The method uses the formula:
Y = logNewBasex
class Program
{
static int Main()
{
double logN = 12.48D;
return 0;
}
}
You can calculate the square root of a decimal positive number. To support
this, the Math class is equipped with a method named Sqrt whose syntax is:
public static double Sqrt(double d);
class Program
{
static int Main()
{
double sqrt = 8025.73D;
return 0;
}
}
Trigonometry
Introduction
Therefore, an angle is the ratio of an arc over the radius. Because an angle is
a ratio and not a “physical” measurement, which means an angle is not a
dimension, it is independent of the size of a circle. Obviously this angle
represents the number of portions included by the three points. A better unit
used to measure an angle is the radian or rad.
A cycle is a measurement of the rotation around the circle. Since the rotation
is not necessarily complete, depending on the scenario, a measure is made
based on the angle that was covered during the rotation. A cycle could cover
part of the circle in which case the rotation would not have been completed.
A cycle could also cover the whole 360˚ of the circle and continue there after.
A cycle is equivalent to the radian divided by 2 * Pi.
The Pi Constant
To perform conversions between the degree and the radian, you can use the
formula:
To calculate the cosine of an angle, the Math class provides the Cos()
method. Its syntax is:
public static double Cos(double d);
Here is an example:
using System;
class Program
{
static int Main()
{
int number = 82;
To calculate the sine of a value, you can call the Sin() method of the Math
class. Its syntax is:
public static double Sin(double a);
Here is an example:
using System;
class Program
{
static int Main()
{
double number = 82.55;
return 0;
}
}
Tangents
Here is an example:
class Program
{
static int Main()
{
uint number = 225;
return 0;
}
}
Here is an example:
using System;
class Program
{
static int Main()
{
short number = 225;
return 0;
}
}
Introduction
The group of units between two midnight points is called a day. The days are
counted from 0, 1, and up. A group of seven consecutive days is called a
week. The weeks are counted from 1 and up. To make it easy to identify a
day, the days of a week are named as Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday, and Sunday. These are referred to as long
names. The corresponding short names are Mon, Tue, Wed, Thu, Fri, Sat,
and Sun. The day considered as the first of the week depends on the
language and/or some other considerations. For example, in US English,
Sunday is usually considered the first day of the week.
Most of the time, a group of four weeks is called a month. The months are
counted from 1 and up. To make it easy to identify a month, each holds a
long name and they are January, February, March, April, May, June, July,
August, September, October, November, and December. Their short names
are Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, and Dec. Except for
the month of February that depends on a factor named Leap Year, the
maximum days of each month are January=31, March=31, April=30,
May=31, June=30, July=31, August=31, September=30, October=31,
November=30, and December=31.
In a regular year, the months are counted from 1 to 12. The technique or
expression used to identify a particular day during a year is called a date. The
days are counted from 1 to 365 or 366 (depending on a factor called a leap
year). A date can be the combination of a day, its months, and the year.
There are other aspects that can be taken into consideration. We will address
them when necessary.
A unit of measure in a day is called a second. The seconds are counted from
0 to 59 or from 0, 1, 2, and so on. In some applications, when precision is
particularly important, a second is considered a group of 1000 portions called
milliseconds. The milliseconds are counted from 0 to 999.
The default constructor allows you to create a date or a time object without
specifying its details. This would be done as follows:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime tm = new DateTime();
return 0;
}
}
}
You can access the information using the variable. The pieces of information
are represented by properties of the DateTime structure and they are:
Month: The Month property is the numeric value, between 1 and 12, of
the month of the variable
Day: The Day property is the numeric value of the day in the Month
value of the variable. Depending on the month, the value is between 1
and 31. For example, if the variable's value is April 6, 2002, the Day
value is 6
Year: The Year property is the numeric value of the year of the variable
Date: The Date property is the combination of the Month, the Day, and
the Year values of the variable
Hour: The Hour is the numeric value of the hour, between 0 and 23, of
the time component of the variable
Minute: The Minute is the numeric value of the minute inside of the
Hour value of the variable. It is a value between 0 and 59
Second: The Second is the numeric value of the second inside of the
Minute value of the Hour value. It is a value between 0 and 59
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime tm = new DateTime();
This also means that the lowest date and time values that a DateTime object
can hold is January 1st, 0001 at 00:00:00. This value is represented by the
MinValue constant member of the DateTime structure. The highest date and
time that a DateTime object can hold in the structure is called MaxValue and
it is set at December 31, 9999.
Dates
Date Creation
namespace DateAndTime
{
class Program
{
static int Main()
Before displaying a DateTime value in your application, you can first convert
it to a string. To support this, the DateTime structure provides the
ToString() method that is overloaded with various versions. One of the
versions takes no argument and its syntax is:
public override string ToString();
If you call this version of the method, the compiler uses a default format
depending on the language set on the user's computer. If you want to
control how the date should be rendered, you can use the version of the
ToString() method that takes as argument a String value.
The computer uses two main categories of date display. These categories are
based on the language used by your computer. For example, most user
computers that reside in the United States use a standard known as US
English. This commands how the date displays in the continental US. Each
category uses specific characters to represent its value:
Format Description
namespace DateAndTime
{
class Program
{
static int Main()
{
MMM The triple M as MMM (in uppercase) gets the name of the
month using three letters. This variable is defined by the
operating system. The names of the month in US English are
Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, and
Dec. Here is an example:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime date = new DateTime(1998, 1,
12);
string strMonth =
date.ToString("MMM");
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime date = new DateTime(2004, 10,
23);
string strMonth =
date.ToString("MMMM");
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime date = new DateTime(2002, 4,
2);
string strDay = date.ToString("dd");
yy The double y is used to get the numeric year with the last two
digits. Here is an example:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime date = new DateTime(2002, 4,
2);
string strYear2Digits =
date.ToString("yy");
yyyy The yyyy string is used to get all four digits of a year. Here is
an example:
using System;
namespace DateAndTime
{
If the year was provided with two digits, such as 98, it would
still be produced with 4 digits. Consider the following
example:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime date = new DateTime(98, 4,
2);
string strYear4Digits =
date.ToString("yyyy");
Notice that this may be a wrong date. For this reason, in your C#
applications, you should always make it a habit to (always) provide
your years with 4 digits.
Date Formats
You may have notice that, by default, a DateTime object always produces
both a date and a time. In some cases, you will be interested in only the date
portion of the object. To get a date value, you can call the
DateTime.ToString() method that takes a String as argument and apply some
rules:
Others: Dash and Others: Besides the forward slash, the user's
- . computer may allow other characters. For example, in US
English, the "-" can be used. You can check available
The other characters and their combinations (MM, MMM, MMMM, dd, yy, and
yyyy) are used as we reviewed them.
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime date = new DateTime(2004, 10, 23);
Instead of creating your own format, the Microsoft Windows operating system
provides two names that can be used to identify a date. A date is referred to
as short if it includes (only) the numeric portions of the month and the day of
a date value. The operating systems follows the rules we have reviewed so
far for the numbers and the Date Separator. The possible formats of a short
To get the Short Date of a DateTime object, pass a "d" (one d in lowercase)
string to the ToString() method. Here is an example:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime date = new DateTime(2004, 10, 23);
string strDate = date.ToString("d");
A date is referred to as long if it includes the names of the month and the day
of the week of a date value. This is called the Long Date Format. To get the
Long Date of a date, pass a "D" (one d in uppercase) string to the
ToString() method of a DateTime object. Here is an example:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime date = new DateTime(2004, 10, 23);
string strDate = date.ToString("D");
To produce the result, the compiler refers to the Long Date Format combo
box of the Customize Regional Options of the Control Panel. The user can
change the format by selecting one from the combo box:
The .NET Framework provides other formats, not regularly used but available.
To get the name of a month and the year value of a DateTime object, both
separated by an empty space, pass a single M (uppercase) as string to the
ToString() method of a DateTime object. Here is an example:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime date = new DateTime(2004, 10, 23);
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime date = new DateTime(2004, 10, 23);
string strDate = date.ToString("y");
Operations on Dates
One of the operations performed on date values is to find out whether the
year value of a date is a leap year. Fortunately, the static IsLeapYear()
method of the DateTime structure can be used to perform this operation. The
syntax of this function is:
This method takes an integer argument and examines it. If the argument,
which must be a valid year number, is a leap year, the method returns true;
otherwise, it would return false. Here are two examples:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime date = new DateTime(1988, 10, 6);
Console.WriteLine("{0} was a leap year: {1}",
date.Year,
DateTime.IsLeapYear(date.Year));
return 0;
}
}
}
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime date = new DateTime(1988, 10, 6);
return 0;
}
}
}
A Time Span
Dates are some of the most important values of the operating system and
many applications need them to perform their routine operations. Common
operations include adding days to a date, subtracting months from a date,
adding years, comparing dates to find out whether one occurs before
another, finding out if a payroll falls on a holiday, etc. To perform some of
these operations, a unit called an interval is considered as part of a date. A
date interval is the number of days, months, or years that have elapsed, or
would elapse, from one starting date to another ending date. Once you have
specified this interval, you can then apply it to a date with the operation of
your choice.
With the DateTime structure, you can add some days to an existing date or
subtract some days from a date value. To support this, the DateTime
structure is equipped with the AddDays() method. Its syntax is:
public DateTime AddDays(int days);
namespace DateAndTime
{
class Program
{
static int Main()
return 0;
}
}
}
One of the constructors of the TimeSpan structure takes four arguments. Its
syntax
public TimeSpan(int days, int hours, int minutes, int seconds);
The first argument of this constructor represents the number of days. If you
are planning to add a number of days to a date, pass a positive integer as the
first argument. If you want to subtract a date, pass a negative value. If you
want to add only a number of days, pass only this argument.
After creating a TimeSpan object, you can call the Add() method of the
DateTime structure to a date value. This would produce a new DateTime
object that is the resulting value. Here are examples:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime startDate = new DateTime(1988, 10, 6);
Console.WriteLine("Starting Date: {0}\n",
startDate);
return 0;
}
}
}
Notice that, when adding or subtracting days, the complier can figure out the
previous day, the previous month, the previous year, the following day, the
following month, or the following year.
To get the date a few years before or after a known date, you can add years
to, or subtract years from, a known date. To support this operation, the
DateTime class provides a method named AddYears(). Its syntax is:
Using the logical operators we reviewed for primitive types, you can compare
the values of dates for equality, differences, lower or greater values. To
support these operations, the DateTime structure have the logical operators
configured.
To compare two dates, apply the desired Boolean operator the same day you
would two variables of primitive types. Here is an example:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime startDate = new DateTime(1988, 10, 6);
Console.WriteLine("Starting Date: {0}", startDate);
return 0;
}
}
}
Time
As defined earlier, the time is a value used to identify the number of units
that have elapsed since a starting period, called midnight, of a day. A day is
made of 24 non-spatial divisions; each one of these divisions is called an
hour. An hour is made of 60 fractions and each one of these fractions is called
a minute. A minute is divided in 60 parts, each called a second. As done with
dates, most of the operations performed on time values are centered around
the DateTime structure.
The rules used by the computer for time display can be seen in the Customize
Regional Options dialog box. To access it, in the Control Panel, you can
double-click Regional and Language Options. In the Regional Options tab of
the Regional and Language Options dialog box, you can click Customize. In
the Customize Regional Options, you can click Time:
In US English, the symbol to separate the hour and the minute. An example
would be: 08:25. In the same way, in US English, the character used to
separate the minute and the second is “:”. An example would be: 08:25 :44.
In many cases, unless necessary, the second is not represented in a time
value.
If you are more concerned about the time, the first, second, and third
arguments are not important. You can pass each as 1. In this case, the date
would be set as January 1, 0001. The other three arguments represent the
components of a time value.
The minutes value must range from 0 to 59; otherwise, an error would be
produced (when studying exception handling, we will see that this means that
the compiler would throw an exception). The seconds value must be between
0 and 59 or the program would cause an error.
When initializing a date or time variable using this constructor, the hour value
must be between 0 and 23. Any other value outside of this range will cause
an error. If the hour portion has a value between 0 and 11, the time is set in
the morning with the AM in the AM/PM section. Here is an example:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime time = new DateTime(1, 1, 1, 10, 24, 52);
If the hour portion is between 12 and 23, the time is set in the afternoon.
When displaying it, the compiler, by default, calculates and displays the 0 to
12 portion and then displays PM in the AM/PM section. Here is an example:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime time = new DateTime(1, 1, 1, 16, 8, 44);
In extreme cases, you may want to use the milliseconds of a time value.
When declaring and initializing the variable, you can use the following
constructor:
public DateTime(int year, int month, int day,
int hour, int minute, int second, int
millisecond);
The milliseconds must range from 0 to 999. If you do not know the
millisecond value, you can provide it as 0.
In a certain application, you may want the user to supply a time value. As
mentioned for the date, there are rules that you, the computer, and the user
must follow to apply a valid formula. As mentioned earlier, the compiler refers
to the computer to find out what a date looks like. A valid time can follow the
format hh:nn AM/PM or hh:nn:ss or one of the valid combinations. When
requesting a time from the user, in case the user is not familiar with the rules
(and you should assume that the user doesn't know them), specify what
formula the user should follow. Here is an example:
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime dateSubmitted;
By now, we have seen that a time value is made of the hour, the minute, the
second, and the millisecond parts. These are values you can specify when
creating a time object using one of the appropriate constructors of the
DateTime structure. If you request a time value from the user or if the
application itself will provide it, you can retrieve its components.
To get the hour portion of an existing DateTime object, you can access its
Hour property. To retrieve the minute side of a time value, access its Minute
property. If you want to know the second value of a DateTime variable, you
can call its Second property. In the same way, you can get the millisecond
value of a time by accessing its Millisecond property.
As seen so far, a DateTime variable always holds both a date and a time
portions. In your program, you may want to get only the time of the variable.
To support this, the DateTime structure is equipped with a property named
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime time = new DateTime(2002, 4, 22, 16, 8,
44);
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime time = new DateTime(2002, 4, 22, 16, 8,
44);
string strTime = time.ToString();
Notice that the value produced by the string includes both the date, the time
and even the AM/PM section. In some cases, you would be interested only in
either the date or the time. To support this type of operation, the DateTime
structure has another overloaded version of the ToString() method that
takes as argument a String value. Its syntax is:
public string ToString(string format);
When calling this method, there are rules you should/must follow.
Like dates, time values follow the Regional (and Language) Settings of
Control Panel when they display. To make this display friendlier, Microsoft
Windows provides the rules, through some characters, you can use to format
a time:
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime time = new DateTime(2002, 4,
22, 5, 8, 37);
string strHour = time.ToString("hh");
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime time = new DateTime(2002, 4,
22, 15, 8, 37);
string strHour = time.ToString("hh");
namespace DateAndTime
{
class Program
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime time = new DateTime(2002, 4,
22, 15, 8, 37);
string strMinute = time.ToString("mm");
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime time = new DateTime(2002, 4,
22, 15, 8, 7);
string strSecond = time.ToString("ss");
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime time = new DateTime(2002, 4,
22, 5, 8, 7);
string strAMPM = time.ToString("tt");
m
Minutes A minute number from 0 to 59.
If the number is less than 10, it would display without the
leading 0. Here is an example:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime time = new DateTime(2002, 4,
22, 15, 8, 37);
string strMinute =
time.ToString("h:m");
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime time = new DateTime(2002, 4,
22, 15, 8, 37);
string strMinute =
time.ToString("h:mm");
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime time = new DateTime(2002, 4,
22, 15, 8, 7);
string strSecond =
time.ToString("h:mm:s");
namespace DateAndTime
{
class Program
{
static int Main()
{
DateTime time = new DateTime(2002, 4,
22, 15, 8, 7);
string strSecond =
time.ToString("h:mm:ss");
When combining these characters to create a format, you should abide by the
rules of your language, such as US English. You should refer to the formula
set in the Time property page of the Regional (and Language) Settings of
Control Panel.
As done for date values, you can compare time values to find out if one
occurs before another or whether they occur at the same time. To support
the comparisons, the DateTime structure is equipped with the Compare()
method.
When a user starts a computer and while using it, it keeps a date and time
values referred to as local date and time or system date and time. Depending
on your application, at one time you may need to get one or both of these
pieces of information. It is important to know that the computer, not you,
controls this information (but you can programmatically change it if you
want). To support both, the DateTime structure is equipped with a static
property named Now. This property holds the year, the month, the day, the
name of the day, the hour, the minute, and the second. Here is an example
of calling it:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
Console.WriteLine("System Date and Time: {0}",
DateTime.Now);
To get the current date of the computer, the DateTime structure provides a
static property named Today. Here is an example:
using System;
namespace DateAndTime
{
class Program
{
static int Main()
{
Console.WriteLine("Current Date: {0}",
DateTime.Today);
return 0;
}
}
}
Description
On a typical application, a button is an object that the user clicks to perform
an action. To make this obvious, a button is a control surrounded by thick
borders. Here is an example of a button on a form:
namespace Algebra2
{
public class Algebra
{
public static long Factorial(long x)
{
if (x <= 1)
return 1;
else
return x * Factorial(x - 1);
}
6. Type Exercise.cs and press Enter twice (to save and to open the form)
8. In the Containers section of the Toolbox, click TabControl and click the
form
9. On the form, right-click the right side of tabPage2 and click Add Page
HotTrack: True
TabControl tclAlgebra Location: 12, 12
Size: 304, 235
TextAlign: Right
TextBox txtNumber Location: 88, 18
Size: 50, 20
TextAlign: Right
TextBox txtFactorial Location: 88, 54
Size: 140, 20
Label n: 22, 21
Label r: 22, 56
Label n: 22, 21
Label r: 22, 56
Creating a Button
To support the buttons of an application, the .NET Framework provides an
abstract class named ButtonBase. The regular button of Microsoft Windows
is implemented by the Button class. At design time, to add a button to your
project, from the Common Controls section of the Toolbox, you can click the
Button and click the form or another container.
public Exercise()
{
InitializeComponent();
}
this.Controls.Add(btnResume);
}
}
2. From the Common Controls section of the Toolbox, click Button and click
on the right side of the top text box
After adding a button to a form (by design or with code), you can change its
caption with code by assigning the desired string to the Text property. For
example, you can change the caption of a button as follows:
button1.Text = "Let it Go!";
After specifying the Text of a button, by default, it's positioned in the middle
center of the button:
public Exercise()
{
InitializeComponent();
}
Controls.Add(btnResume);
}
}
4. Access the Factorial tab page and double-click its Calculate button
try
{
number = long.Parse(txtFactNumber.Text);
result = Algebra.Factorial(number);
txtFactorial.Text = result.ToString();
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
}
7. Access the Permutation tab page and double-click its Calculate button
try
{
n = long.Parse(txtPermutationN.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
try
{
r = long.Parse(txtPermutationR.Text);
result = Algebra.Permutation(n, r);
txtPermutation.Text = result.ToString();
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
}
10. Access the Combination tab page and double-click its Calculate button
try
{
n = long.Parse(txtCombinationN.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
try
{
r = long.Parse(txtCombinationR.Text);
result = Algebra.Combinatorial(n, r);
txtCombination.Text = result.ToString();
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
Controls.Add(btnResume);
}
By default, both the caption and the image display ion the middle-center of
the button. To make them distinct and allow the user to see both, you can
design a bitmap that has both and assign that bitmap as the image of the
button. Alternatively, you can use a separate string and a separate picture.
Controls.Add(btnResume);
}
Instead of using the Image property, you can first create an image list and
add some pictures to it. Then, using the ImageList property, assign it to the
button. Use the ImageIndex property to specify what picture would be displayed
on the button.
Flat: The button appears flat. When the mouse is over it, it becomes
highlighted
Popup: The button appears flat. When the mouse is over it, the borders
of the button are raised
Obviously the most important and the most intuitive event of a button occurs
when clicked. This event is of type EventArgs, which indicates that it doesn't
provide nor does it need any formal details about what is going on. To launch
this event, you can double-click the button on the form. To create this event
programmatically, first implement the method that would carry its
assignment, then increment-add (with the += operator) it to the Click
property of the button by assigning it the EventHandler constructor.
When creating a form or a dialog box, after adding a button, in the Properties
window, click DialogResult and select on the values:
Except for None, by default, it does not matter what value you select but, you
should follow Windows standard to select the right value.
After specifying the returned value of a button, access the properties of the
form or dialog box:
After configuring the DialogResult of the button(s), when the user clicks
one of the buttons to close the form or dialog box, you can get the value of
the Form.ShowDialog() method which returns one of the values of the
DialogResult enumeration.
Applications:
Algebra
Simple Interest
Description
A combo box is a list of items that the user can select from. Like a list box, a
combo box is usually made of a list of strings. Unlike a list box, a combo box
saves space by using just as much room as a text box control. To show that it
is holding a list, a combo box displays a down-pointing arrow on the right side
of its text box. In the following screenshot, the Font Effects property page of
the Character dialog box of OpenOffice.org presents the Underlining, the
Color, the Effects, the Strikethrough, the Relief, and the Font Color combo
boxes:
Because a combo box does not (permanently) display its list like a list box, to
show its content, the user can click the arrow button. Here is an example:
public Exercise()
{
InitializeComponent();
}
Controls.Add(cbxAcademicDisciplines);
}
}
Font: Microsoft
Label Year Sans Serif, 8.25pt,
style=Bold
Microsoft Sans
Label Make Serif, 8.25pt,
style=Bold
Microsoft Sans
Label Model Serif, 8.25pt,
style=Bold
ComboBox cbxCarYears
ComboBox cbxMakes
ComboBox cbxModels
ComboBox cbxCategories
Font: Microsoft
Label Available Parts Sans Serif, 9.75pt,
style=Bold
ListBox lbxPartNumbers
ListBox lbxPartNames
ListBox lbxUnitPrices
Customer
GroupBox Selected
Items
Label Part #
TextBox txtPartNumber1
TextBox txtPartName1
TextBox txtPartNumber2
TextBox txtPartName2
TextBox txtPartNumber3
TextBox txtPartNumber4
TextBox txtPartName4
TextBox txtPartNumber5
TextBox txtPartName5
TextBox txtPartNumber6
TextBox txtPartName6
Introduction
Like all visual controls, a combo box shares all the basic characteristics of
other graphic control: the name, the location, the size, the ability to be
enabled or disabled, the ability to hide or show it, the ability to dock or
anchor, etc.
The Items property of the ComboBox class is created from the nested
ObjectCollection class. This class has the same functionality and features
as its counterpart of the list box. This means that, to programmatically create
of items, you can (continuously) call the ObjectCollection.Add() method.
Here is an example:
public class Exercise : System.Windows.Forms.Form
{
Label lblTitle;
ComboBox cbxAcademicDisciplines;
public Exercise()
{
InitializeComponent();
}
Controls.Add(cbxAcademicDisciplines);
}
}
To add an array of items, you can call the AddRange() method. To insert an
item somewhere inside the list, you can call the Insert() method.
If you want the list of items to be sorted, you can change the value of the
Sorted property in the Properties window from False (the default) to True.
To sort a list programmatically, you can assign a true value to the Sorted
property. You can un-sort the list by changing the value of the Sorted
property. This property works exactly like its equivalent in the ListBox control.
this.cbxCarYears.Items.Add(i);
}
Instead of using of using the index of an item, to select an item using its
identity or name, you can use the SelectedItem property. To select an item
by its name, assign it to the SelectedItem property.
3. To create a class that can holds a structured item of a list, change the
class as follows:
using System;
namespace CollegeParkAutoParts1
{
public class PartDescription
{
private long ID;
private int yr;
private string mk;
private string mdl;
private string cat;
private string name;
private decimal price;
public PartDescription()
{
this.ID = 0;
this.yr = 1960;
this.mk = "";
this.mdl = "";
this.name = "Unknown";
this.price = 0.00M;
}
namespace CollegeParkAutoParts1
{
public partial class Central : Form
{
PartDescription[] parts = new PartDescription[56];
public Central()
{
InitializeComponent();
}
6. To display the list of car makes when the user selects a year, implement
the event as follows:
private void cbxCarYears_SelectedIndexChanged(object sender,
EventArgs e)
{
cbxMakes.Text = "";
cbxMakes.Items.Clear();
cbxModels.Text = "";
cbxModels.Items.Clear();
cbxCategories.Text = "";
cbxCategories.Items.Clear();
lbxPartNumbers.Items.Clear();
lbxPartNames.Items.Clear();
lbxUnitPrices.Items.Clear();
8. To display the list of car models when the user has selected a year and a
make, implement the event as follows:
private void cbxMakes_SelectedIndexChanged(object sender,
EventArgs e)
{
cbxModels.Text = "";
cbxModels.Items.Clear();
cbxCategories.Text = "";
cbxCategories.Items.Clear();
lbxPartNumbers.Items.Clear();
lbxPartNames.Items.Clear();
lbxUnitPrices.Items.Clear();
10. To display the list of categories after the user has selected the year, the
make, and the model, implement the event as follows:
private void cbxModels_SelectedIndexChanged(object sender,
EventArgs e)
{
lbxPartNumbers.Items.Clear();
lbxPartNames.Items.Clear();
lbxUnitPrices.Items.Clear();
11. Return to the form and double-click the Category combo box
12. To display the list of available parts, implement the event and define a
new method as follows:
private void cbxCategories_SelectedIndexChanged(object sender,
EventArgs e)
{
lbxPartNumbers.Items.Clear();
lbxPartNames.Items.Clear();
lbxUnitPrices.Items.Clear();
lbxPartNumbers.Items.Add(part.PartNumber.ToString());
lbxPartNames.Items.Add(part.PartName);
lbxUnitPrices.Items.Add(part.UnitPrice.ToString());
}
}
14. When the user clicks an item from the Part Numbers list box, to make
sure the corresponding item is selected in the other list boxes,
implement the event as follows:
private void lbxPartNumbers_SelectedIndexChanged(object sender,
EventArgs e)
{
lbxUnitPrices.SelectedIndex =
lbxPartNames.SelectedIndex =
lbxPartNumbers.SelectedIndex;
}
15. Return to the form and double-click the lbxPartNames list box
17. Return to the form and double-click the lbxUnitPrices list box
19. Return to the form and click (once) the lbxPartNumbers list combo box
20. In the Properties window, click the Events button and, in the Events
section, double-click DoubleClick
try
{
subTotal2 =
decimal.Parse(this.txtSubTotal2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal3 =
decimal.Parse(this.txtSubTotal3.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal4 =
decimal.Parse(this.txtSubTotal4.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal5 =
decimal.Parse(this.txtSubTotal5.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
txtQuantity2.Text = "1";
txtSubTotal2.Text = txtUnitPrice2.Text;
txtQuantity3.Text = "1";
txtSubTotal3.Text = txtUnitPrice3.Text;
txtQuantity3.Focus();
}
else if (txtPartNumber4.Text == "")
{
txtPartNumber4.Text =
(string)lbxPartNumbers.SelectedItem;
txtPartName4.Text =
(string)lbxPartNames.SelectedItem;
txtUnitPrice4.Text =
(string)lbxUnitPrices.SelectedItem;
txtQuantity4.Text = "1";
txtSubTotal4.Text = txtUnitPrice4.Text;
txtQuantity4.Focus();
}
else if (txtPartNumber5.Text == "")
{
txtPartNumber5.Text =
(string)lbxPartNumbers.SelectedItem;
txtPartName5.Text =
(string)lbxPartNames.SelectedItem;
txtUnitPrice5.Text =
(string)lbxUnitPrices.SelectedItem;
txtQuantity5.Text = "1";
txtSubTotal5.Text = txtUnitPrice5.Text;
txtQuantity5.Focus();
}
else if (txtPartNumber6.Text == "")
{
txtPartNumber6.Text =
(string)lbxPartNumbers.SelectedItem;
txtPartName6.Text =
(string)lbxPartNames.SelectedItem;
txtUnitPrice6.Text =
(string)lbxUnitPrices.SelectedItem;
txtQuantity6.Text = "1";
txtSubTotal6.Text = txtUnitPrice6.Text;
txtQuantity6.Focus();
} // If all Part # text boxes are filled, don't do
anything
else
CalculateOrder();
}
22. Return to the form and click (once) the lbxPartNames list box
25. Return to the form and click (once) the lbxUnitPrices list box
28. Display the form and click the first text box under Qty
29. In the Properties window and in the Events section, double-click the
Leave field
31. Return to the form and click the second text box under Qty
32. In the Events section of the Properties window, double-click the Leave
field and implement the event as follows:
private void txtQuantity2_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice =
decimal.Parse(this.txtUnitPrice2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
CalculateOrder();
}
33. Return to the form and click the third text box under Qty
34. In the Events section of the Properties window, double-click the Leave
field and implement the event as follows:
private void txtQuantity3_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity3.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice =
decimal.Parse(this.txtUnitPrice3.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
CalculateOrder();
}
35. Return to the form and click the fourth text box under Qty
36. In the Events section of the Properties window, double-click the Leave
field and implement the event as follows:
private void txtQuantity4_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity4.Text);
}
try
{
unitPrice =
decimal.Parse(this.txtUnitPrice4.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
CalculateOrder();
}
37. Return to the form and click the fifth text box under Qty
38. In the Events section of the Properties window, double-click the Leave
field and implement the event as follows:
private void txtQuantity5_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity5.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice =
decimal.Parse(this.txtUnitPrice5.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
CalculateOrder();
}
40. In the Events section of the Properties window, double-click the Leave
field and implement the event as follows:
private void txtQuantity6_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity6.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice =
decimal.Parse(this.txtUnitPrice6.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
CalculateOrder();
}
42. Double-click the first Remove button and implement its event as follows:
private void btnRemove1_Click(object sender, EventArgs e)
{
txtPartNumber1.Text = "";
txtPartName1.Text = "";
txtUnitPrice1.Text = "0.00";
txtQuantity1.Text = "0";
txtSubTotal1.Text = "0.00";
CalculateOrder();
}
46. Double-click the third Remove button and implement its event as
follows:
private void btnRemove3_Click(object sender, EventArgs e)
{
txtPartNumber3.Text = "";
txtPartName3.Text = "";
txtUnitPrice3.Text = "0.00";
txtQuantity3.Text = "0";
txtSubTotal3.Text = "0.00";
CalculateOrder();
}
48. Double-click the fourth Remove button and implement its event as
follows:
private void btnRemove4_Click(object sender, EventArgs e)
{
txtPartNumber4.Text = "";
txtPartName4.Text = "";
txtUnitPrice4.Text = "0.00";
txtQuantity4.Text = "0";
txtSubTotal4.Text = "0.00";
CalculateOrder();
}
50. Double-click the fifth Remove button and implement its event as follows:
private void btnRemove5_Click(object sender, EventArgs e)
{
txtPartNumber5.Text = "";
txtPartName5.Text = "";
52. Double-click the sixth Remove button and implement its event as
follows:
private void btnRemove6_Click(object sender, EventArgs e)
{
txtPartNumber6.Text = "";
txtPartName6.Text = "";
txtUnitPrice6.Text = "0.00";
txtQuantity6.Text = "0";
txtSubTotal6.Text = "0.00";
CalculateOrder();
}
54. Double-click the Close button and implement its Click event as follows:
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
This method takes as argument the string to find in the combo box. If the
item is found in the list, the method returns its position. If the list does not
have that string, the method return -1. The above syntax of the method
would look through the whole list. If you want the search to start at a specific
index, you can use the following version of the FindString() method:
public int FindString(string s, int startIndex);
This method proceeds like the FindString() method by starting to look for the
string from the beginning of the list. If you want to specify from where to
start looking for the string, you should use the following version:
public int FindStringExact(string s, int startIndex);
Standard: This is the default value of the property. It makes the control
appear with raised borders:
private void InitializeComponent()
{
SuspendLayout();
lblTitle = new Label();
lblTitle.Text = "Academic Disciplines";
lblTitle.Location = new Point(12, 12);
lblTitle.AutoSize = true;
cbxAcademicDisciplines.Items.Add("Natural Sciences");
cbxAcademicDisciplines.Items.Add("Mathematics and
Computer Sciences");
cbxAcademicDisciplines.Items.Add("Social Sciences");
cbxAcademicDisciplines.Items.Add("Humanities");
cbxAcademicDisciplines.Items.Add("Professions and
Applied Sciences");
cbxAcademicDisciplines.FlatStyle = FlatStyle.Standard;
Controls.Add(cbxAcademicDisciplines);
}
Popup: The control will appear flat with a surrounding gray line:
cbxAcademicDisciplines.FlatStyle = FlatStyle.Popup;
System: The user's operating system (and theme, if any) will determine
how the control must appear
One of the types of combo boxes is referred to as Drop Down and is created
by setting the DropDownStyle property to DropDown. Here is an example:
private void InitializeComponent()
{
lblTitle = new Label();
lblTitle.Text = "Academic Disciplines";
lblTitle.Location = new Point(12, 12);
lblTitle.AutoSize = true;
Controls.Add(lblTitle);
cbxAcademicDisciplines.DropDownStyle =
ComboBoxStyle.DropDown;
Controls.Add(cbxAcademicDisciplines);
}
This type is made of a text box on the left side and a down-pointing arrowed
button on the right side. Depending on how the control was created, when it
comes up, it may not display anything:
Normally, if you want a DropDown style of combo box to display a string when
the control comes up, you can either enter a value in the Text property or
assign a string to the ComboBox.Text property. Here is an example:
private void InitializeComponent()
{
cbxAcademicDisciplines.DropDownStyle =
ComboBoxStyle.DropDown;
cbxAcademicDisciplines.Text = "Social sciences";
Controls.Add(cbxAcademicDisciplines);
}
The string you give to the Text property does not have to be one of the
items of the list.
To use the combo box, the user can click its down pointing arrow. At any
time, to find out whether the list is displaying, you can check the value of the
DroppedDown Boolean property. In the same way, to drop the list, you can
programmatically set the combo box' DroppedDown property to true.
Once the list is displaying, if the user clicks that arrow, a list would appear (or
expand). If the string assigned to the Text property is one of the items in the
list, it would display in the text box side of the control and it would be
selected in the list. Here is an example:
private void InitializeComponent()
{
lblTitle = new Label();
lblTitle.Text = "Academic Disciplines";
lblTitle.Location = new Point(12, 12);
lblTitle.AutoSize = true;
Controls.Add(lblTitle);
cbxAcademicDisciplines.DropDownStyle =
ComboBoxStyle.DropDown;
cbxAcademicDisciplines.Text = "Social Sciences";
Controls.Add(cbxAcademicDisciplines);
}
If the string assigned to the Text property is not one of the items in the list, it
would still appear selected in the text box side of the control:
Here is an example:
private void InitializeComponent()
{
lblTitle = new Label();
lblTitle.Text = "Academic Disciplines";
lblTitle.Location = new Point(12, 12);
lblTitle.AutoSize = true;
Controls.Add(lblTitle);
cbxAcademicDisciplines.DropDownStyle =
ComboBoxStyle.DropDown;
Controls.Add(cbxAcademicDisciplines);
}
When the list displays, either because the user clicked the arrow button,
pressed Alt + the down arrow key or because you decided to display it, the
control fires a DropDown event, which is of type EventArgs.
If the user sees an item that he or she wants or was asked to select, he or she
can click it. After an item has been clicked, two things happen: 1. the list retracts
(or collapses) like a plastic; 2. the item that was clicked fills the text part and
becomes the new selection:
On the other hand, after displaying the list, if the user doesn't want to select
anything from the list, he or she can click the arrow again or click anywhere
away from the list. The list would collapse and the text part would get back to
the previous text.
Once again, to use the control, the user can click its arrow, which causes the
list to display. The user can also display the list using the keyboard by
pressing Alt + down arrow key after giving focus to the control.
The most regularly used combo boxes are made of text items. You can also
create a combo box that displays colors or pictures. To create such a combo
box, you start by changing the value of the DrawMode property that is set to
Normal by default. If you want to display items that are not just regular text,
you can set this property to either OwnerDrawFixed, which would make all
items have the same height, or OwnerDrawVariable, which allows different
items to have different sizes.
If the combo box has a DropDownStyle other than Simple, there is typically
a fixed number of items that display when the user clicks the control’s arrow.
You can control the number of items that displays using the
MaxDropDownItems property. By default, this is set to 8. If the list contains a
number of items less than the MaxDropDownItems integer value, all of the
items would display fine. If the list contains more than the
MaxDropDownItems number of items, when the user clicks the arrow, a
vertical scroll box would appear. The control would display
In the next previous sections, we saw how to create a list of items. The .NET
Framework provides an alternative. Instead of creating a list from scratch,
you can use one that exists already. For example, you can use a list of
recently accessed web sites or custom list of your own. To assist you with
this, the ComboBox class provides with three techniques.
To specify an external list of items to use for the combo box, you have two
options. You can use the AutoCompleteSource property, that is based on the
AutoCompleteSource enumeration. The members of this enumeration are:
None, RecentlyUsedList, FileSystem, FileSystemDirectories,
HistoryList, ListItems, AllSystemSources, AllUrl, and CustomSource.
Imagine that you want to use the list of web pages you had visited lately. To
use that list, you can specify the AutoCompleteSource as HistoryList.
After specifying the source of the list, use the AutoCompleteMode property to
specify how the combo box (or rather the text box side of the control) will
assist the user. This property is based on the AutoCompleteMode
enumeration that has four members. None is the default value. Imagine you
had set the value of the AutoCompleteSource property as HistoryList. If
you specify AutoCompleteMode as:
Suggest: In the text box part of the combo box, the user can click and
start typing. A list of closely-matched items would display:
Append: In the text box part, the user can start typing. The control would
then start looking for the closest matches and try to complete the user's
entry with those available. Here is an example:
First the user types h and http:// comes up as the first closest match.
Then, the user specifies that the address starts with m and the
compiler suggests, in alphabetical order, the closest URL with that.
Then, the user types ms and finds out that msdn2 is available
The user can continue typing. If the desired item appears in the list, the user can
select it. Otherwise, as the user is typing, the closest match displays in the text
box part of the control
Instead of using an external list, you can create your own. To do this, use the
AutoCompleteCustomSource property. At design time, to create a list of
strings, access the Properties window for the text box. In the Properties
window, click the ellipsis button of the AutoCompleteCustomSource field to
open the String Collection Editor. Enter the strings separated by a hard
Return, and click OK. You can also programmatically create the list. To assist
you, the .NET Framework provides a class named
AutoCompleteStringCollection. The AutoCompleteStringCollection
class implements the IList, the ICollection, and the IEnumerable
interfaces.
After creating the custom list, to let the combo box use it, set the
AutoCompleteMode property to CustomSource.
Introduction
To further assist you with application design, the .NET Framework provides
the flow layout panel that you can use instead of manually positioning your
controls horizontally or vertically. When used horizontally, the flow layout
panel takes care of aligning controls so that all of them would have the same
distance from the top border of their container. Of course, this has to do
only with the controls that belong to the same group (the same container).
The flow layout panel is represented in the .NET Framework by the
FlowLayoutPanel class and in the Toolbox by the FlowLayoutPanel object.
Therefore, to use it, click it from the Toolbox and add it to your form. The
flow layout panel appears as a dotted rectangular object:
After placing it on a form, you can add controls to it. To do this, you would
click a control from the Toolbox and click inside the flow layout panel. When
you add the first control, it gets positioned in the top left side of the container
and you cannot move it to a different position (if this were done it would
deceive the purpose of the flow layout panel):
When you add a second control to the flow layout panel, it is positioned on
the right side of the previously added control with the same horizontal
alignment. You can continue adding other controls. If you want the controls
to be aligned vertically, resize the flow layout panel accordingly:
In the same way, if the flow layout panel is narrow and the controls are
positioned vertically, if you enlarge it, its control would be positioned horizontally.
As you can see, the flow layout panel provides a convenient way of aligning
controls.
As mentioned above, after adding a flow layout panel to a form, if you add a
control to it, the control is positioned in the top-left section. If you add a
second control, it is positioned on the right side of the previous control. This
would be the same with the other subsequent controls. If you add a control
but there is no room on the right side, the control would be positioned on the
next row. If you resize the flow layout panel, the controls would be aligned
After adding a button to a form (by design or with code), you can change its
caption with code by assigning the desired string to the Text property. For
example, you can change the caption of a button as follows:
button1.Text = "Let it Go!";
After specifying the Text of a button, by default, it's positioned in the middle
center of the button:
Here is an example:
public class Exercise : System.Windows.Forms.Form
{
Button btnResume;
public Exercise()
{
InitializeComponent();
}
Controls.Add(btnResume);
}
}
4. Access the Factorial tab page and double-click its Calculate button
try
{
number = long.Parse(txtFactNumber.Text);
result = Algebra.Factorial(number);
txtFactorial.Text = result.ToString();
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
}
7. Access the Permutation tab page and double-click its Calculate button
try
{
r = long.Parse(txtPermutationR.Text);
result = Algebra.Permutation(n, r);
txtPermutation.Text = result.ToString();
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
}
10. Access the Combination tab page and double-click its Calculate button
try
{
n = long.Parse(txtCombinationN.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
try
{
r = long.Parse(txtCombinationR.Text);
result = Algebra.Combinatorial(n, r);
txtCombination.Text = result.ToString();
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
}
Controls.Add(btnResume);
}
By default, both the caption and the image display ion the middle-center of
the button. To make them distinct and allow the user to see both, you can
design a bitmap that has both and assign that bitmap as the image of the
button. Alternatively, you can use a separate string and a separate picture.
Fortunately, each can have its own alignment. We already saw how to control
the alignment of the caption.
Controls.Add(btnResume);
}
Instead of using the Image property, you can first create an image list and
add some pictures to it. Then, using the ImageList property, assign it to the
button. Use the ImageIndex property to specify what picture would be
displayed on the button.
Flat: The button appears flat. When the mouse is over it, it becomes
highlighted
Popup: The button appears flat. When the mouse is over it, the borders
of the button are raised
Standard: The button appears and behave like all regular buttons you
have seen
Obviously the most important and the most intuitive event of a button occurs
when clicked. This event is of type EventArgs, which indicates that it doesn't
provide nor does it need any formal details about what is going on. To launch
this event, you can double-click the button on the form. To create this event
programmatically, first implement the method that would carry its
assignment, then increment-add (with the += operator) it to the Click
property of the button by assigning it the EventHandler constructor.
When creating a form or a dialog box, after adding a button, in the Properties
window, click DialogResult and select on the values:
Except for None, by default, it does not matter what value you select but, you
should follow Windows standard to select the right value.
After specifying the returned value of a button, access the properties of the
form or dialog box:
After configuring the DialogResult of the button(s), when the user clicks
one of the buttons to close the form or dialog box, you can get the value of
the Form.ShowDialog() method which returns one of the values of the
DialogResult enumeration.
Applications:
Algebra
Simple Interest
Introduction
In the past, to add an internet or email link to a form, there were many
steps to follow. As the internet and email had become an integral part of the
culture, it was also time to have an appropriate control adapted for this need.
To address this issue, a control called LinkLabel is available from the .NET
Framework.
Link: This is the general color used on a link that a user has not clicked
before. The LinkLabel class defines this color through the LinkColor
property.
Active Link: When the user clicks a link, its target typically opens if
everything is alright. This causes the link to change its color status. The
color of an active link is represented in the LinkLabel class with the
ActiveLinkColor property.
After creating a link, when the user accesses it, you can define some behavior
the link would exhibit to the user, such as getting underlined or not
underlined when the mouse passes over the link. The behaviors of a link can
be controlled through the LinkBehavior property whose values are
AlwaysUnderline, HoverUnderline, NeverUnderline, or the application
would refer to Internet Options dialog box of Control Panel.
Here is an example:
private void linkLabel1_LinkClicked(object sender,
LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start(
@"C:\Program Files\Internet
Explorer\iexplore.exe",
"http://www.functionx.com/vccli");
}
Description
Microsoft Windows provides a control used to select dates on a colorful
calendar:
The dates used and the way they display are based on the Regional Settings
of the Control Panel. It may also depend on the operating system. This
convenient control is called month calendar or simply calendar. The title bar
of the control displays two buttons and two labels. The left button allows the
user to select the previous month by clicking the button. The left label
displays the currently selected month. The right label displays the year of the
displayed date. The right button is used to get to the next month.
The calendar can be configured to display more than one month. Here is an
example that displays two months:
To select a year, the user can click the year number. This changes the year
label into a spin button:
Under the title bar, the short names of week days display, using the format
set in Control Panel. In US English, the first day is usually Sunday. The first
day can be changed by the programmer.
On the control, the currently selected date has a circle around. To select a
date on the control, the user clicks the desired date, which changes from the
previous selection.
In the main area, the numeric days of the month display on a white
background (this color and any color on the control can be changed as we
will see in the next section). To select a date, the user clicks it in the list. By
default, the calendar opens with today's day circled with a hand-drawn-look-
alike ellipse. Using the buttons of the title bar, the month label, and/or the
year, the user can change the date. If at one time the calendar is displaying a
date other than today, and if the user wants to return to today's date, he or
she can click the bottom label that displays Today (you as the programmer
can hide the Today label if you want).
Creating a Calendar
AutoCompleteSource: CustomSource
AutoCompleteMode: Accept
TextBox txtHourlySalary
Label Monday
Label Tuesday
Label Wednesday
Label Thursday
Label Friday
Label Saturday
Label Sunday
Label Hours
Label Amount
Label Regular
Label Overtime
Button btnClose
try
{
friday1 = double.Parse(txtFriday1.Text);
}
catch (FormatException)
{
MessageBox.Show("You typed an invalid value\n" +
"Please try again");
txtFriday1.Focus();
}
try
{
saturday1 = double.Parse(txtSaturday1.Text);
}
catch (FormatException)
{
MessageBox.Show("You typed an invalid value\n" +
"Please try again");
txtSaturday1.Focus();
}
try
{
sunday1 = double.Parse(txtSunday1.Text);
}
catch (FormatException)
txtRegularTime.Text = regularHours.ToString("F");
txtOvertime.Text = overtimeHours.ToString("F");
txtRegularAmount.Text = regularAmount.ToString("F");
txtOvertimeAmount.Text =
overtimeAmount.ToString("F");
txtNetPay.Text = totalEarnings.ToString("F");
}
Selecting a Date
As mentioned in our description, the calendar control displays the days of a
selected month. The control also displays the remaining days, if any, of the
first week of the currently selected month; that is, the days of the previous
month that share the week with the first day of the first week of the selected
month. The control also displays the first days of the subsequent month that
share the week with the last day of the current month.
To use the calendar control, the user can click a date, whether it a date from
the current month or a day of the other (previous and next) month. When the
user has clicked a date to select it, the control fires a DateSelected event.
The DateSelected event is of type DateRangeEventArgs.
The user can also select a date using the keyboard. To do this, the user
must first give focus to the control. This is possible by pressing Tab
continuously until the control receives focus (or by clicking any date on the
control. To select a date using the keyboard, the user can continually press
one of the arrow keys (on the keyboard) until the desired date is selected.
When a date has been selected, whether by the user (using the mouse or the
keyboard) or by you (through code), the control fires a DateChanged event.
The DateChanged event is of type DateRangeEventArgs.
The user can also select a range of dates using the keyboard or using a
combination of the mouse and the keyboard. To do this, the user must first
give focus to the control. To select a range of dates using the keyboard, the
user can press and hold Shift, then press one of the arrow keys continually
until the last date of the desired range is selected (in reality, we will see that
there is a property that controls the maximum range of dates that can be
selected). To select a range of dates using a combination of the mouse and
keyboard, the user can click the first date, press and hold Shift, then click
the last date.
After selecting the days, the starting date is stored in the SelectionStart
property. The last date of the selection is stored in the SelectionEnd
property. Both properties are of DateTime type. The range of the selected
dates is stored in a SelectionRange value. SelectionRange is simply a
class that can give you information about the beginning and the end of a
selected range of dates.
By default, the user can select only up to 7 days at a time. If you want the
user to be able to select more or less days than that. Here is an example
where the user have selected dates from the 11 to the 20th, that is 10 days:
After selecting a range of dates, the control fires a DateChanged event, which
is of type DateRangeEventArgs. We saw earlier that the
DateRangeEventArgs class has two properties. The
DateRangeEventArgs.Start property holds the starting date of the range
that the user made. The DateRangeEventArgs.End holds the last date from
the range that the user made.
1. On the form, click the calendar control and drag its right border so it can
display two months:
Description
As we have seen regularly in this and as you will see in other lessons, you can
display a picture directly on a form. Still, to give you a more comfortable
space to show a picture, the .NET Framework provides a Windows control
named PicturePox.
button and click the form. To programmatically get the control, you can
create a handle to the PictureBox class. Before using the control, make sure
you add it to the list of Controls of the form that will host it. Here is an
example:
using System;
using System.Windows.Forms;
public Exercise()
{
}
Application.Run(new Exercise());
return 0;
}
}
Introduction
As a regular visual control, after a picture box has been added to a form, it
assumes a default size (unless you dragged and drew when adding it). You
can then move or resize it using the techniques of application design we
reviewed in Lessons 3 and 4. Of course, you can also specify the location and
the size of the control programmatically. Here is an example:
using System;
using System.Drawing;
using System.Windows.Forms;
public Exercise()
{
InitializeComponents();
}
At run time, unless you display an object in the picture box or draw a shape
in it, the user would not know where the picture box starts and where it ends:
There is no way of knowing that the above form contains a picture box. If you
want the picture box to show its borders to the user, you can use the
BorderStyle property. We described this property in Lesson 5.
Click the ellipsis button of the Image field in the Properties window
In both cases, a dialog box would come up to assist you with locating and
selecting a picture.
public Exercise()
{
InitializeComponents();
}
At run time, you can also specify the path or the URL to the picture by
assigning it to the PictureBox.ImageLocation property. Here is an
example:
public class Exercise : Form
{
private PictureBox pctBox;
public Exercise()
{
InitializeComponents();
}
After assigning a string to the ImageLocation property, you can call the
PictureBox.Load() method to actually show the image. This method is
overloaded with two versions.
When accessing this property, if you use an event such as the Paint
event of the picture box or the Click event of a button, you don't have to call
the Load() method to show the picture; but it is more effective and faster.
This version takes as argument the URL of, or the path to, the picture. Here is
an example:
public class Exercise : Form
{
private PictureBox pctBox;
public Exercise()
{
InitializeComponents();
}
After you have specified the image that the picture box would display, by
default, it is located from the top-left corner of the control. In some cases, for
example if the picture's size is lower than the control's, this would be fine and
you may not need to be concerned with that:
The picture box can show only as far as its size. If an image goes beyond the
control, its parts would be hidden. In some cases, the image may appear too
wide, too narrow, too tall, or too short for the picture box. And in some cases,
if the image's size is higher than the picture box, the control would not show
some important aspects. Therefore, in some cases, you want to resize either
the picture to fit the control, or the control to fit the picture. In some cases,
you can programmatically resize a control by changing its Size property. On
the other hand, you can scale a picture as we learned with bitmap. The
PictureBox class provides an alternative.
Normal: The picture is positioned from the top-left corner of the control
as seen in the above form
If you give the user the ability to resize the picture box, when this is
done, the picture would always be drawn in the middle-center of the
control
After
If you give the user the ability to resize the picture box, when this is
done, the picture would always resize itself to fit the size of the control
Zoom: The image is positioned in the middle of the control but it is also
resized following a certain algorithm:
o If the image is taller than the control, the picture gets resized to
be smaller so its new width and height can fit in the control and
the ratio Bitmap.Width/Bitmap.Height ratio is respected. Here
is an example
Before
o If the image is wider than the control, the picture gets resized to
be small enough so its new width and height can fit in the control
and the ratio Bitmap.Width/Bitmap.Height is respected. Here is
an example
Before After
After
AutoSize: The size of the control would be changed to fit the picture:
o If the picture is smaller than the control, the size of the control
would be increased to show the whole picture
Before After
Description
Text is considered rich if it can display various characters or paragraphs in
different styles and features that make it more attractive than a regular ASCII
text. Such a text can have some of its sections in different colors. Its
paragraphs can have customized attributes or arranged independent of each
other. Although you can create a complete rich but static text, the common
use of a rich text is to let the user process most of the formatting.
public Exercise()
Controls.Add(rchNote);
}
}
3. Type Editor.cs as the new name of the form and press Enter
11. Click Filter and type Rich Text Format (*.rtf)|*.rtf|Text File
(*.txt)|*.txt|All Files|
12. From the Common Controls section of the Toolbox, click RichTextBox
and click the form
13. From the Menus & Toolbars section of the Toolbox, click MenuStrip and
14. On the form, click Type Here, type File and press Enter
15. Under File, click Type Here, type New and press Enter
16. On the right side of File, click Type Here, type Edit and press Enter
17. Under Edit, click Type Here, type New and press Enter
18. In the same way, complete the menu strip with the following items:
namespace Notice1
{
public partial class Editor : Form
{
string CurrentFileName;
public Editor()
{
InitializeComponent();
}
20. Return to the form and click the rich text control
Introduction
Like the other graphical Windows controls, the right text box uses the common
characteristics such as the location, the size, the minimum size, the maximum
size, the anchor, the docking, the font, the ability to be visible or hidden, the
ability to be enabled or disabled, and the border style. Like the TextBox control,
the rich text control inherits various characteristics from the TextBoxBase
class, including the Text property, the Lines collection, the read-only attribute,
the ability to select and manipulate text. The rich text box also shares various
characteristics with the multi-line text box such as the Multiline property, the
scroll bars, the word wrap, the ability to accept the Tab and the Enter keys.
Here is an example:
private void InitializeComponent()
{
rchNote = new RichTextBox();
rchNote.Size = new Size(Width, Height);
rchNote.Multiline = true;
rchNote.ScrollBars = RichTextBoxScrollBars.Both;
Controls.Add(rchNote);
}
}
This method takes as argument the name or path to a file. It will save the file
as RTF. If you want the user to save a file that is either RTF, ASCII, or another
format, to specify the desired format, you can use the following version of the
method:
public void SaveFile(string path, RichTextBoxStreamType
fileType);
As seen in the first version, the first argument is the name or path of the file.
The second argument allows you to specify the type of file that is being saved,
which could be a normal ASCII text. This argument is of type
RichTextBoxStreamType, which is an enumeration. The members of the
RichTextBoxStreamType enumeration are PlainText, RichNoOleObjs,
RichText, TextTextOleObjs, or TextTextOleObjs.
Instead of directly using the name of the file, you can create it as a stream. In
this case, the RichTextBox class provides the following version of the
SaveFile() method:
This method takes as argument the name or path to a file. The file must be in
RTF format. If it is not, the file will not be opened and the compiler would
throw an IOException exception. If you want to give the user the ability to
open different types of files, you should use the following version of the
LoadFile() method:
The first argument is the same as a the single argument of the first version.
The second argument allows you to specify the type of file that is being
opened, which could be a normal ASCII text. This argument is of type
RichTextBoxStreamType.
Instead of directly using the name of the file, you can create it as a stream. In
this case, the RichTextBox class provides the following version of the
LoadFile() method:
// When the user clicks File -> New to start a new document,
// before creating a new document,
// find out if the document is "dirty" ask
// the user whether to save or not
if (rchEditor.Modified == true)
{
// Present the message box to the user who
// will decide whether to save
if (answer == DialogResult.Yes)
{
// If the user answers Yes
// Find out if the current document has never been
saved
if (CurrentFileName == "<Not Allowed>")
{
// If it has never been saved,
// then display the Save dialog box
if (dlgSave.ShowDialog() == DialogResult.OK)
{
// Save the file
rchEditor.SaveFile(dlgSave.FileName);
// Change the current file name to something
not allowed
CurrentFileName = "<Not Allowed>";
// Display Untitled name of the
// current file on the title bar
Text = "Parasol - Untitled";
// Since the document has been saved and the
user wants
// to create a new one, empty the control
rchEditor.Clear();
// Update the Modified attribute
rchEditor.Modified = false;
}
else // the user had clicked Cancel, don't do
anything
return;
}
else // If the document was saved before, then
simply update it
{
rchEditor.SaveFile(CurrentFileName);
// Change the current file name to something not
allowed
CurrentFileName = "<Not Allowed>";
// Display Untitled name of the current file on
the title bar
Text = "Parasol - Untitled";
rchEditor.Clear();
// Update the Modified attribute
rchEditor.Modified = false;
}
}
rchEditor.SaveFile(dlgSave.FileName);
}
else
return;
}
else
{
// This was not a new document,
// so, simply save it
rchEditor.SaveFile(CurrentFileName);
}
}
else if (answer == DialogResult.No)
{
// If the user answered No to the question,
don't save
// Simply open the file
if (dlgOpen.ShowDialog() == DialogResult.OK)
{
// Open the new document after
// letting the user select it
rchEditor.LoadFile(dlgOpen.FileName);
// Change the file name of our archives
CurrentFileName = dlgOpen.FileName;
// Get the name of the file that the
user selected
FileInfo fleParasol = new
FileInfo(dlgOpen.FileName);
Text = "Parasol - " + fleParasol.Name;
rchEditor.Modified = false;
}
else
return;
}
else
return;
}
else
}
else // There is no action to take
Close();
}
Formatting Text
We saw that you could change the general font of a text box and you can
change the color of the characters. If you do this on a text box, all of the
characters are changed to the same font and the same color. One of the
extended properties of a rich text box over a regular text box is the ability to
change the font and/ the color of individual characters, words, or paragraphs
and the change applies only to the desired characters.
Before changing a character or a word, you must first select it. To change the
font of the text that is selected on the control, the selected text is identified
with the SelectionFont property. To change the color of the text that is
selected, the selected text is identified with the SelectionColor property.
To assist you with this, you can use the Font dialog box. After selecting the
character or word, you can transfer their attributes to the Font dialog box
before displaying it. After using the dialog box, if the user clicks OK, you can
retrieve the font and color characteristics then apply them to the selected
character or text.
if (dlgFont.ShowDialog() == DialogResult.OK)
{
// Display the Font dialog box
// If the user clicks OK, get the
characteristics of the font
// Apply them to the selected text of the Rich
Edit control
rchEditor.SelectionFont = dlgFont.Font;
rchEditor.SelectionColor = dlgFont.Color;
}
}
To change the alignment at run time, assign the desired value to the
SelectionAlignment property. In the following example, the alignment of the
selected paragraph is set in response to the user clicking a button:
private void button1_Click(object sender, EventArgs e)
{
richTextBox1.SelectionAlignment =
HorizontalAlignment.Center;
}
Practical Learning: Aligning a Paragraph
1. On the form, click Format and double-click Paragraph Align Left
3. Return to the form, click Format and double-click Paragraph Align Center
5. Return to the form, click Format and double-click Paragraph Align Right
A Bulleted Paragraph
Instead of just a regular section made only of text, you can create an
unordered list of lines or paragraphs in your document. To support this, the
RichTextBox class is equipped with a Boolean property named
SelectionBullet. If you set this property to false on a paragraph, the
paragraph would start with a bullet. If you apply this property to more than one
consecutive paragraph, each would start with a bullet.
Introduction
During your application design, if you have a group of controls that you want
to align either horizontally or vertically, you can use the flow layout panel.
You can use different rows and columns of flow layout panels to align the
controls. If you do this, you would then have to align the flow layout panels
also to make sure their controls are aligned. In reality, the flow layout panel is
a valuable accessory for control design but it may not effectively align
different types of controls. To assist with another type of problem, you can
use the table layout panel.
To add a new column, under the Properties window, you can click Add
Column
To add a row, under the Properties window, you can click Add Row
To add more than one column or more than one row, in the Properties
window, click Columns or Rows and click its ellipsis button. This would
open the Column and Row Style dialog box
Besides the ability to align the controls, the table layout panel provides
various aesthetic characteristics, such as the background color of the table,
various styles for the dividing lines of the cells, etc.
After adding a button to a form (by design or with code), you can change its
caption with code by assigning the desired string to the Text property. For
example, you can change the caption of a button as follows:
button1.Text = "Let it Go!";
After specifying the Text of a button, by default, it's positioned in the middle
center of the button:
Here is an example:
public class Exercise : System.Windows.Forms.Form
{
Button btnResume;
public Exercise()
Controls.Add(btnResume);
}
}
4. Access the Factorial tab page and double-click its Calculate button
try
{
number = long.Parse(txtFactNumber.Text);
result = Algebra.Factorial(number);
txtFactorial.Text = result.ToString();
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
}
7. Access the Permutation tab page and double-click its Calculate button
try
{
n = long.Parse(txtPermutationN.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
try
{
r = long.Parse(txtPermutationR.Text);
result = Algebra.Permutation(n, r);
txtPermutation.Text = result.ToString();
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
}
try
{
n = long.Parse(txtCombinationN.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
try
{
r = long.Parse(txtCombinationR.Text);
result = Algebra.Combinatorial(n, r);
txtCombination.Text = result.ToString();
}
catch (FormatException)
{
MessageBox.Show("Invalid Number");
}
}
Controls.Add(btnResume);
}
By default, both the caption and the image display ion the middle-center of
the button. To make them distinct and allow the user to see both, you can
design a bitmap that has both and assign that bitmap as the image of the
button. Alternatively, you can use a separate string and a separate picture.
Fortunately, each can have its own alignment. We already saw how to control
the alignment of the caption.
Controls.Add(btnResume);
}
Flat: The button appears flat. When the mouse is over it, it becomes
highlighted
Popup: The button appears flat. When the mouse is over it, the borders
of the button are raised
Standard: The button appears and behave like all regular buttons you
have seen
Obviously the most important and the most intuitive event of a button occurs
when clicked. This event is of type EventArgs, which indicates that it doesn't
provide nor does it need any formal details about what is going on. To launch
this event, you can double-click the button on the form. To create this event
programmatically, first implement the method that would carry its
assignment, then increment-add (with the += operator) it to the Click
property of the button by assigning it the EventHandler constructor.
When creating a form or a dialog box, after adding a button, in the Properties
window, click DialogResult and select on the values:
After specifying the returned value of a button, access the properties of the
form or dialog box:
After configuring the DialogResult of the button(s), when the user clicks
one of the buttons to close the form or dialog box, you can get the value of
the Form.ShowDialog() method which returns one of the values of the
DialogResult enumeration.
Applications:
Algebra
Simple Interest
Description
The Save and Open dialog boxes allow a user to save or open files only.
Microsoft Windows provides a dialog box specially made so that a user can
select a folder if an application needs one for any reason a programmers
judges necessary. This dialog box appears as follows:
When this dialog box comes up, it displays the Desktop folder as the parent
and all the other folders can be located from it. To use it, the user can click
one of the folders or drives and click OK. If the desired folder is not seen but
is available, the user can expand the existing folders and drives, click the
desired folder, and click OK. If the necessary folder is not available at all, the
user can first select an existing folder or drive, click the Make New Folder
button, type a name for the new folder, and click OK.
Besides the folders, the Browse For Folder dialog box also allows the user to
navigate to folders or directories of the network.
To display the Browse For Folder dialog box, call its ShowDialog() method.
Here is an example:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
The Description
By default, and as seen on the above screenshot, the Browse For Folder
dialog box doesn't indicate what it is used for. This is because it is left to you
to let the user know what you expect. To provide this information, the Browse
For Folder dialog box is equipped with a label that can be made visible or
not. It is available through the Description property. If you provide a string
for this property, it would display under the title bar but above the tree view
of the dialog box. If you add the FolderBrowserDialog control to the form,
you can type a string in the Description field in the Properties window.
You should not specify both the RootFolder and the SelectedPath
properties on the same FolderBrowserDialog control.
After the user has used the Browse For Folder dialog box, has selected a
folder, and clicked OK, to find out what folder the user selected, get the value
of the SelectedPath property.
You can also check the value of the ShowNewFolderButton property to find
out whether the dialog box is equipped with a Make New Folder button.
Introduction
In our introduction to the main menu, we saw that, to access it, the user
clicks one of its categories. A contextual menu is one that appears when the
user right-clicks an area of an application or form. In most applications,
when the user right-clicks a title bar, the operating system is configured to
display a system menu. Here is an example:
To visually create a contextual menu, in the Menus & Toolbars section of the
Toolbox, click the ContextMenuStrip button and click the form. Once
you have a ContextMenuStrip object, you can create its menu items. To do
this, as mentioned for the MenuStrip, you can click the first Type Here line,
type a string, press Enter, and continue creating the other menu items in the
same way.
Unlike a main menu, a popup menu provides a single list of items. If you
want different popup menus for your form, you have two options. You can
create various popup menus or programmatically change your single popup
menu in response to something or some action on your form.
using System;
using System.Drawing;
using System.Windows.Forms;
void InitializeComponent()
{
System.Windows.Forms.ContextMenuStrip context =
new System.Windows.Forms.ContextMenuStrip();
}
}
To assist you with each item of a contextual menu, ToolStrip, the ancestor
to the ContextMenuStrip class, is equipped with a property named Items.
This property is of type ToolStripItemCollection, which is a collection-
based class. The ToolStripItemCollection class implements the IList,
the ICollection, and the IEnumerable interfaces.
ToolStripMenuItem[] mnuEdit =
{
new ToolStripMenuItem("Copy"),
new ToolStripMenuItem("Paste")
};
}
After creating a menu item, to add it to the contextual menu, you can call the
ToolStripItemCollection.Add() method. To add an array of items, you
can call the create ToolStripItemCollection.AddRange() method. Here
are examples:
void InitializeComponent()
{
System.Windows.Forms.ContextMenuStrip context =
new System.Windows.Forms.ContextMenuStrip();
context.Items.Add(mnuCut);
context.Items.AddRange(mnuEdit);
}
2. While the context menu strip is still selected, in the Properties window
click (Name) and type mnuWithProperties
4. Under the Select Item And Add To List combo box, make sure MenuItem
is selected and click Add
7. On the left side, click Add and, on the right side, change the properties
as follows:
Text: Delete
(Name): mnuDeleteProperty
8. On the left side, click Add and, on the right side, change the properties
as follows:
Text: Clear
(Name): mnuClearProperties
9. Click OK
10. From the Menus & Toolbars section of the Toolbox, click
ContextMenuStrip and click the form
11. While the context menu strip is still selected, in the Properties window
click (Name) and type mnuNoProperty
15. In the Properties window, click (Name), type mnuNewProperty and press
Enter
context.Items.Add(mnuCut);
context.Items.AddRange(mnuEdit);
ContextMenuStrip = context;
}
public Form1()
{
InitializeComponent();
}
. . . No Change
There is nothing particularly specific with writing code for a popup menu item.
You approach it exactly as if you were dealing with a menu item of a main
menu. You can write code for an item of a popup menu independent of any
other item of a main menu. If you want an item of a popup menu to respond
to the same request as an item of a main menu, you can write code for one
of the menu items (either the item on the main menu or the item on the
popup menu) and simply call its Click event in the event of the other menu
item.
if (dlgProperty.ShowDialog() == DialogResult.OK)
{
lvwProperties.SelectedItems[0].Text =
dlgProperty.txtPropertyNumber.Text;
lvwProperties.SelectedItems[0].SubItems[1].Text =
dlgProperty.cbxPropertyTypes.Text;
lvwProperties.SelectedItems[0].SubItems[2].Text =
dlgProperty.txtAddress.Text;
lvwProperties.SelectedItems[0].SubItems[3].Text =
dlgProperty.txtCity.Text;
lvwProperties.SelectedItems[0].SubItems[4].Text =
dlgProperty.cbxStates.Text;
lvwProperties.SelectedItems[0].SubItems[5].Text =
dlgProperty.txtZIPCode.Text;
lvwProperties.SelectedItems[0].SubItems[6].Text =
dlgProperty.txtBedrooms.Text;
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (answer == DialogResult.Yes)
lvwProperties.SelectedItems[0].Remove();
}
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (answer == DialogResult.Yes)
lvwProperties.Items.Clear();
}
14. Right-click an empty line of the list view to see the contextual menu and
click New Property
Introduction
To assist the user with selecting a font for an application, Microsoft
Windows provides the Font dialog box:
The Font dialog box appears with three combo boxes of a simple style, a group box that
contains a label, a combo box of a drop down list style, and two buttons (labeled OK and
Cancel).
The list of fonts installed on the computer appear in the Font combo box. To select a
font, the user can start typing its name and the combo box would present suggested
names. The user can also scroll down in the list and click the desired font.
The four types of font styles are listed in the Font Style combo box: the
Regular, the Italic, the Bold, and the combined Bold Italic styles.
The possible sizes are listed in the Size combo box. The user can click a size
or scroll down in the list to find the desired size. The user is allowed to use a
size that is not listed. To use it, the user can click in the text box side of the
control, delete the number, and type the new number.
As the user is making the selections that would define a font, the Sample
label shows a preview of the selection.
After making the selections in the Font, the Font Style, and the Size combo
boxes, the user can click OK.
As an option, the Font dialog box can allow the user to apply two more styles
and a color to the selected font. To make this possible, the lower-left section
of the dialog box can be equipped with an Effects group box. Here is an
example:
The Effects group box is equipped with a Strikeout check box, an Underline
check box, and a Color combo box. To apply a style, the user can click its
check box. To remove a style, the user can uncheck it. To select a color, the
user can click the arrow of the Color combo box and select a color.
As mentioned already, after making the selections, the user can click OK. To
dismiss the selections, the user can click Cancel or press Esc. After clicking OK
or Cancel, the dialog box would be closed. As an alternative, the Font dialog
box can be equipped with an Apply button. In this case, when the dialog box
comes up, the user can make selections. If the user clicks Apply, the new
selections would be executed, as if the user had clicked OK, but the dialog
box would continue displaying. After clicking Apply, even if the user clicks
Cancel, the changes made on the dialog box would be validated.
At design time, to provide a Font dialog to your application, from the Dialogs
section of the Toolbox, you can click the FontDialog button and click the
form. To programmatically provide a Font dialog box to your application,
declare a variable of type FontDialog and use the new operator to allocate its
memory.
To display a Font dialog box to the user, call its ShowDialog() method. Here
is an example:
using System;
using System.Drawing;
using System.Windows.Forms;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
dlgFont= new FontDialog();
dlgFont.ShowDialog();
}
}
At design time, to define the font, click the FontDialog object under the form.
In the Properties window, click Font and click its ellipsis button. This would
display the Font dialog box. You can make your selections and then click OK.
At run time, to specify the font, first create a Font object, and then assign it
to the Font property of the FontDialog variable. Here is an example:
void InitializeComponent()
{
Font fnt = new Font("Garamond", 18.00F,
FontStyle.Italic);
dlgFont.ShowDialog();
}
On the other hand, after the user has made the selections on the dialog box
and clicked OK (or Apply), to get the list of selections the user made, you can
get the values of its Font property.
Besides OK and Cancel, you can equip a font dialog box with a button labeled
Apply. To support this, the FontDialog class is equipped with a Boolean
property named ShowApply. By default, this property is set to false, which
means the button would be hidden. If you want to show the button, set this
property to true. Here is an example:
void InitializeComponent()
{
dlgFont = new FontDialog();
dlgFont.ShowColor = true;
dlgFont.ShowApply = true;
dlgFont.ShowDialog();
As opposed to the OK button, when the user clicks Apply, the dialog box does
not close and therefore (its ShowDialog() method) does not return a
DialogResult result. Instead, the dialog box fires an Apply event. This
event is of type EventArgs, which means it does not give your information
about what the user did (or did not do). Fortunately, to get information about
the state or the values of the dialog, you can simply inquire about its various
properties and you would get all the information you need without any effort.
dlgFont.ShowColor = true;
dlgFont.Color = Color.Red;
dlgFont.ShowDialog();
}
After using the dialog box, if the user had selected a color and clicked OK (or
Apply), to find out the color the user had selected, get the value of the Color
property.
Description
A list box presents a list of items to choose from. Each item displays on a line.
The user makes a selection by clicking in the list. Once clicked, the item or
line on which the mouse landed becomes highlighted, indicating that it is the
current choice. Here is an example:
After an item has been selected, to make a different selection, the user would
click another. The new clicked item becomes selected or highlighted; the
previously selected item looses its highlighting attribute. The user can also
change the selection by pressing the up or down arrow keys.
List boxes are categorized in two types: single and multi-selection. The
second category allows a user to select more than one item by pressing Ctrl
to select items at random or by pressing Shift to select items in a range.
One of the main reasons for using a list box is to display a list of items to the
user. Sometimes the list would be very large. If the list is longer than the
available client area of the control, the control would be equipped with a
scroll bar that allows the user to navigate up and down to access all items of
the list. You will have the option of deciding how many items to display on
the list.
public Exercise()
{
InitializeComponent();
}
Controls.Add(lbxFamily);
}
}
In our applications, the names of the list-based controls will be in plural. This is
not a rule and it is not based on any preconceived standard.
Musical Instrument
GroupBox
Selection
Label Categories
Label Types
Label Items
ListBox lbxTypes
ListBox lbxItems
Label Part #
Label Description
Label Qty
TextBox txtPartID1
TextBox txtDescription1
TextBox txtDescription2
TextBox txtPartID3
TextBox txtDescription3
TextBox txtPartID4
TextBox txtDescription4
TextBox txtPartID5
TextBox txtDescription5
TextBox txtPartID6
TextBox txtDescription6
Introduction
Like every control, when creating a list box, make sure you give it a name.
Once the list box is positioned on a container, as done with other controls,
you can move it by clicking and dragging the control. You can also resize it
using any of the techniques we learned to add, position, move, and resize
controls. If the list will cover many items, design it so its height can display 8
items at a time. Otherwise, for a list of 8 or less items, use only the necessary
height that would accommodate all of the items.
At design time, to create a list of items, access the Properties window of the
list box and click the ellipsis button of the Items field. This would open the
String Collection Editor:
Controls.Add(lbxFamily);
}
You can also first create an array of items and then add that array to the
collection. To support this, the ObjectCollection class provides the
AddRange() method. Here is an example:
Controls.Add(lbxFamily);
}
If you use either the Add() or the AddRange() method to add an item or a
group of items, the item or the group would be added to the end of the list, if
a list exists already. To insert a new item somewhere inside of the list, call
the Insert() method.
2. In the Properties window, click Items and click its ellipsis button
Guitars
Bass
Keyboards
Drums & Percussion
Band & Orchestra
Recording & Sound
Folk Instruments
Books & Videos
Accessories
6. Click OK
9. After using the form, close it and return your programming environment
namespace MusicalInstrumentStore1
{
class PartDescription
{
private string number;
private string discr;
private decimal uprice;
public PartDescription()
13. Access the MusicStore.cs file and create a few arrays as follows:
namespace MusicalInstrumentStore1
{
public partial class MusicStore : Form
{
string[] CatBass = {
"Electric Bass", "Acoustic-Electric Bass",
"Amplifiers", "Effects", "Accessories" };
string[] CatKeyboard = {
"Pianos", "Organs", "Synthesizers",
"Portable", "Workstations", "Arrangers",
"Stands", "Amps", "Pedals", "Accessories" };
string[] CatDrums = {
"Acoustic Drums", "Cymbals",
"Electronic Percussion", "World Percussion" };
string[] CatBand = {
"Trumpets", "Trombones", "Saxophones",
"Clarinets", "Flutes", "Baritones", "Tubas",
"Oboes", "Recorders", "Accessories" };
string[] CatAccessories = {
"Headphones", "Strings", "Slides", "Metronomes",
"Tuners", "Music Stands", "Cases", "Cables",
"Hearing Protection", "Electric Guitar Bags",
"Guitar Pedals", "Cleaning/Care" };
PartDescription[] ElectricGuitars =
PartDescription[] AcousticGuitars =
{
new PartDescription("224885",
"Epiphone Hummingbird Acoustic Guitar",
245.55M),
new PartDescription("283407",
"Dean V Coustic Thin Body Acoustic-Electric Guitar",
205.50M),
new PartDescription("275111",
"Yamaha FG720S 12-String Acoustic Guitar",
325.55M),
new PartDescription("249036",
"Rogue RA-100D Dreadnought Acoustic Guitar",
82.95M),
new PartDescription("285507",
"Alvarez RD8 Regent Series Dreadnought Acoustic
Guitar",
PartDescription[] ElectricBasses =
{
new PartDescription("248780",
"Epiphone Thunderbird IV Bass",
325.50M),
new PartDescription("203487",
"Squier® Vintage Modified '70s Jazz Bass",
305.95M),
new PartDescription("204633",
"Fender Standard Precision Bass",
450.75M),
new PartDescription("297548",
"Music Man StingRay 5-String Bass Guitar",
1485.95M)
};
PartDescription[] AcousElectBasses =
{
new PartDescription("248780",
"Ibanez AEB10E Acoustic-Electric Bass Guitar with
Onboard Tuner",
335.50M),
new PartDescription("203487",
"Dean Playmate EABC 5-String Cutaway Acoustic-
Electric Bass",
285.95M),
new PartDescription("204633",
"Fender BG-32 Acoustic/Electric Bass Guitar",
495.75M),
new PartDescription("634974",
"Gibson Thunderbird IV Bass", 1500.00M),
new PartDescription("674950",
"Rogue VB-100 Violin Bass", 255.95M),
new PartDescription("634742",
"Squier Standard P Bass 4-String Bass",
220.75M),
new PartDescription("637904",
"Peavey Millennium BXP 4-String Bass",
210.95M)
};
PartDescription[] Pianos =
{
new PartDescription("584603",
"Williams ETUDE Console Piano",
450.95M),
new PartDescription("504724",
"Rolan EP-760C Digital Piano w/Stand",
650.95M)
};
PartDescription[] Books =
{
new PartDescription("883670",
"Alfred Guitar for the Absolute Beginner",
16.55M),
new PartDescription("837654",
"Hal Leonard Guitar Tab White Pages",
20.95M),
new PartDescription("843047",
"Carl Fischer Guitar Grimoire Progressions and
Improvisation",
24.75M),
new PartDescription("845716",
"Bill Edwards Publishing Fretboard logic Spc Ed.",
17.95M),
new PartDescription("833427",
"Walrus Productions Guitar Chord Poster",
6.85M)
};
PartDescription[] Cables =
{
new PartDescription("188370",
"Musician's Friend Professional Cable",
4.55M),
new PartDescription("183614",
"Monster Cable S-100 Straight Cable",
20.95M),
new PartDescription("143047",
"Hosa TRS-TRS Stereo 1/4\" Cable",
4.65M),
new PartDescription("145716",
"Mogami Silver Series Cable",
12.95M)
};
. . . No Change
Controls.Add(lbxFamily);
lbxFamily.SelectedIndex = 3;
}
After an item has been selected, to find out the index of the item that is
currently selected, get the value of the ListBox.SelectedIndex property.
To select an item, the user can click it in the list box. When an item has been
clicked, the list box fires a SelectedIndexChanged event. Because selecting
an item is the most regularly performed operation on a list box,
SelectedIndexChanged is the default event of a list box. This event is of
type EventArgs which means that it does not provide any significant
information other than to let you know that an item has been selected.
Nonetheless, this event allows you to easily check if an item has been
selected and what item has been selected.
By default, the user can select only one item in the list. If you want the user
to be able to select more than one item, change the value of the
SelectionMode property. This property is based on the SelectionMode
enumeration. After the user has selected more than one item, to get the
indexes of the items that are selected, you can access the
ListBox.SelectedIndices property which holds that list.
4. On the form, double-click the Types list box and implement its event as
follows:
private void lbxTypes_SelectedIndexChanged(object sender,
EventArgs e)
{
if( lbxTypes.SelectedItem == (object)"Electric
Guitars" )
foreach(PartDescription part in ElectricGuitars)
lbxItems.Items.Add(part);
else if (lbxTypes.SelectedItem == (object)"Acoustic
Guitars")
foreach(PartDescription part in
AcousticGuitars )
lbxItems.Items.Add(part);
else if (lbxTypes.SelectedItem == (object)"Electric
Bass")
foreach (PartDescription part in ElectricBasses)
lbxItems.Items.Add(part);
else if (lbxTypes.SelectedItem == (object)"Acoustic-
Electric Bass")
foreach (PartDescription part in
AcousElectBasses)
lbxItems.Items.Add(part);
else if (lbxTypes.SelectedItem == (object)"Pianos")
foreach(PartDescription part in Pianos)
lbxItems.Items.Add(part);
else if (lbxTypes.SelectedItem ==
(object)"Synthesizers")
foreach(PartDescription part in Synthetizers)
lbxItems.Items.Add(part);
else if (lbxTypes.SelectedItem == (object)"Books")
foreach(PartDescription part in Books)
lbxItems.Items.Add(part);
else if (lbxTypes.SelectedItem == (object)"Cables")
foreach(PartDescription part in Cables)
lbxItems.Items.Add(part);
}
7. On the form, click the Items list box. In the Properties window, click the
Events button and double-click the DoubleClick field
try
{
subTotal2 =
decimal.Parse(this.txtSubTotal2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal3 =
decimal.Parse(this.txtSubTotal3.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal4 =
decimal.Parse(this.txtSubTotal4.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal5 =
decimal.Parse(this.txtSubTotal5.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal6 =
decimal.Parse(this.txtSubTotal6.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
this.txtQuantity3.Text = "1";
this.txtSubTotal3.Text = (part.UnitPrice *
1).ToString();
this.txtQuantity3.Focus();
}
else if (this.txtPartID4.Text.Equals(""))
{
this.txtPartID4.Text = part.PartNumber;
this.txtDescription4.Text = part.PartName;
this.txtUnitPrice4.Text =
part.UnitPrice.ToString();
this.txtQuantity4.Text = "1";
this.txtSubTotal4.Text = (part.UnitPrice *
1).ToString();
this.txtQuantity4.Focus();
}
else if (this.txtPartID5.Text.Equals(""))
{
this.txtPartID5.Text = part.PartNumber;
this.txtDescription5.Text = part.PartName;
this.txtUnitPrice5.Text =
part.UnitPrice.ToString();
this.txtQuantity5.Text = "1";
this.txtSubTotal5.Text = (part.UnitPrice *
1).ToString();
this.txtQuantity5.Focus();
}
else if (this.txtPartID6.Text.Equals(""))
{
this.txtPartID6.Text = part.PartNumber;
this.txtDescription6.Text = part.PartName;
this.txtQuantity6.Text = "1";
this.txtSubTotal6.Text = (part.UnitPrice *
1).ToString();
this.txtQuantity6.Focus();
} // If all Part # text boxes are filled, don't do
anything
else
return;
9. Display the form and click the first text box under Unit Price
11. Click each of the text boxes under Unit Price and each of the text boxes
under Qty
13. In the Properties window and in the Events section, double-click the
Leave field
try
{
qty2 = int.Parse(txtQuantity2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice2 = decimal.Parse(txtUnitPrice2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
qty3 = int.Parse(txtQuantity3.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice3 = decimal.Parse(txtUnitPrice3.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
qty4 = int.Parse(txtQuantity4.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
try
{
qty5 = int.Parse(txtQuantity5.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice5 = decimal.Parse(txtUnitPrice5.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
qty6 = int.Parse(txtQuantity6.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice6 = decimal.Parse(txtUnitPrice6.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
16. Double-click the first Rmv button and implement its Click event as
follows:
private void btnRemove1_Click(object sender, EventArgs e)
{
txtPartID1.Text = "";
txtDescription1.Text = "";
txtUnitPrice1.Text = "0.00";
txtQuantity1.Text = "0";
txtSubTotal1.Text = "0.00";
btnRemove1.Enabled = false;
}
18. Double-click the second Rmv button and implement its Click event as
follows:
private void btnRemove2_Click(object sender, EventArgs e)
{
txtPartID2.Text = "";
txtDescription2.Text = "";
txtUnitPrice2.Text = "0.00";
txtQuantity2.Text = "0";
txtSubTotal2.Text = "0.00";
btnRemove2.Enabled = false;
}
20. Double-click the third Rmv button and implement its Click event as
follows:
private void btnRemove3_Click(object sender, EventArgs e)
{
txtPartID3.Text = "";
txtDescription3.Text = "";
txtUnitPrice3.Text = "0.00";
txtQuantity3.Text = "0";
txtSubTotal3.Text = "0.00";
btnRemove3.Enabled = false;
}
22. Double-click the fourth Rmv button and implement its Click event as
follows:
private void btnRemove4_Click(object sender, EventArgs e)
{
txtPartID4.Text = "";
txtDescription4.Text = "";
txtUnitPrice4.Text = "0.00";
txtQuantity4.Text = "0";
txtSubTotal4.Text = "0.00";
btnRemove4.Enabled = false;
}
24. Double-click the fifth Rmv button and implement its Click event as
follows:
private void btnRemove5_Click(object sender, EventArgs e)
{
txtPartID5.Text = "";
txtDescription5.Text = "";
txtUnitPrice5.Text = "0.00";
txtQuantity5.Text = "0";
txtSubTotal5.Text = "0.00";
btnRemove5.Enabled = false;
}
26. Double-click the sixth Rmv button and implement its Click event as
follows:
private void btnRemove6_Click(object sender, EventArgs e)
{
txtPartID6.Text = "";
txtDescription6.Text = "";
txtUnitPrice6.Text = "0.00";
txtQuantity6.Text = "0";
txtSubTotal6.Text = "0.00";
btnRemove6.Enabled = false;
}
Instead of removing an item by its name or identification, you can use its
position. To do that, you can call the RemoveAt() method and pass the zero-
based index of the undesired item. If the index is valid, the item would be
deleted from the list.
To remove all items from the list, you can call the Clear() method.
1. Change the SelectedIndex events of the Types and the Items list boxes
as follows:
private void lbxCategories_SelectedIndexChanged(object sender,
EventArgs e)
{
lbxTypes.Items.Clear();
lbxItems.Items.Clear();
if (lbxCategories.SelectedItem == (object)"Guitars")
{
lbxTypes.Items.Add("Electric Guitars");
lbxTypes.Items.Add("Acoustic Guitars");
lbxTypes.Items.Add("Acoustic-Electric Guitars");
lbxTypes.Items.Add("Amplifiers");
lbxTypes.Items.Add("Effects");
lbxTypes.Items.Add("Microphones");
lbxTypes.Items.Add("Accessories");
lbxTypes.Items.Add("Value Packages");
}
else if (lbxCategories.SelectedItem == (object)"Bass")
lbxTypes.Items.AddRange(CatBass);
else if (lbxCategories.SelectedItem ==
(object)"Keyboards")
lbxTypes.Items.AddRange(CatKeyboard);
else if (lbxCategories.SelectedItem == (object)"Drums &
Percussion")
lbxTypes.Items.AddRange(CatDrums);
{
ListBox lbxFamily;
public Exercise()
{
InitializeComponent();
}
string[] strMembers =
{
"Niece", "Nephew", "Uncle", "Aunt",
"Grand Father", "Grand Mother"
};
lbxFamily.Items.AddRange(strMembers);
Controls.Add(lbxFamily);
System.Windows.Forms.Application.Run(new Exercise());
return 0;
}
}
At design time, if just one or a few items are hidden by the scroll bar, you can
heighten it if the form provides more space.
public Exercise()
{
InitializeComponent();
}
lbxBook.Items.Add("College Algebra");;
lbxBook.Items.Add("Finite Mathematics");
lbxBook.Items.Add("Mathematical Structures");
Controls.Add(lblTitle);
Controls.Add(lbxBook);
}
}
If at least one of the items of the list box is wider than the width of the
control, the right side(s) of that (those) may disappear. To allow the user to
see the hidden part of the item(s), you should display a horizontal scroll bar.
To support this, the ListBox class is equipped with a Boolean property
named HorizontalScrollbar. To make a list box display a horizontal scroll
bar, at design time, access the Properties window for the list box and set its
HorizontalScrollbar property to True. You can also do this programmatically.
Here is an example:
private void InitializeComponent()
{
lblTitle = new Label();
lblTitle.Text = "Book Titles";
lblTitle.Location = new Point(12, 12);
bxBook.HorizontalScrollbar = true;
Controls.Add(lblTitle);
Controls.Add(lbxBook);
}
This property allows the operating system to find the widest item in the list
and provide a horizontal scroll bar that is long enough to display each item
when the user scrolls to the right. The above code would produce:
public Exercise()
{
InitializeComponent();
}
Controls.Add(lblTitle);
Controls.Add(lbxBook);
}
}
1. Display the form and click the most right list box. Using the Properties
window, set its HorizontalScrollbar property to True
3. After using it, close the form and return to your programming
environment
Description
A spin button, also called a spin box, also called an up/down control, is a
Windows control equipped with two opposite arrow buttons .
The user clicks one of the arrow buttons at one time to increase or decrease
the current value of the control. The value held by the control is also called its
position.
public Exercise()
{
InitializeComponent();
Controls.Add(nudCounter);
}
}
System.Windows.Forms.Application.Run(new Exercise());
return 0;
}
}
If you want the buttons to be positioned on the left, set this property to Left.
The values of this property are managed through the LeftRightAlignment
enumeration of the UpDownBase parent class. Here is an example of aligning
the buttons to the left:
private void InitializeComponent()
{
nudCounter = new NumericUpDown();
nudCounter.Location = new Point(12, 12);
nudCounter.UpDownAlign = LeftRightAlignment.Left;
Controls.Add(nudCounter);
}
When the value of an spin button has been changed, the control fires a
ValueChanged() event. This event simply uses an EventArgs class as
argument. If the user decides to manually edit the value of the control by
typing a number in the text box part of the control, the spin button fires a
TextChanged() event.
Controls.Add(nudCounter);
}
If you use large numbers in the thousands, they may become difficult to read:
Controls.Add(nudCounter);
}
Controls.Add(nudCounter);
}
This causes the control to check the value used as the thousands separator in
the Control Panel of the computer that is using the application. The
thousands separator for US English is the comma ",". Here is an example:
Controls.Add(nudCounter);
}
Applications:
Pledge Distribution
Introduction
One of the ways users print consists of sending the document to the printer.
To directly send a document to the printer, you need to make sure that the
control, whose value needs to be printed, supports printing. To accommodate
the users of your application, you can provide a menu item or a button they
would click. An example of such a button would be . To print, the user can
click this button. With this type of printing, when the user decides to print,
the whole document would be printed "as is", in color if the document is
colored and if the printer supports colors. If there is more than one printer,
the computer would use what is known as the default printer.
Providing a Printer
To provide the users with the ability to customize printing through the Print
dialog box, you can add a PrintDialog object from the Dialogs section of
the Toolbox to your form. The PrintDialog control is implemented through the
PrintDialog class of the System.Windows.Forms namespace. To
programmatically create a PrintDialog object, you can declare a variable of
type PrinterDialog. Here is an example:
using System;
using System.Drawing;
using System.Windows.Forms;
public Exercise()
{
InitializeComponent();
}
Controls.Add(btnPrint);
}
To present the Print dialog box to the user, you can call its ShowDialog()
method.
void InitializeComponent()
{
btnPrint = new Button ();
btnPrint.Location = new Point(12, 12);
btnPrint.Text = "&Print...";
btnPrint.Click += new EventHandler(btnPrintDocument);
Controls.Add(btnPrint);
}
After creating the document to print through a PrintDocument object, you can
associate it with a PrintDialog. To support this, the PrintDialog class is
equipped with the Document property. To specify the object that would carry
the printing, you can assign the PrintDocument object to the
PrintDialog.Document property. Here is an example:
dlgPrint.Document = docPrint;
dlgPrint.ShowDialog();
}
A document to print can be made of only one or many pages. Each page has
a number of characteristics. The characteristics of a page are controlled by
the PrintDocument.PageSettings property which itself is based on the
PageSettings class. The PageSettings class is defined in the
System.Drawing.Printing namespace. This class holds the dimensions of
the page, the values of the margins applied on the page, the tray that would
supply the paper (since some printers have many trays), the printer
resolution, whether the page would be printed in color or black and white,
whether the page would be printed in Portrait or Landscape orientation, etc.
If you don't want to specify these characteristics, you can set the
PrintDocument.PageSettings property to DefaultPageSettings.
If you know the name of the document to be printed, you can assign it to the
PrintDocument.DocumentName property. Here is an example:
dlgPrint.Document = docPrint;
dlgPrint.ShowDialog();
}
Once the printer is ready, the application would then need to know what
needs to be printed on the paper. At this time, the PrintPage event is fired.
The PrintPage event is of type PrintPageEventArgs. The
PrintPageEventArgs class allows you to fully customize the page of the
document to be printed. For example, it is equipped with a Graphics
property that allows you to "draw" anything you want on the paper. The
PrintPageEventArgs class also allows you to get the location and
dimensions of the area to be printed. This is represented by the PageBounds
property, which produces a Rectangle object.
Once the PrintDocument object is ready, you must pass it to the Print dialog
box. To do that, assign the name of the PrintDocument variable to the
PrintDialog.Document property.
The first option presented to the user is the name of the printer to be used.
Because there can be many printers available to the user, the printers are
presented as a combo box:
The Name combo box in the Printer section or the Select Printer list view
allows the user to select the printer that will handle the job. If you are writing
a universal application and cannot predict what printer(s) the user would
Under the Name combo box, the labels provide the status of the selected
printer (whether it is ready or not), the type of printer (such as its
manufacturer), its location (such as where in the building the printer is
located; the person who installed the printer or may have provided this
printer), and an optional comment (this information is created by the person
who installed the printer or it can be changed in the printer's properties).
After selecting the printer, the user can access the properties of that
particular printer. Different printers support different options. To configure
the printed paper based on the selected printer, the user can click either
Properties or Preferences. This opens the Document Properties or the Printing
Preferences dialog box. The content of this dialog box (highly) depends on
the printer that was selected but some characteristics are shared among
printers.
On the lower-right side of the Printer section or of the Select Printer section,
there is a check box labeled Print To File. When this check box is checked, the
document is transformed into a file rather than being printed. In this case, if
the user clicks OK or Print, a dialog box would come up, asking the user to
specify the path and a name for the new file that will be created. The
appearance of that dialog box depends. Here is an example:
If you want the Print To File check box to be checked, set the
PrinterSettings.PrintFoFile Boolean property to true. Its default value
is false, which lets the user decide whether to check it or not.
This allows the user to still specify whether to print the whole document or
only the section that was selected. If the document contains more than one
page, the user can navigate to a particular page and decide to print only that
page using the Current Page radio button. Again, if the document contains
more than one page, the user can specify a range of pages to print. All these
options are usually left up to the user. On the other hand, if you want to
specify the range of pages to print, you can use the
PrinterSettings.FromPage and the ToPage properties. If you want to
specify the limits of ranges allowed to the user, use the MinimumPage and the
MaximumPage properties.
Description
Most of the applications allow users to open or display an empty document.
This indicates that such an application expects the user to create a document.
Once a document has been created, a user would usually want to store its
contents on a medium (hard drive, floppy disk, etc). Microsoft Windows
provides a common dialog box for this purpose: The Save As dialog box:
The primary role of the Save As dialog box is to allow users to store a file on
the hard drive of the computer, on a portable medium such as a floppy disk,
or on a network drive. To make this efficient and complete, the user must
supply two valuable pieces of information: the location and the name of the
file. The location of a file is also known as its path.
Various rules have changed. For example, the names of folders and files on
Microsoft Windows >= 95 can have up to 255 characters. The extension of
the file is mostly left to the judgment of the programmer but most files are
still using extensions. Applications can also be configured to save different
types of files; that is, files with different extensions.
To use the Save As dialog box, users usually click an item under the File
menu. Here is how it works for most regular applications. The user creates a
new document. If the user wants to save the file, he or she can click File ->
Save. If the document was not previously saved, the application would call
the Save As dialog box. If a document is displaying, whether it was saved
previously or not, the user can also click File -> Save As... which also would
call the Save As dialog box.
Two objects are particularly important on the Save As dialog box: The Save In
combo box and the File Name text box or combo box (the File Name box is
made of a combo box to make it user-friendly but over all, users hardly use
the list side of this combo box). Since Windows 95, the user does not have
to specify an extension if the programmer makes it easy. To help with this,
the Save As dialog box is equipped with a Save As Type combo box. This
combo box allows the user to select one of the extensions. The available
extensions have to be created by the programmer so the user can select from
a preset list. If the programmer neglects this, the user would have no
extension to select from. Although the file can still be saved, the operating
system would not associate it with a known type of file. Therefore, if you
specify a series of extensions, the user can select one of these and, in the File
Name box, he or she can simply type a name for the file.
If the user does not specify an extension, the operating system would
associate the extension of the Save As Type combo box. Users of regular
commercial applications, such as word processors, spreadsheet programs, or
graphical applications, etc, are usually trained not to care about the
extensions and let the application deal with that detail. In some other
circumstances, the users must pay close attention to the extension they give
a file. This is common on web development or graphics design because
various file extensions are supported and overall produce the same end
result.
After working on a Save As dialog box, users can click Save or press Enter,
which would validate their entry. To change their mind, regardless of what
they did on the Save As dialog box, users can click Cancel or press Esc, which
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
sfd = new SaveFileDialog();
}
}
return 0;
}
}
The SaveFileDialog class inherits from the FileDialog class from which it
gets most of its characteristics and behaviors.
As you may realize, text files or web files are all text-based files. This means
that if you create a text-based or rich-text based application, you should allow
the users to decide whether the file they are trying to open can be "read" by
a text-based control. To provide this ability, you can specify an unknown
extension specified as All Files.
The Filter
To create a list of allowable extensions for your FileSaveDialog object, you
can use the Filter property from the Properties window. At run time, you
can create a list of file extensions as a string. If the Save As dialog box will
need only one extension, you can create the string using the following syntax:
Prompt|Extension
The Prompt is a section that defines what the user would see in the Save As
Type combo box. An example would be 24-bit Bitmap. Such a string does
not let the user know what actual extension the file would use. Therefore, as
a courtesy, you can specify, between parentheses, the extension that would
be applied if this extension is used. The Prompt can be 24-bit Bitmap
(*.bmp). In this case, the extension used would be bmp. The asterisk * lets
the user know that whatever is provided as the file name would be used in
place of the asterisk. The period indicates the separation from the file to its
extension. This means that the characters on the left of the period would be
the file name, the characters on the right side of the period would be used as
the actual file extension.
If you want to provide various extensions to your Save As dialog box, you can
separate them with a | symbol. An example would be:
HTML Files (*.htm)|*.htm|Active Server Pages (*.asp)|*.asp|Perl
Script (*.pl)|*.pl
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
sfd = new SaveFileDialog();
sfd.Filter = "HTML Files (*.htm)|*.htm|" +
"Active Server Pages (*.asp)|
*.asp|" +
"Apache Files (*.php)|*.php|"
+
"Perl Script (*.pl)|*.pl|" +
"All Files|";
}
}
After creating a filter, when the dialog box comes up, the Save As Type
combo box displays the first index of the filter. If you want, instead of
displaying the first index by default, you can specify another index. To specify
the desired index at design time, change the value of the FilterIndex field
in the Properties window. To programmatically specify it, assign a value to the
FileSaveDialog.FilterIndex property. Here is an example:
public Exercise()
{
void InitializeComponent()
{
sfd = new SaveFileDialog();
sfd.Filter = "HTML Files (*.htm)|*.htm|" +
"Active Server Pages (*.asp)|
*.asp|" +
"Apache Files (*.php)|*.php|"
+
"Perl Script (*.pl)|*.pl|" +
"All Files|";
sfd.FilterIndex = 3;
}
}
Once you know the types of files that your application will be dealing with,
you can make your dialog box friendly by displaying the most likely extension
for a document created using your application. For example, if you create a
text-based application, users are more likely to create a text file with it. If you
create a rich text-based application, users are more likely to create a Rich
Text Format file with it. This most likely extension is known as the default
extension, it allows the user not to provide an extension in the most likely
cases when saving a file. By simply providing a file name and clicking Save,
the operating system would associate the file with the default extension. Of
course, if you create a filter, the user can specify a desired allowed extension.
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
sfd = new SaveFileDialog();
sfd.Filter = "HTML Files (*.htm)|*.htm|" +
using System;
using System.Windows.Forms;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
sfd = new SaveFileDialog();
sfd.Filter = "HTML Files (*.htm)|*.htm|" +
"Active Server Pages (*.asp)|
*.asp|" +
"Apache Files (*.php)|*.php|"
+
"Perl Script (*.pl)|*.pl|" +
"All Files|";
sfd.FilterIndex = 3;
sfd.DefaultExt = "htm";
sfd.ShowDialog();
}
}
return 0;
}
}
Here is an example:
private System.Void button1_Click(System.Object sender,
System.EventArgs e)
{
string strMyDocuments =
Environment.GetFolderPath(Environment.SpecialFolder.Personal);
this.textBox1.Text = strMyDocuments;
}
Once again, most of the time, you will not be concerned with this issue if you
are creating an application for any user.
Probably the most important issue users care about, as far as they are
concerned, is a name for the file they are trying to save. Users know that
they can set the name of the file in the File Name box. To make this action a
little faster, you can provide a default name for a file in case a user does not
want to specify a file name. This is done by typing a name in the FileName
field of the Properties window. In practicality, the FileName value is the
string that displays in the File Name box of the Save As dialog box.
By default, when the Save As dialog box comes up, it displays "Save As" on
its title bar. If you want a different caption, set the desired string in the Title
field of the Properties window or assign a string to the
FileSaveDialog.Title property.
Introduction
A text box is a Windows control used to get or display text to the user. At its
most regular use, a text box serves as a placeholder to fill out and provide
information. Such a use is common on employment applications, login
dialog boxes, forms, etc. Like most other controls, the role of a text box is not
obvious at first glance; that is why it should be accompanied by a label that
defines its purpose.
From the user’s standpoint, a text box is named after the label closest to it.
Such a label is usually positioned to the left or the top side of the text box.
From the programmer’s point of view, a text box is a placeholder used for
various things. For example, you can show or hide it as you see fit. You can
also use it only to display text without allowing the user to change it.
Introduction
As a control primarily meant to display text, like a label, the text box shares
many of the characteristics of a label: text alignment, font, color, etc.
After creating a text box, it may be empty, the user can start typing in it to fill
it with text. You can programmatically assign it a string to occupy it. Another
way you can put or add text to the control is to paste the content of the
clipboard, using text from another control. The syntax of the Paste() method
is:
public void Paste();
At any time, to know the length of the text in the control, you can retrieve the
value of the TextLength property, which is of type int.
Selecting Text
The selection of text from a text box control can be performed either by you
or by a user. To select part of the text, you can specify the starting point
using the SelectionStart property, which is of type int. After the starting
position, you can specify the number of characters to include in the selection.
This is done using the SelectionLength property, which is of type int. The
SelectionStart and the SelectionLength properties allow you to
programmatically select text. The user, on the other hand, also knows how to
select part of the text of the control. These operations can also be performed
using the Select() method of the TextBox class. Its syntax is:
public void Select(int start, int length);
Alternatively, the user may want to select the whole content of the control.
To programmatically select the whole text of a text box control, call the
SelectAll() method. Its syntax is:
When some text has been selected in the control, to get that text, you can
retrieve the value of the SelectedText property, which is a handle to
String.
Operations on Text
After the text, in part or in whole, has been selected, you or the user can
manipulate it. For example, you can copy the selection to the clipboard. This
is done using the Copy() method. Its syntax is:
public void Copy();
To delete the whole contents of the text box, you can call the Clear()
method. Its syntax is:
public void Clear();
Any operation performed on the text box can be undone using the Undo()
method whose syntax is:
public void Undo();
To prevent an undo operation, call the ClearUndo() method. Its syntax is:
public void ClearUndo();
Mnemonics
As mentioned already, a text box should be accompanied by a label that
indicates what it is used for. To support this relationship, the Label control
provides various properties. An accelerator character is a symbol of the label
that provides easy access to its text box. On the label, such a character is
underlined. An example would be First Name. The idea is that, if the user
presses the Alt key in combination with the label’s underlined character, the
text box it accompanies would receive focus.
The UseMnemonic property of a label is only used to indicate that the label
would display an accelerator character and the & symbol typed on the label
creates that accelerator character. To indicate which text box would receive
focus when the accelerator character of the label is invoked, you must make
sure you establish an appropriate tab sequence using the Tab Order menu
item from the main menu or using the combination of TabStop/TabIndex
properties. Typically, the label should have a Tab Order or TabIndex value
that is just - 1 of that of the control it serves.
If you want to assist the user with completing the string entered in a text
box, first specify where the necessary strings will come from. You have two
options. You can use the AutoCompleteSource property, that is based on the
AutoCompleteSource enumeration. Its members are: None,
RecentlyUsedList, FileSystem, FileSystemDirectories, HistoryList,
ListItems, AllSystemSources, AllUrl, and CustomSource.
After specifying the source of the list that will assist the user to complete the
entry of the text box, set it AutoCompleteMode property. This property is
based on the AutoCompleteMode enumeration that has four members. None
is the default value.
Character Casing
A text box can be configured to display only lowercase characters, only
uppercase characters, or a mix. This characteristic is controlled by the
CharacterCasing property, which is an enumerator that holds the same
name. The default value of this property is Normal, which indicates that the
control can use a mix of lowercase and uppercase characters. If you set this
property to Lower, all existing characters, if any, in the control would be
converted to lowercase and all future characters typed in the control would be
automatically converted to lowercase. If you set this property to Upper, all
existing characters, if any, in the control would be converted to uppercase
and all future characters typed in the control would be automatically
converted to uppercase.
Character Password
The operating system uses a default character it uses to hide the contents of
a text box. If you want to use that character, set the
UseSystemPasswordChar property to true. If you prefer to specify your own
character, you can use the PasswordChar property. Although this property is
a char type of data, changing it actually accomplishes two things:
If you type a character in its field in the Properties window, for example
if you type *, any character typed in it would be un-readable
Introduction
The regular text box is meant to display a piece or one line of text. If the user
enters text and presses Enter, nothing particular happens. If the user enters
text and presses Tab, the focus moves to the next control in the tab
sequence. You may want to create an application that goes further than the
one-line limit. For example, if you have used Notepad, you would know that it
shares the font characteristics of a text box but it also allows some text
navigation features that require more than one line. You can create such an
application based on the text box control.
When entering text in a multi-line text box control, the characters start on the
left side of the multi-line text box and are subsequently added on the right
side. The ability to align text is controlled by the TextAlign property. For a
multi-line text box control, the alignment is configured using the
HorizontalAlignment enumerator.
Wrapping Text
As the user enters text in a multi-line text box box, the compiler considers
that a paragraph starts from the user typing a character until he or she
presses Enter. Therefore, a paragraph could be an empty space, a character,
a word, a line of text, a whole page or an entire book. Depending on the
width of the multi-line text box control, the text is incrementally added to the
right side of each previous character. If the caret gets to the right border of
the control, the text automatically continues to the next line, although it is still
considered as one paragraph. To start a new paragraph, the user has to press
Enter. The ability for the text to continue on the next line when the caret
encounters the right border of the multi-line text box is controlled by the
None: This is the default value and its means that the text box would not
display any scrollbar
Vertical: This option specifies that the text box should display a vertical
scroll bar when its content becomes too long
private void mnuEditCut_Click(object sender, EventArgs e)
private void mnuEditCopy_Click(object sender, EventArgs e)
{
this.txtNotice.Copy();
}
private void mnuEditPaste_Click(object sender, EventArgs e)
{
this.txtNotice.Paste();
}
Application
Elementary Addition
Payroll Processing
Introduction
A track bar is a control used to slide a small bar or pointer, also called a
thumb, along a continuous line. In the following dialog box, there is an
example of a track bar under Adjust the slider...:
As far as appearances are concerned, there are two types of track bars,
depending on the orientation: horizontal or vertical. Here is an example of a
vertical track bar on the left side of Medium:
A track bar can be used as a progress control to help the user monitor an
activity. A track bar also allows the user to specify a value that conforms to a
range. When equipped with small indicators, also called ticks, a track bar can
be used to control exact values that the user can select in a range, preventing
the user from setting just any value.
public Exercise()
{
InitializeComponent();
}
Controls.Add(tbrSlider);
}
}
The Orientation
After placing a TrackBar control on a form or other container, by default, its
assumes a horizontal position. The position of the track bar is controlled by
Orientation property implemented through the Orientation enumeration
that has two members. To change the direction of the control, on the
Properties window, set the Orientation property to the desired value. For
example, to make it vertical, change the field from Horizontal to Vertical.
tbrSlider.Orientation = Orientation.Vertical;
Controls.Add(tbrSlider);
}
The dimensions of the track bars we have displayed so far don't appear
practical. This is because we were using the default values. Like every
control, the track bar has default dimensions and like many controls, these
default values are usually not suitable. This means that every time you create
a track bar, make sure you specify either its Size property or its Width and
its Height properties. Here is an example:
private void InitializeComponent()
{
tbrSlider = new TrackBar();
tbrSlider.Location = new Point(12, 12);
tbrSlider.Width = 180;
Controls.Add(tbrSlider);
}
When the user drags the thumb, the control holds a new value known as the
Value property. You also can assign a value to this property to change the
position of the thumb. The value of the Value property must be an integer.
After the user has changed it, to know the value of the track bar, you can
access its Value property. Here is an example:
private void InitializeComponent()
{
tbrSlider = new TrackBar();
tbrSlider.Location = new Point(12, 12);
tbrSlider.Width = 180;
tbrSlider.Value = 6;
Controls.Add(tbrSlider);
}
tbrSlider.Minimum = 8;
tbrSlider.Maximum = 140;
Controls.Add(tbrSlider);
}
You can also set the minimum and the maximum values by calling the
TrackBar.SetRange() method. Its syntax is:
The first argument is the same as the Minimum property and the second
argument is the same as the Maximum property. Here is an example:
private void InitializeComponent()
{
tbrSlider = new TrackBar();
tbrSlider.Location = new Point(12, 12);
tbrSlider.Width = 480;
tbrSlider.SetRange(8, 140);
tbrSlider.Value = 86;
Controls.Add(tbrSlider);
}
Always make sure that the minimum value is lower than the maximum. This
safe measure will allow you to better control the current value of the control.
At design time, if you set the Minimum property to a value higher than that of
the Maximum, for example setting Minimum to 66 while Maximum=10, the
value of the Maximum would be set to that of the Minimum. In this case, both
properties would have the same value. This makes the control unusable: if
the Minimum and the Maximum properties hold the same values, the user
cannot move the thumb. In the same way, at run time, avoid assigning
unpractical values to these properties.
Controls.Add(tbrSlider);
}
When this happens, you can reduce the number of ticks. This is done using
the TickFrequency property. Here is an example:
private void InitializeComponent()
{
tbrSlider = new TrackBar();
tbrSlider.Location = new Point(12, 12);
tbrSlider.Width = 400;
tbrSlider.SetRange(8, 255);
tbrSlider.Value = 125;
tbrSlider.TickFrequency = 10;
Controls.Add(tbrSlider);
}
tbrSlider.TickStyle = TickStyle.TopLeft;
Controls.Add(tbrSlider);
}
As a third option, you can have the tick marks on both sides of the slider. To
get this, set the TickStyle property to Both. With this value, the thumb
becomes a small rectangle (changing from its pentagon shape):
Applications:
Car Inventory
Introduction
A check box is a control that makes a statement true or false. To perform this validation,
the control displays a small square box that the user can click. Here are examples:
To let the user know what the check box control represents, the control is accompanied by a l
statement. When the square box is empty , the statement is false. When the square box
mark , the statement is true.
To programmatically create a check box, declare a variable of type CheckBox, use the new
memory for it, and add it to the Controls collection of its holder. Here is an example:
using System;
using System.Drawing;
using System.Windows.Forms;
public Exercise()
{
InitializeComponent();
}
Controls.Add(chkValidate);
}
}
Unlike the radio button that usually comes along with other radio buttons, a check box can appear
comes in a group with others, the behavior of one check box is independent of the other check box
to the same group.
7. Using the Erase tool , wipe its interior to erase its content
8. Use the Ellipse tool and the black color to draw an oval shape
9. Fill it up with a brown color (the color on the right side of the black)
12. Click the option button and select the Medium brush
15. With still the black and the brown colors, randomly click and right-click different poi
16. Click the white color. Right-click the yellow color. Randomly click and right-click a fe
17. Click the brown color again and click the Line tool
18. Randomly draw horizontal, vertical, and dialog lines in the shape
19. Right-click a white section in the drawing area, position the mouse on Current Icon
22. Use the Icon field of the form in the Properties window to assign the pizza.ico icon t
Additional
Control Text Name
Properties
Label Qty
AlignText: Right
TextBox 0.00 txtTotalBread
ReadOnly: True
AlignText: Right
TextBox 0.00 txtTotalWings
ReadOnly: True
GroupBox Toppings
GroupBox Drinks
Label Qty
AlignText: Right
TextBox 0.00 txtTotalCan
ReadOnly: True
AlignText: Right
TextBox 0.00 txtTotalSoda20
ReadOnly: True
AlignText: Right
TextBox 0.00 txtTotalSoda2L
ReadOnly: True
AlignText: Right
TextBox 0.00 txtTotalOJ
ReadOnly: True
Label Water
AlignText: Right
TextBox 0.00 txtTotalWater
ReadOnly: True
AlignRight: Right
TextBox 0.00 txtTotalPrice
ReadOnly: True
To find out if an item is selected, get the value of its Checked property. Another possibility co
state of the check mark. For example, you can check or uncheck the check mark when th
button. To do this, you can simply negate the truthfulness of the control as follows:
checkBox1.Checked = ! checkBox1.Checked;
Like the radio button, when a check box is clicked, the control fires a CheckedChanged event t
has been checked. This event is of type EventArgs. If the check box can display only two states,
this event is enough.
3. Click the Medium radio button, the Large radio button, the Pepperoni, the Sausage, the Ex
Olives, and the Onions check boxes
4. Release Shift
10. Click each of the following controls: txtMedium, txtLarge, txtEachTopping, txtQtyBread, txt
txtQtyWings, txtPriceWince, txtQtyCan, txtPriceCan, txtQtySoda20, txtPriceSoda20, txtQtyS
txtPriceSoda2L, txtQtyOJ, txtPriceOJ, txtQtyWater, and txtPriceWater
13. In the Code Editor, define a method named CalculatePrice() and implement the events as follow
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace DaniloPizza1
{
public partial class Exercise : Form
{
public Exercise()
{
InitializeComponent();
}
try
{
// Get the price of pizza depending on the selected
size
if (rdoSmall.Checked == true)
PriceSize = double.Parse(txtSmall.Text);
if (rdoMedium.Checked == true)
PriceSize = double.Parse(txtMedium.Text);
if (rdoLarge.Checked == true)
PriceSize = double.Parse(txtLarge.Text);
}
catch (FormatException)
{
MessageBox.Show("The value you typed for the price " +
"of a pizza is invalid" +
"\nPlease try again");
}
if (chkSausage.Checked == true)
To change the appearance of a check box, assign the Button or Normal value to its Appea
Appearance values are defined in the Appearance enumeration. You can also do this program
Like the radio button, the check box control fires an AppearanceChanged event when the
changes from Normal to Button or vice-versa.
Applications
Boolean Algebra
Introduction
Like a list view, a data grid view is a rectangular control made of columns and rows:
To use the data grid view, the user can identify a column, click a cell under it, and start
typing. By default, each cell behaves like a text box. The user can:
As mentioned already, by default, the cells of a data grid view are made of
text boxes. If you want, you can make the cells under the columns into
combo boxes, check boxes, buttons, links, or pictures:
Remember that many aspects of a data grid view can be customized. For
example, you can let the user change the width of a column. You can display a
context menu when the user right-clicks a column header or a row header. You
button and click the form of your application. This would create a black
rectangular box on the form:
To support the data grid view, the .NET Framework provides a class named
DataGridView. Therefore, to programmatically create a data grid view,
declare a variable of type DataGridView and add it to the Controls collection
of the form. Here is an example:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace DataGridViewExercise1
{
public partial class Exercise : Form
{
DataGridView dgvStudents;
public Exercise()
{
InitializeComponent();
}
As a normal Windows control, when creating it, make sure you specify some
of the regular characteristics such as the location, the size, the anchoring, the
docking, etc. Here is an example
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
Text = "Students Records";
Introduction
As its name suggests, a data grid view is presented as a grid, which appears
like a spreadsheet made of columns. The columns organize a data grid view
in categories of information. To hold the columns of a data grid view, the
DataGridView class is equipped with a property named Columns. The
DataGridView.Columns property is of type
DataGridViewColumnCollection defined as follows:
[ListBindableAttribute(false)]
public class DataGridViewColumnCollection : BaseCollection,
IList,
ICollection,
IEnumerable
As you can see, this class implements the IList, the ICollection, and the
IEnumerable interfaces. This means that you can use the
DataGridViewColumnCollection class to create and manage columns.
Creating a Column
One of the first actions you should perform on a data grid view consists of
creating one or more columns. If you are visually creating a data grid view,
on the form, click the data grid view control. In the Properties window, click
Columns and click its ellipsis button. As an alternative, on the form, click the
data grid view and click the button on its top right section:
To create a column, click the Add button. If you had clicked the button on the
top-right section of the data grid view, you can click the Add Column button.
In both cases, the Add Column dialog box would come up:
Controls.Add(dgvStudents);
}
After a new column has been added, the data grid view fires a ColumnAdded
event, which is handled by the DataGridViewColumnEventArgs class.
Deleting a Column
If you do not want a certain column in your data grid view, you can remove
it. If you are visually working on the data grid view, open the Edit Columns
dialog box. To delete a column, click it in the Selected Columns list and click
the Remove button.
When a column has been deleted, the data grid view fires a ColumnRemoved
event. This event also is handled by the DataGridViewColumnEventArgs class.
The data grid view considers the column type as a cell template. To support
cell templates, the .NET Framework provides the DataGridViewCell class.
Except for the check box, you can use the DataGridViewCell class to
specify the type of cells a column should display. To do this, declare a
variable of type DataGridViewCell and use the new operator to initialize it with
one of the following classes:
After declaring and initializing the variable, you can assign it to the
CellTemplate property of the column. Here is an example:
Controls.Add(dgvStudents);
}
Once the new column has been built, to make it possible to actually add it to
the data grid, the DataGridViewColumnCollection class is equipped with a
method named Add that comes in two versions. One of its flavors uses the
following syntax:
public virtual int Add(DataGridViewColumn dataGridViewColumn)
namespace Exercise3
{
public partial class Exercise : Form
{
DataGridView dgvStudents;
public Exercise()
{
InitializeComponent();
}
Controls.Add(dgvStudents);
}
If you create the column to show combo box, to create the values of the
combo box, the DataGridViewComboBoxColumn class is equipped with a
property named Items. This property is of type ObjectCollection and is
created inside the DataGridViewComboBoxCell class. Here is an example of
calling the Add() method of this class:
private void Exercise_Load(object sender, EventArgs e)
{
dgvStudents = new DataGridView();
dgvStudents.Location = new Point(10, 10);
dgvStudents.Size = new Size(420, 80);
colGender.Items.Add("Male");
colGender.Items.Add("Female");
colGender.Items.Add("Unknown");
dgvStudents.Columns.Add(colGender);
}
Controls.Add(dgvStudents);
}
To make it simple and practical, we will use C# rules to name our columns.
If you are visually creating a column, a default caption is given in the Header
Text box. You can accept that string or change it. After creating a column, to
change its caption, open the Edit Columns dialog box and click the column in
the Selected Columns list. In the Properties section, click the HeaderText field
and change its value.
Controls.Add(dgvStudents);
}
Controls.Add(dgvStudents);
}
This version allows you to create a column by specifying its object name and
its caption. Here are examples:
private void Exercise_Load(object sender, EventArgs e)
{
dgvStudents = new DataGridView();
dgvStudents.Location = new Point(10, 10);
dgvStudents.Size = new Size(350, 100);
Controls.Add(dgvStudents);
}
By default, when a data grid view displays its columns, the user is able to
resize any of them. To do this, the user can position the mouse on the
separating line of two columns, click, and drag left or right. If you want, you
can allow this or prevent the user from resizing a column. This characteristic
is controlled by the Resizable Boolean property of the DataGridColumn
class. The default value of the DataGridColumn.Resizable property is true,
which indicates that the user can resize it. To prevent this change, you can
set this property to false:
There are various ways the user can resize a column. The user can position
the mouse on the right border of a column header, click and hold down the
mouse, then drag left or right. The user can also double-click the right border
of a column. However the user does this, when the width of a column has
been changed, the data grid view fires a ColumnWidthChanged event. This
event is handled by the DataGridViewColumnEventArgs class. If the user
double-clicks the right border of a column, the control fires a
ColumnDividerDoubleClick event. This event is handled by the
DataGridViewColumnDividerDoubleClickEventArgs class.
Referring to a Column
In some operations, you will need to indicate the column you want to access.
If you are working visually, open the Edit Columns dialog box and click the
column in the Selected Columns list.
MessageBox.Show(dgvStudents.Columns[1].HeaderText);
Controls.Add(dgvStudents);
}
Introduction to Rows
After creating a data grid view and its columns, you can start populating it
with values. When the data grid view comes up, the user can click a cell.
When the user clicks a cell, that cell becomes highlighted, indicating that it
has received focus. Here is an example:
When a cell receives focus, the data grid view fires a CellEnter Event. This
event is handled by the DataGridViewCellEventArgs class. This class is
equipped with two properties named ColumnIndex and RowIndex. The
ColumnIndex property indicates the index of the column that was clicked.
The RowIndex property indicates the index of the column that was clicked.
After clicking a cell, the user can start typing if the cell is text-based. If the
cell already contained a value, the user can click it first to give it focus and
then edit its content. When the user starts editing the value of a cell, the data
grid view fires a CellBeginEdit event, which is handled by the
DataGridViewCellCancelEventArgs class. As its name suggests, the
primary characteristic of this class is that it allows you to accept or reject
what the user is doing. After the user has edited the value of a cell, the data
grid view fires a CellEndEdit event. This event is handled by the
DataGridViewCellEventArgs class. When this ends, the cell should have a
new value. Here is an example:
After specifying the value of a cell or taking the necessary action, the user
can move to another cell. When a cell loses focus, the data grid view fires a
CellLeave event. This event is handled by the
DataGridViewCellEventArgs class.
The user can perform these operations for each cell under the columns. The
row of cells at the same level under the columns is called a record. Here is an
example of a record with the values Joyce, Simms, and Female:
Each row starts with a gray box on the left side. When the user clicks a cell of
a particular row, the data grid view fires a RowEnter event that indicates that
the row has just received focus. Then, the gray box of that record becomes
equipped with a pen icon. The RowEnter event is handled by the
DataGridViewCellEventArgs class. If the user clicks a cell of another row,
such as a cell above it, under it, or a column header, the data grid view fires
a RowLeave event, which indicates that the previous row lost focus. The
RowLeave event also is handled by the DataGridViewCellEventArgs class.
A record that has been added already displays an empty gray box. The next
empty record has a gray box with a *. The line between two rows is called a row
divider.
[ListBindableAttribute(false)]
public class DataGridViewRowCollection : IList,
ICollection,
IEnumerable
As you can see, this class implements the IList, the ICollection, and the
IEnumerable interfaces. Since a data grid view can have many records, the
records are stored in a zero-based indexed collection. The first record has an
index of 0. The second has an index of 1, and so on. To support this, the
DataGridViewRowCollection class is equipped with an indexed property
(named Item) that is overloaded with two versions. Therefore, to refer to a
record, apply the [] operator to the DataGridView.Rows property. An
example would be:
private void Exercise_Load(object sender, EventArgs e)
{
dgvStudents = new DataGridView();
dgvStudents.Location = new Point(10, 10);
dgvStudents.Size = new Size(350, 100);
Controls.Add(dgvStudents);
dgvStudents.Rows[0] . . .
}
In the same way, if a data grid view contains many records, you can refer to
any, based on its index. The index refers to the gray box on the left of the
record.
There are various things the user can do with a row header. For example, the
user can click a row header. A row header that has been clicked becomes
equipped with a right-pointing arrow and its cells become selected:
The user can also double-click a row header and you can take action if
necessary. When the user double-clicks a row header, the data grid view fires
a RowHeaderMouseDoubleClick event. This event is handled by the
DataGridViewCellMouseEventArgs class.
If the user double-click the bottom border of a row, the data grid view fires a
RowDividerDoubleClick event. This event is handled by the
DataGridViewRowDividerDoubleClickEventArgs class. The
DataGridViewRowDividerDoubleClickEventArgs class is equipped with one
property named RowIndex, which holds the index of the row whose bottom
border was double-clicked.
Introduction
A data grid view is meant to display values and these values are stored in
cells. Under each column header is a box called a cell. To add a value to a
If the user clicks the content (it could be its value) of a cell, the data grid
view fires a CellContentClick event. This event is handled by the
DataGridViewCellEventArgs class.
After clicking a cell, the user can start typing the desired value. The user can
also double-click the content of a cell. In this case, the data grid view fires a
CellContentDoubleClick event. This event is handled by the
DataGridViewCellEventArgs class.
This is a typical collection class that implements the IList, the ICollection,
and the IEnumerable interfaces. This class allows you to refer to a record,
which is primarily a collection of cells that share the same row. To support
this idea of a range of cells, the DataGridViewCellCollection class is
equipped with an indexed property (named Item) that is overloaded with two
versions. One of the versions allows you to refer to a cell based on the index
of its column. The most left cell of a row has an index of 0. The second from
left has an index of 1, and so on.
To identify a cell in a record, you use the concept of a cell being the
intersection of a row and a column. Therefore, you can use the
DataGridView.Rows[] indexed property to specify the record. Then access
the DataGridViewRow.Cells[] indexed property to specify the column
under which the cell exists. Here is an example:
private void Exercise_Load(object sender, EventArgs e)
{
dgvStudents = new DataGridView();
Controls.Add(dgvStudents);
// First Record
dgvStudents.Rows[0] . . .
// Second Record
dgvStudents.Rows[1] . . .
// Intersection of: First Record - First Column
dgvStudents.Rows[0].Cells[0] . . .
// Intersection of: First Record - Second Column
dgvStudents.Rows[0].Cells[1] . . .
// Intersection of: Second Record - First Column
dgvStudents.Rows[1].Cells[0] . . .
// Intersection of: Second Record - Second Column
dgvStudents.Rows[1].Cells[1] . . .
}
Using the index of a column supposes that you know the exact sequence of
columns. As an alternative, you can be more precise by using the object
name of a column. To support this, the DataGridViewRow.Cells[] indexed
property has another version that takes a string as argument. Here is an
example:
private void Exercise_Load(object sender, EventArgs e)
{
dgvStudents = new DataGridView();
dgvStudents.Location = new Point(10, 10);
dgvStudents.Size = new Size(350, 100);
Controls.Add(dgvStudents);
dgvStudents.Rows[0].Cells[0]
dgvStudents.Rows[0].Cells[1]
dgvStudents.Rows[0].Cells["Gender"] . . .
}
Once you have identified a cell, you can then do in it what you want.
Controls.Add(dgvStudents);
dgvStudents.Rows[0].Cells[0].Value = "Joyce";
dgvStudents.Rows[0].Cells[1].Value = "Simms";
dgvStudents.Rows[0].Cells["Gender"].Value =
"Female";
}
If a cell is a check box, to specify its value, assign true or false to its Value
property. Here is an example:
private void Exercise_Load(object sender, EventArgs e)
{
dgvStudents = new DataGridView();
dgvStudents.Location = new Point(10, 10);
dgvStudents.Size = new Size(320, 80);
Controls.Add(dgvStudents);
dgvStudents.Rows[0].Cells[0].Value = "Ernestine";
dgvStudents.Rows[0].Cells[1].Value = "Cavier";
dgvStudents.Rows[0].Cells[2].Value = true;
}
If the column is a combo box, you can assign a string to its Value property.
The value should be one of the items in the combo box.
If the column is configured for web links, you can assign a string to its Value
property. You should make sure the string is either a valid URL or an email
address. Here is an example:
private void Exercise_Load(object sender, EventArgs e)
{
dgvStudents = new DataGridView();
dgvStudents.Location = new Point(10, 10);
dgvStudents.Size = new Size(540, 80);
Controls.Add(dgvStudents);
dgvStudents.Rows[0].Cells[0].Value = "Ernestine";
dgvStudents.Rows[0].Cells[1].Value = "Cavier";
dgvStudents.Rows[0].Cells[2].Value = "Female";
dgvStudents.Rows[0].Cells[3].Value = true;
dgvStudents.Rows[0].Cells[4].Value =
"caviere@emailfrance.fr";
}
Creating a Record
We mentioned that, when a user adds a new value into a cell, a new empty
record is created under that row. Also, by default, after you have just created
the columns of a data grid view, the studio adds an empty record to it. If you
work programmatically, you do not get the same feature, or only one default
empty record is given to you. Therefore, before creating one or more values
for a record, you must make sure there is an empty record ready to receive
your values. This means that you must first create a (an empty) record. You
have various options.
Controls.Add(dgvStudents);
dgvStudents.Rows.Add();
}
You may want to create many records before adding values to them. To
support this, the DataGridViewRowCollection class provides another
version of the Add() method. Its syntax is:
public virtual int Add(int count);
When calling this method, pass the desired number of records as argument.
Once you have created the records, you can then add the desired values.
Here is an example of calling Add():
private void Exercise_Load(object sender, EventArgs e)
{
dgvStudents = new DataGridView();
dgvStudents.Location = new Point(10, 10);
dgvStudents.Size = new Size(350, 200);
Controls.Add(dgvStudents);
dgvStudents.Rows.Add(4);
dgvStudents.Rows[0].Cells[0].Value = "Joyce";
dgvStudents.Rows[0].Cells[1].Value = "Simms";
dgvStudents.Rows[0].Cells["Gender"].Value =
"Female";
dgvStudents.Rows[1].Cells["FirstName"].Value =
"Peter";
dgvStudents.Rows[1].Cells[1].Value = "Mukoko";
dgvStudents.Rows[1].Cells[2].Value = "Male";
}
Instead of adding the values of cells one at a time, you can store them in an
array, then add the whole when it is ready. To support this, the
Controls.Add(dgvStudents);
Description
A group is a window that draws a bordered line all around. This makes it
draw a limiting placeholder for other controls. To indicate what it is used for,
a group box may display a title, also referred to as its caption. Here is an
example of a group box on a form:
public Exercise()
{
InitializeComponent();
}
Controls.Add(grpHolder);
}
Controls.Add(grpHolder);
}
Notice that it is possible to have a control whose size causes some of its
section to be hidden. To accommodate the control(s) positioned in a group
box, you can make the container resize itself so as to reveal the hidden
part(s) of its controls. To support this, the GroupBox class is equipped with
the Boolean AutoSize property. The default value of the
GroupBox.AutoSize property is false. If you set it to true, the group box
would resize itself and all of its controls should appear:
Using a Mnemonic
As mentioned already, a group box can be equipped with a caption, which is
created by assigning a string to its Text property. A mnemonic is a character
(or a letter) that the user can use to access a group box. To create a
mnemonic, precede one character (or one letter) of its caption with &. Here is
an example:
Introduction
A list box is used to display a list of strings and all items of that control are
primarily strings. To go a little further than a simple list of strings, the
Microsoft Windows operating system provides the list view control. A list view
is used to display a list of items to the user but it can be configured to change
the type of display.
public Exercise()
{
InitializeComponent();
}
Controls.Add(lvwCountries);
}
}
3. From the Common Controls section of the Toolbox, click ListView and
click the form
4. While the list view is still selected, in the Properties window, change the
(Name) to lvwStoreItems
View Styles
To set it apart from the list box, a list view provides various options of
displaying its items. To support this, the ListView class is equipped with
the View property that is based on the View enumeration. Its members are:
LargeIcon: In this view, the control displays a list of items in the order
they were added from left to right and from top to bottom. This means
that items start displaying on the top left section of the control to right.
When the first line is filled and there are still items, the list continues to
the next line. Each item uses a square size corresponding to a 32x32
pixel
SmallIcon: Like the LargeIcon style, this view displays the list of items
from the left to the right then to the next line if necessary. This time,
each item uses a square region corresponding to a 16x16 pixel size
List: Like the SmallIcon option, each item uses a 16x16 pixel square to
display. This time, the list is arranged in columns: the first item appears
to the left side of the control. The next item (usually in alphabetical
order) appears under it, and so on. If there are more items to fit in one
column, the list continues with a new column to the right of the previous
one. This continues until the list is complete
Details: This view clearly sets the list view apart from the list box. In
this view, instead of showing just the string of the (main) item, each
item can provide more detailed information in a column
1. To create an icon, on the main menu, click Project -> Add New Item...
10. Right-click the white area and click Delete Image Type
13. On the main menu, click Project -> Add New Item...
19. On the main menu, click Project -> Add New Item...
22. Right-click the white area and click Delete Image Type
26. Double-click the left button and implement its event as follows:
private void btnLargeIcons_CheckedChanged(object sender,
EventArgs e)
{
lvwStoreItems.View = View.LargeIcon;
}
28. Double-click the second button from left and implement its event as
follows:
private void btnSmallIcons_CheckedChanged(object sender,
EventArgs e)
{
lvwStoreItems.View = View.SmallIcon;
}
30. Double-click the third button from left and implement its event as
follows:
private void btnList_CheckedChanged(object sender, EventArgs e)
{
lvwStoreItems.View = View.List;
}
32. Double-click the second button from right and implement its event as
follows:
private void btnDetails_CheckedChanged(object sender, EventArgs
e)
{
lvwStoreItems.View = View.Details;
}
34. Double-click the Close button and implement its Click events as follows:
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
36. Execute the application and click the buttons on the form
To support the various sets of icons, the ListView class is equipped with a
property named LargeImageList for the 32x32 icons and another property
named SmallImageList for the 16x16 icons. After creating both ImageList
objects, you can assign each to the appropriate property.
After assigning the icons to the list view items, each view style can use the
appropriate item to display:
LargeIcon: In this view, each item is displayed with its assigned 32x32
pixels icon. The string of the item displays under its corresponding icon:
List: Each item appears with the 16x16 pixels small icon to its left:
SmallIcon: Like the List option, each item appears with the 16x16
pixels icon:
1. To create an icon, on the main menu, click Project -> Add New Item...
5. Right-click a white area in the main window -> Current Image Type ->
16x16, 16 colors
13. As done above, display the 16x16, 16 colors version of the icon and
design the icon as follows:
16. On the main menu, click Project -> Add New Item...
23. On the main menu, click Project -> Add New Item...
30. On the main menu, click Project -> Add New Item...
42. Locate the folder that contains the current project and display it in the
Look In combo box
44. In the same way, add the other pictures in the following order:
Teens.ico, Women.ico, Men.ico, and Misc.ico
45. Click OK
48. In the Properties window, click the ellipsis button of the Images field
51. Click OK
Members ImageIndex
ListViewItem: {883095} 0
ListViewItem: {602936} 1
ListViewItem: {935709} 2
ListViewItem: {735633} 2
ListViewItem: {492758} 4
58. Click OK
Introduction
One of the characteristics that set the list view apart from the list box is that
the former can provide more information about each item of its list. Based on
this, each type of item can be equipped with its own list of sub-items. The
view would appear as follows:
At design time, to create the columns, access the Properties window for the
list view and click the ellipsis button of the Columns field. This would open the
ColumnHeader Collection Editor. To create a column, you can click Add. In
the right Properties list, you can click Text and type the string that would
display on the column header.
lvwCountries.View = View.Details;
lvwCountries.Columns.Add("Name", 120,
HorizontalAlignment.Left);
Controls.Add(lvwCountries);
}
Caption: The Text property holds the string that displays on top of the
column
Index: Since the columns are stored in a collection, this property allows
you to get the index of this column in the collection it belongs to
The Parent List View: If you want to know what list view the current
column header belongs to, you can access its ColumnHeader.ListView
property
lvwCountries.View = View.Details;
lvwCountries.Columns.Add("Name", 120,
HorizontalAlignment.Left);
Controls.Add(lvwCountries);
}
Instead of adding one column at a time as we have done above, you can first
create an array of ColumnHeader objects and pass it to the
ListView.ColumnHeaderCollection.AddRange() method. Its syntax is:
lvwCountries.View = View.Details;
lvwCountries.Columns.Add("Name", 120,
HorizontalAlignment.Left);
Controls.Add(lvwCountries);
}
10. Click OK
11. While the list view is still selected in the form, change its View property
to Details
13. After viewing the form, close it and return to your programming
environment
Column Insertion
If you call the AddRange() method, its list of columns is created at the end of
any existing column, unless there was no other column. If you call the Add()
method to create a column, the new column is added at the end of the
existing columns, unless it is the first column. If you don't want the new
column to simply be created at the end of the other column(s), if any, you
can call the ColumnHeaderCollection.Insert() method. It is overloaded
with two versions and their syntaxes are:
public void Insert(int index, ColumnHeader value);
public void Insert(int index, string str, int width,
HorizontalAlignment textAlign);
In both versions, the first argument specifies the index where the new column
will be created inside the Columns collection.
1. To start a new project, on the main menu, click File -> New -> Project...
2. In the Templates list, click Windows Application and set the Name to
AltairRealtors2
BorderStyle:
FixedSingle
Altair Realtors -
Label Font: Times New
Properties Listing
Roman, 21.75pt,
style=Bold
ListView lvwProperties
colPropertyNumber Prop # 50
colCity City 80
Columns
colState State 40
Locating Columns
To find out if a certain column is part of a list view, you can call the
ColumnHeaderCollection.Contains() method. Its syntax is:
This method looks for the value ColumnHeader. If it finds it, it returns the
column's index from the collection. If the method doesn't find it, it returns -1.
Deleting Columns
If you don't need a column any more, you can delete it. In the same way, you
can delete all columns of a list view. To delete a ColumnHeader object, you
can call the ColumnHeaderCollection.Remove() method. Its syntax is:
public virtual void Remove(ColumnHeader column);
To delete a column based on its position in the collection, you can call the
ColumnHeaderCollection.RemoveAt() method. Its syntax is:
This method expects a string that will display as the new item. Here is an
example:
private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(452, 214);
lvwCountries.Items.Add("Egypt");
Controls.Add(lvwCountries);
}
This method expects a ListViewItem value. One way you can use it consists
of providing the string the item would display. To do this, you can use the
following constructor of the ListViewItem class:
public ListViewItem(string text);
This constructor expects as argument the text that the new item will display.
Here is an example:
private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(452, 214);
lvwCountries.Items.Add("Egypt");
lvwCountries.Items.Add(lviPortugal);
Controls.Add(lvwCountries);
}
Control
Property
Label
#:
DialogResult:
Button Cancel btnCancel
Cancel
Form
FormBorderStyle: FixedDialog
StartPosition: CenterScreen
AcceptButton: btnOK
CancelButton: btnCancel
MinimizeBox: False
ShowInTaskBar: False
6. On the form, double-click the New Property button and implement its
event as follows:
private void btnNewProperty_Click(object sender, EventArgs e)
{
AvailableProperty dlgProperty = new AvailableProperty();
dlgProperty.txtPropertyNumber.Text = propNumber;
dlgProperty.Text = "Altair Realtors - New Property";
if (dlgProperty.ShowDialog() == DialogResult.OK)
{
ListViewItem lviStoreItem =
new
ListViewItem(dlgProperty.txtPropertyNumber.Text);
lvwProperties.Items.Add(lviStoreItem);
}
}
8. When the form displays, click the New Property button and, when the
dialog box comes up, click OK
lvwCountries.Items.Add("Egypt");
ListViewItem[] lviCountries =
{
new ListViewItem("Australia"),
new ListViewItem("Mali"),
new ListViewItem("Venezuela")
};
lvwCountries.Items.AddRange(lviCountries);
Controls.Add(lvwCountries);
}
Alternatively, you can create an array of strings and pass it to the following
constructor of the ListView class:
public ListViewItem(string[] items);
On a large image or a small image style, the item on the top-left side has
an index of 0. The second item from the left has an index of 1, and so
on, up to the subsequent lines, if any
On a details style, the most top item has an index of 0. The second item
from the top has an index of 1, and so on
When a list view comes up, it displays its list of items. To use an item, the
user can click it. When an item has been clicked, the control fires a
SelectedIndexChanged event. The SelectedIndexChanged event is of type
EventArgs, which means it does not carry any significant information except
to let you know that an item has been clicked. Worse, this event does not
even let you know the index of the item that was clicked. This means that
you must work on your own to identify the item that was clicked.
When the user clicks an item, you can use a technique to identify the item
that was selected, when another item gets selected, the the item that was
previously selected fires an ItemSelectionChanged event.
Editing a Label
Clicking an item once allows the user to select it. You may create an
application that allows the user to edit an item, that is, to change the string
that the item displays. To edit an item, the user can click (once) an item, then
click (once) the item again. This puts it into edit mode. The user can then use
the keyboard to change the string of the item:
To support the ability to let the user edit an item, the ListView class is
equipped with the LabelEdit Boolean property. The default value of this
property is false, which would prevent the user from editing the item in the
list view. If you set this property to true, the user can click, then click the
item to edit it.
If you allow the user to edit the item, after the user has edited it, the control
fires an AfterLabelEdit event.
Activating an Item
When an item has been selected, it becomes highlighted. If you use the
LabelEdit property to allow the user to edit an item, this is a local edition.
In the next sections, we will learn how to add sub-items to a list view item.
When an item is equipped with sub-items, you may want your application to
allow the user to change the item, one of its sub-items, or everything. Before
doing anything, an item must be activated. There are three ways an item has
been activated.
OneClick: With this option, the user would click an item once to active it
TwoClick: If you set the Activation property to this member, the user
would have to click the item, then click it again to activate it (clicking
once and clicking again once is not the same as double-clicking)
When an item has been activated, the control fires an ItemActivate event.
You can use either this or the SelectedIndexChanged event to process the
item.
1. Display the first form AltairRealtor.cs [Design] and, on the form, click the
list view
5. Click the New Item button followed by the OK button a few times
Using Columns
Besides the items, the user can also use the columns. For example, you can
allow the user to re-arrange or sort the list of items with the user clicks a
column. When the user a column header, the control fires a ColumnClick
event. The ColumnClick event is of type ColumnClickEventArgs. The
ColumnClickEventArgs class is equipped with the Column integer property
that allows you to identify the index of the column that was clicked.
Besides clicking a column header, the user can also resize a column by
dragging the line separator between two columns. If the user decides to
resize a column and starts dragging the line separator, the control fires
ColumnWidthChanging event. After the user has resized a column, the
control fires a ColumnWidthChanged event.
Introduction
The idea of having columns is to provide more information about each item of
a list view instead of a simple string for each. Consider the following example:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WinForms1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
lvwCountries.Columns.Add("Name", 120,
HorizontalAlignment.Left);
ColumnHeader colArea = new ColumnHeader();
colArea.Text = "Area";
colArea.Width = 80;
colArea.TextAlign = HorizontalAlignment.Right;
lvwCountries.Columns.Add(colArea);
lvwCountries.Items.Add("Egypt");
3. In the Properties window, click Items and click its ellipsis button
4. In the ListView Collection Editor, as the first item is selected, on the right
side, click SubItems and click its ellipsis button
8. On the right side, click Text and type Newborn Girl's Dress Set
15. Click OK
16. Click each item and complete its sub-items with the following:
Unit
Category Item Name Size Qty
Price
namespace WinForms1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
lvwCountries.Columns.Add("Name", 120,
HorizontalAlignment.Left);
ColumnHeader colArea = new ColumnHeader();
colArea.Text = "Area";
colArea.Width = 80;
colArea.TextAlign = HorizontalAlignment.Right;
lvwCountries.Columns.Add(colArea);
ListViewItem lviEgypt =
lvwCountries.Items.Add("Egypt");
lviEgypt.SubItems.Add("1,001,450");
lviEgypt.SubItems.Add("74,718,797");
lviEgypt.SubItems.Add("Cairo");
lviEgypt.SubItems.Add("eg");
The first argument of this constructor specifies the ListViewItem object that
this sub-item will belong to. The second argument is simply the string that
this sub-item will display. After defining a ListViewSubItem object, you can
pass it to the following version of the ListViewSubItemCollection.Add()
method:
public ListViewSubItem Add(ListViewItem.ListViewSubItem item);
namespace WinForms1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
lvwCountries.Columns.Add("Name", 120,
HorizontalAlignment.Left);
ColumnHeader colArea = new ColumnHeader();
colArea.Text = "Area";
colArea.Width = 80;
colArea.TextAlign = HorizontalAlignment.Right;
lvwCountries.Columns.Add(colArea);
ListViewItem lviEgypt =
lvwCountries.Items.Add("Egypt");
lviEgypt.SubItems.Add("1,001,450");
lviEgypt.SubItems.Add("74,718,797");
lviEgypt.SubItems.Add("Cairo");
lviEgypt.SubItems.Add("eg");
The first argument is the index that the new sub-item will occupy after being
inserted. The second argument is the sub-item to create.
Control
Label Property #:
Property
Label
Type:
Label Address:
Label City:
Label State:
Modifiers: Public
Items:
DC
ComboBox cbxStates MD
PA
VA
WV
Label Bedrooms:
DialogResult:
Button Cancel btnCancel
Cancel
Form
FormBorderStyle: FixedDialog
StartPosition: CenterScreen
AcceptButton: btnOK
CancelButton: btnCancel
MaximizeBox: False
MinimizeBox: False
ShowInTaskBar: False
4. On the (first) form, double-click the New Item button and change its
Click event as follows:
private void btnNewProperty_Click(object sender, EventArgs e)
{
dlgProperty.txtPropertyNumber.Text = propNumber;
dlgProperty.Text = "Altair Realtors - New Property";
if (dlgProperty.ShowDialog() == DialogResult.OK)
{
string strPropertyType =
dlgProperty.cbxPropertyTypes.Text;
string strAddress = dlgProperty.txtAddress.Text;
string strCity = dlgProperty.txtCity.Text;
string strState = dlgProperty.cbxStates.Text;
string strZIPCde = dlgProperty.txtZIPCode.Text;
string strBedrooms = dlgProperty.txtBedrooms.Text;
string strBathrooms = dlgProperty.txtBathrooms.Text;
string strMarketValue = dlgProperty.txtMarketValue.Text;
ListViewItem lviProperty =
new
ListViewItem(dlgProperty.txtPropertyNumber.Text);
lviProperty.SubItems.Add(strPropertyType);
lviProperty.SubItems.Add(strAddress);
lviProperty.SubItems.Add(strCity);
lviProperty.SubItems.Add(strState);
lviProperty.SubItems.Add(strZIPCde);
lviProperty.SubItems.Add(strBedrooms);
lviProperty.SubItems.Add(strBathrooms);
lviProperty.SubItems.Add(strMarketValue);
lvwProperties.Items.Add(lviProperty);
}
}
Font: This allows you to apply a font of your choice for a particular sub-
item. This would be done as follows:
ListViewItem lviSweden = new ListViewItem("Sweden");
lviSweden.UseItemStyleForSubItems = false;
ListViewItem.ListViewSubItem subSweden =
new ListViewItem.ListViewSubItem(lviSweden, "449,964");
. . .
subSweden = new ListViewItem.ListViewSubItem(lviSweden,
"Stockholm");
subSweden.Font = new Font("Times New Roman", 14,
FontStyle.Italic);
lviSweden.SubItems.Add(subSweden);
. . .
When called, this method resets the font, the text color, and the background
color.
Font: If you assign a new font to the item, this property allows you to
apply a font of your choice to a particular sub-item. This would be done
as follows:
. . .
ListViewItem lviAustralia = new ListViewItem("Australia");
lviAustralia.Font = new Font("Georgia", 8, FontStyle.Bold);
ListViewItem.ListViewSubItem subAustralia =
new ListViewItem.ListViewSubItem(lviAustralia,
"7,686,850");
lviAustralia.SubItems.Add(subAustralia);
subAustralia = new ListViewItem.ListViewSubItem(lviAustralia,
"19,731,984");
lviAustralia.SubItems.Add(subAustralia);
subAustralia = new ListViewItem.ListViewSubItem(lviAustralia,
"Canberra");
lviAustralia.SubItems.Add(subAustralia);
subAustralia = new ListViewItem.ListViewSubItem(lviAustralia,
"au");
lviAustralia.SubItems.Add(subAustralia);
lvwCountries.Items.Add(lviAustralia);
. . .
dlgProperty.txtPropertyNumber.Text = propNumber;
dlgProperty.Text = "Altair Realtors - New Property";
if (dlgProperty.ShowDialog() == DialogResult.OK)
{
string strPropertyType =
dlgProperty.cbxPropertyTypes.Text;
string strAddress = dlgProperty.txtAddress.Text;
string strCity = dlgProperty.txtCity.Text;
string strState = dlgProperty.cbxStates.Text;
string strZIPCde = dlgProperty.txtZIPCode.Text;
string strBedrooms = dlgProperty.txtBedrooms.Text;
float Bathrooms =
float.Parse(dlgProperty.txtBathrooms.Text);
decimal MarketValue =
decimal.Parse(dlgProperty.txtMarketValue.Text);
ListViewItem lviProperty =
new
ListViewItem(dlgProperty.txtPropertyNumber.Text);
lviProperty.SubItems.Add(strPropertyType);
lviProperty.SubItems.Add(strAddress);
lviProperty.SubItems.Add(strCity);
lviProperty.SubItems.Add(strState);
lviProperty.SubItems.Add(strZIPCde);
2. Execute the application and test the form by creating four different
records
You can also locate an item using the coordinates of a point inside its
bounding area. To use this technique, you can call the GetItemAt() method
of the ListView class. Its syntax is:
public ListViewItem GetItemAt(int x, int y);
Deleting Items
When calling this method, you must pass the index of the undesired item. If
the item is found, it would be deleted. If you provide a negative index or one
that is higher than the ListViewItemCollection.Count property, the
compiler would throw an ArgumentOutOfRangeException exception.
To delete all items from a list view, you can call the ListViewItem.Clear()
method. Its syntax is:
public virtual void Clear();
When called, this method removes all items of the list view.
Clickable: This is the default style. The columns headers appear and behave like
buttons:
Nonclickable: The columns are flat and don't change their appearance when the
user clicks one:
lvwCountries.HeaderStyle = ColumnHeaderStyle.Nonclickable;
When an item has been selected or more than one item are selected, the
selected items are stored in a list represented by the SelectedItems
property of the ListView class. The ListView.SelectedItems property is
an object based on the ListView.SelectedListViewItemCollection
class. If the ListView.MultiSelect property is set to false, this collection
would contain only one item.
The number of items selected in the control is known as the Count property
of the SelectedListViewItemCollection class. Each item selected can be
identified through the Item indexed property of the
SelectedListViewItemCollection class.
After selecting an item, if the user clicks another control, the item that was
selected would not be highlighted anymore. If you want the control to
continue showing the current selection even when the list view loses focus,
set the value of the HideSelection Boolean property of the ListView class
accordingly.
Grid Lines
lvwCountries.GridLines = true;
lvwCountries.CheckBoxes = true;
Description
Besides saving files, another common operation performed by users consists
of opening files. This refers to existing files since a file must primarily exist.
To support this operation, Microsoft Windows provides a standard object:
the Open File dialog box:
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
ofd = new OpenFileDialog();
}
}
Application.Run(new Exercise());
return 0;
}
}
The Filename
One of the most important properties of an Open dialog box is the file it
presents to the user. This is represented by the FileName property. If you
want a default file to be specified when the dialog box comes up, you can
specify this in the FileName property of the Properties window. If you need
to use this property, you should make sure the file can be found. If the file is
Most of the time, you will not be concerned with this property if you are
creating an application that will allow the users to open any files of their
choice. Once a file is located, it can be accessed using the
OpenFileDialog.FileName property.
The Filter
To make your application more effective, you should know what types of files
your application can open. This is taken care of by specifying a list of
extensions for the application. To control the types of files that your
application can open, specify their extensions using the Filter Property. The
Filter string is created exactly like that of a SaveFileDialog control as we
saw earlier.
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
After opening the dialog box, if the user selects a file and clicks OK or presses
Enter, the file would be opened.
Print Preview
Introduction
If you use the printing process that solely involves the print dialog box, you
may send a document to the printer without knowing what the printed
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
btnPrintPreview = new Button();
btnPrintPreview.Location = new Point(12, 12);
btnPrintPreview.Text = "&Print Preview...";
btnPrintPreview.Width = 100;
btnPrintPreview.Click += new
EventHandler(PreviewDocumentClick);
Controls.Add(btnPrintPreview);
}
As a dialog-based
object, to display the print preview, the
PrintPreviewDialog class inherits the ShowDialog() method from its
parent the Form class. Here is an example:
void PreviewDocumentClick(object sender, EventArgs e)
{
PrintPreviewDialog dlgPrintPreview = new
PrintPreviewDialog();
dlgPrintPreview.ShowDialog();
}
The preview area shows a sample of what a printed sheet would look like. If
the dialog box is not "aware" of what would be printed, it displays the
"Document does not contain any pages" string. This means that, in order to
display something, you must create and design it. To make this possible, the
PrintPreviewDialog class is equipped with a property named Document.
The PrintPreviewDialog.Document property is of type PrintDocument.
Therefore, in order to design a sample sheet, you should have created and
configured a PrintDocument object. Here is an example:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Printing;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
btnPrintPreview = new Button();
btnPrintPreview.Location = new Point(12, 12);
btnPrintPreview.Text = "&Print Preview...";
btnPrintPreview.Width = 100;
btnPrintPreview.Click += new
EventHandler(PreviewDocumentClick);
Controls.Add(btnPrintPreview);
dlgPrintPreview.Document = docPrint;
}
System.Windows.Forms.Application.Run(new Exercise());
return 0;
}
}
To assist you with actually designing what you want to display in the preview
area, the PrintDocument class fires an event named PrintPage. This event
is of type PrintPageEventArgs. The PrintPageEventArgs class is equipped
with a property named Graphics, which is of type Graphics. You can then
use your knowledge of the Graphics class to create or design the preview.
Here is an example:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Printing;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
btnPrintPreview = new Button();
btnPrintPreview.Location = new Point(12, 12);
btnPrintPreview.Text = "&Print Preview...";
btnPrintPreview.Width = 100;
btnPrintPreview.Click += new
EventHandler(PreviewDocumentClick);
Controls.Add(btnPrintPreview);
dlgPrintPreview.Document = docPrint;
}
If the print preview is not maximized, the content of the preview area may
appear (too) small for the user, especially if it is made of text. To enlarge it,
the user has two alternatives. If the user maximizes the window, the preview
area would also be enlarged and the content would be easier to see. As an
alternative, the user can click the arrow of the Zoom button. This would
display a list of the zoom rates:
After using the print preview, the user can close it.
Description
A scrollbar is a control that allows the user to navigate a document in two
directions by clicking a button that displays an arrow. The control is equipped
To use a scroll bar, the user can click one of the arrows. This causes the
thumb to move towards the button that was clicked. The user can also click
and hold the mouse on a button. This causes the thumb to move
continuously, as long as the button is held down, towards the button, until
the thumb cannot move any farther. The user can also drag the thumb in one
direction to move it or click between a button and the thumb. This causes the
thumb to move faster than clicking a button. The thumb of a scroll bar can be
positioned only along the scroll bar, between the scroll bar’s button.
Based on their orientation, there are two types of scroll bars: horizontal and
vertical. The horizontal scroll bar allows the user to navigate a document left
and right. The vertical scroll bar allows navigating up and down.
Based on their relationship with the parent control or owner, there are two
types of scroll bars: those that are (automatically) associated with their
parent or owner and scroll bar controls that are manually added by the
programmer.
The Palette property page of Borland C++ Builder’s Environment Options dialog
box shows the Pages list box and the Components list view. Because each
control has a long list that it cannot show completely, it is equipped with a
vertical scroll bar. This allows the user to display the hidden list when needed.
Although they are the most used containers, by default, the form and the
panel control don't display scroll bars, even if you add controls that exceed
their allocated client area:
The text box and the rich text box controls are equipped with a property
called ScrollBars.
Because they are always likely to display a long text, the multi-line text box
and the rich text box controls are natively ready to display either or both
scroll bars. This is easily done using the ScrollBars property. It provides four
options as follows:
Value Comments
Introduction
Microsoft Windows provides two other types of scroll bars, considered
complete controls in their own right. Like all other controls, these ones must
be explicitly created; that is, they are not added automatically but they
provide most of the same basic functionality as if the operating system's
automatically added the scroll bars.
As you can see from this illustration, the minimum value of a vertical scroll bar
is on top. This is the way the vertical scroll bar control of the .NET Framework
is configured. On a regular application, the minimum of a vertical scroll is in the
bottom section of the control.
At run time, when the user scrolls the control, you can find the position of the
bar by getting the value of the Value property.
Introduction
Microsoft Windows provides two other types of scroll bars, considered
complete controls in their own right. Like all other controls, these ones must
be explicitly created; that is, they are not added automatically but they
provide most of the same basic functionality as if the operating system's
automatically added the scroll bars.
In the same way, if you set the value of Value to a value higher than the
Maximum, you would receive an Invalid Property Value error. To
programmatically set the position of the bar, assign the desired value, which
must be between Minimum and Maximum, to the Value property.
At run time, when the user scrolls the control, you can find the position of the
bar by getting the value of the Value property.
Introduction
The Environment class provides a special property used to count a specific
number of lapses that have occurred since you started your computer. This
information or counter is available through the TickCount property. This
property counts the number of milliseconds that have elapsed since you
started your computer. Just like the timer control, what you do with the result
of this property is up to you and it can be used in various circumstances.
3. From the Components section of the Toolbox, click the Timer control
and click the form
namespace CompAppElapsedTime1
{
public partial class Form1 : Form
{
private int CompTime;
public Form1()
{
InitializeComponent();
}
8. Double-click the timer1 control and implement its Timer event as follows:
private void timer1_Tick(object sender, EventArgs e)
{
int CurTickValue = Environment.TickCount;
int Difference = CurTickValue - CompTime;
13. To make the values easier to read, change the code of the OnTimer
event as follows:
private void timer1_Tick(object sender, EventArgs e)
{
int curTickValue = Environment.TickCount;
int difference = curTickValue - CompTime;
Description
A checked list box is a list box whose items are each equipped with a check
box. In the following Customize dialog box of Microsoft Office, the control
under the Toolbars label is a checked list box:
A checked list box combines the functionalities of the list box and the check
box controls. As a list box, it displays each of its items on a line. If there are
too many items than the control can display, it would be equipped with a
vertical scroll bar.
To select an item in the list, the user can click the desired string. The most
important and obvious characteristic of the checked list box is that each item
displays a check box on its left. This box allows the user to select or deselect
each item. To select an item, the user must click its box and not its string, to
indicate an explicit selection. This draws a check mark in the box. As
described with the check box control, the user can deselect an item by
removing the check mark. The check mark indicates that an item is selected
and the absence of the check mark indicates the contrary. Like the check box
control, you can allow the user to indicate a "half-checked" item. In this case,
a check box can appear unchecked, checked, or grayed.
namespace AltairRealtors1
{
public class AvailableProperty
{
long propNbr;
string propType;
string adrs;
string ct;
string stt;
int zip;
short beds;
float baths;
double mValue;
public AvailableProperty()
{
}
public Exercise()
{
InitializeComponent();
}
Controls.Add(lbxPersonalRelationships);
}
}
Other
Control Text Name
Properties
BorderStyle:
FixedSingle
Font: Times
Label Altair Realtors
New Roman,
21.75pt,
style=Bold
CheckedListBox lbxPropertiesTypes
Label Prop #
Label Address
Label City
Label State
Label Beds
Label Baths
lbxPropertyNumber
ListBox
s
ListBox lbxAddresses
ListBox lbxCities
ListBox lbxStates
ListBox lbxZIPCodes
ListBox lbxBathrooms
ListBox lbxMarketValues
Introduction
The CheckedListBox class is derived from the ListBox class. This means
that the checked list box possesses all the public (and protected)
characteristics of the list box and its parent the ListControl class. This
control also uses the HorizontalScrollbar and the HorizontalExtent
properties that behave exactly as we reviewed for the list box. It also uses
the SelectionMode property with the same behavior as that of the list box.
public Exercise()
{
InitializeComponent();
}
lbxPersonalRelationships.Items.Add("Family Member");
lbxPersonalRelationships.Items.Add("Friend");
lbxPersonalRelationships.Items.Add("Classmate");
lbxPersonalRelationships.Items.Add("Business Partner");
lbxPersonalRelationships.Items.Add("Simple
Acquaintance");
lbxPersonalRelationships.Items.Add("Undefined");
Controls.Add(lbxPersonalRelationships);
}
}
Remember that you can also add an array of items by calling the AddRange()
and you can insert an item using the Insert() method.
2. In the Properties window, click Items and click its ellipsis button
3. In the String Collection Editor, type Single Families and press Enter
Checking an Item
As mentioned already, the main difference between a list box and a checked
list is the presence of check marks in the former. When using the control, the
user can click one or more check boxes. Here is an example:
After the user has clicked a few check boxes, you may want to find out which
ones are checked. The checked list box provides two techniques you can use.
As seen for the list box, each item of the control has an index. When one, a
few, or all items have been checked (those that display a check mark), the
indices of the checked items are stored in a collection represented by the
CheckedIndices property. This property is based on the nested
CheckedIndexCollection collection class. The CheckedIndexCollection
class implements the IList, the ICollection, and the IEnumerable
interfaces.
When the user has clicked item to put a check mark on it, the control fires the
ItemCheck event. Its formula is:
This method takes as argument a value that can identify an item from the
checked list box. If the item is found and it is checked, this method returns
true. Otherwise, it returns false.
namespace AltairRealtors1
{
public partial class RealEstate : Form
{
AvailableProperty[] properties = new
AvailableProperty[15];
public RealEstate()
{
InitializeComponent();
}
4. On the form, double-click the Show button and implement its Click event
as follows:
private void btnShow_Click(object sender, EventArgs e)
{
lbxPropertyNumbers.Items.Clear();
lbxAddresses.Items.Clear();
lbxCities.Items.Clear();
lbxStates.Items.Clear();
lbxZIPCodes.Items.Clear();
lbxBedrooms.Items.Clear();
lbxBathrooms.Items.Clear();
lbxMarketValues.Items.Clear();
lbxPropertyNumbers.Items.Add(prop.PropertyNumber.ToString());
lbxAddresses.Items.Add(prop.Address);
lbxCities.Items.Add(prop.City);
lbxStates.Items.Add(prop.State);
lbxZIPCodes.Items.Add(prop.ZIPCode);
lbxBedrooms.Items.Add(prop.Bedrooms);
lbxBathrooms.Items.Add(prop.Bathrooms);
lbxMarketValues.Items.Add(prop.MarketValue);
}
}
}
if (lbxPropertiesTypes.CheckedItems.Contains("Townhouses"))
{
foreach (AvailableProperty prop in properties)
{
if (prop.PropertyType == "Townhouse")
{
lbxPropertyNumbers.Items.Add(prop.PropertyNumber.ToString());
lbxAddresses.Items.Add(prop.Address);
lbxCities.Items.Add(prop.City);
lbxStates.Items.Add(prop.State);
lbxZIPCodes.Items.Add(prop.ZIPCode);
lbxBedrooms.Items.Add(prop.Bedrooms);
lbxBathrooms.Items.Add(prop.Bathrooms);
lbxMarketValues.Items.Add(prop.MarketValue);
}
}
}
if
(lbxPropertiesTypes.CheckedItems.Contains("Condominiums"))
{
foreach (AvailableProperty prop in properties)
{
if (prop.PropertyType == "Condominium")
{
lbxPropertyNumbers.Items.Add(prop.PropertyNumber.ToString());
lbxAddresses.Items.Add(prop.Address);
lbxCities.Items.Add(prop.City);
lbxStates.Items.Add(prop.State);
lbxZIPCodes.Items.Add(prop.ZIPCode);
lbxBedrooms.Items.Add(prop.Bedrooms);
lbxBathrooms.Items.Add(prop.Bathrooms);
lbxMarketValues.Items.Add(prop.MarketValue);
9. To make sure that when a user clicks an item in one list box, the
corresponding item gets selected in the other list boxes, on the form,
click the Prop # list box
13. In the Properties window, click the Events button and double-click
SelectedIndexChanged
To support the ability to automatically put a check mark on an item when the
user clicks it, the CheckedListBox provides the CheckOnClick Boolean
property. Its default value is False. If you want the items to be automatically
checked, set this property to true.
On an existing checked list box, to find out if the its items are automatically
checked, get the value of the CheckOnClick property.
ThreeDCheckBoxes
False True
If the control displays a combo box and if the user clicks the arrow on the
When the check box is checked, the user can change the displayed date.
When the check box is unchecked, the control is displayed and the user
cannot change the date. The user must first put a check mark in the check
box in order to be able to change the date.
The state of the check box is controlled by the Boolean Checked property. If
the user clicks the check box to put a check mark in it, this property's value
becomes true.
If the control is equipped with a spin button, to change the month, the user
can click the month and then click one of the arrow buttons of the spin
control. The user can also use the arrow keys to get the same effect. In the
same way, the user can change the values of the day or the year.
If the control appears as a combo box, the user can click the arrow button.
This would display a calendar:
When the calendar displays, the control throws a DropDown event. The
DropDown event is of type EventArgs. This means that this event does not
carry any significant information, other than to let you know that the calendar
of the control has been dropped to display.
While the calendar is displaying, the user can change the month, change the
year, or click a date to select one. T user can still change the date in the text
box side of the control. However it is done, on the text box or on the
calendar, when the date of the control has been changed, the control fires a
ValueChanged event. The ValueChanged event, which is the default event of
the control, is of type EventArgs, meaning it does not give you any detail
about the date that was selected or about anything the user did. You would
use your own means of finding out what date the user had selected or
specified. This can easily be done by getting the Value property of the
control.
If the control is displaying a calendar, once the user clicks a date, the
calendar disappears and the control becomes a combo box again. When the
calendar retracts, the control fires a CloseUp event. The CloseUp event is of
type EventArgs, which means it does not carry any particular information
other than letting you know that the calendar has been closed.
The font used on the text throughout the calendar is set by the
CalendarFont property
The background color of the current month of the calendar is set by the
CalendarMonthBackground property
The minimum and the maximum dates are specified using the MinDate
and the MaxDate properties
The displayed calendar object allows the user to select a date using the same
techniques we described for the alendar control. The calendar part of the
date time picker control displays using the same colors and other properties
as we saw with the calendar control. After the user has selected a date, the
date value displays in the text box section of the combo box and the calendar
disappears.
This means that you should be reluctant to let the users type whatever they
want. The less they type, the less checking you need to do.
The Date Time Picker control uses some events that the month calendar
control does not have. Whenever the user changes the date or time value of
the control, a ValueChanged event fires. You can use this event to take some
action such as indicating to the user that the new date is invalid.
If the Format property of the control is set to Date and if the ShowUpDown
property is set to False, when the user clicks the arrow of the combo box to
display the calendar part of the date time picker control, the DropDown event
fires. On the other hand, if the user clicks the arrow to retract the calendar,
the CloseUp event fires. Both events are of EventArgs type.
Introduction
In some application that deals with graphic, you may use only one picture
but in various, if not most other applications, such as those used to display,
exchange, or switch pictures, you may deal with different pictures. In such a
type of application, sometimes the pictures are of different sizes, even
including unpredictable sizes. In another type of application, some of the
pictures you use may have the (exact) same size. For this type, instead of
using each picture individually, you can store them in a collection, then access
each picture when needed.
An image list is a collection of icons or pictures that are stored so that each
icon or picture can be located by an index. The icons or pictures must be of
the same size and they should be the same type. This means that the
When it comes to design, there are two types of image lists. Each picture can
be added individually to the collection, or all of the pictures can be designed
in a longer picture and, inside of that long picture, you would use a technique
to locate each picture.
Once you get an image list, there is no pre-defined way you must use it.
Some Windows controls use an image list to use the pictures they need but
there are various other unpredictable ways you can use an image list.
1. To create a new application, on the main menu, click File -> New ->
Project...
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
lstImages = new ImageList();
}
}
return 0;
}
}
The ImageList class is equipped with another constructor whose syntax is:
public ImageList(IContainer container);
1. From the Components section of the Toolbox, click ImageList and click
the form
3. From the Components section of the Toolbox, click Timer and click the
form
5. From the Common Controls section of the Toolbox, click PictureBox and
click the form
7. Save all
To create or design your bitmaps, you can use either the bitmap designer of
Microsoft Visual Studio or you can use a more advanced external application
to prepare the pictures. Although the pictures used in an image list are
usually square (16x16, 32x32, 48x48, 96x96, etc), you can use a different
length and a different height but, if you are creating individual pictures, they
should each have the same size (same length and same height).
Instead of using different pictures, you can create one long picture whose
sections would be used to identify each picture. There is no particular way
you must design the long picture and there is no real rule about its
dimensions: the size would become an issue when it is time to use the
picture(s). Alternatively, when creating the picture, if it will include the
different pictures that would be considered in the list, make sure you know
where each sectional picture starts and where it ends. Here is an example:
After preparing the pictures, you can get ready to create the image list. If you
want, you can specify the size of each picture before actually creating the list.
To support this, the ImageList class is equipped with a property named
ImageSize. The ImageSize property is of type Size. You can use it to
specify the size of each picture. Here is an example:
using System;
using System.Drawing;
using System.Windows.Forms;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
lstImages = new ImageList();
lstImages.ImageSize = new Size(256, 256);
}
}
If the image list has been created already, to find out the size of the picture,
you can get the value of the ImageSize property.
Under the form, click lstPictures and, in the Properties window, set the
ColorDeph to Depth32Bit
In the Properties window, click the ellipsis button of the Images field
This would open the Images Collection Editor. To add a picture, you can click
the Add button, locate a picture and select it. You can continue doing this
until you have selected all necessary pictures. Here is an example:
To assist you with creating the list of images, the ImageList class is
equipped with a property named Images, which is a collection. The
ImageList.Images property is of type ImageCollection. The
ImageCollection class implements the IList, the ICollection, and the
IEnumerable interfaces.
Using the ImageCollection class through the Images property, you can add
the necessary icons or pictures one at a time. To help you with this, the
ImageCollection class implements the Add() method. If you are creating a
list of icons, you can call the following version of the Add() method:
public void Add(Icon value);
If you are creating a list of pictures, you can call the following version of the
Add() method:
Here is an example:
public class Exercise : Form
{
private ImageList lstImages;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
lstImages = new ImageList();
lstImages.ImageSize = new Size(256, 256);
Instead of adding one picture at a time, you can first store them in an array.
To add an array of pictures, the ImageCollection class provides a method
named AddRange and whose syntax is:
public void AddRange(Image[] images);
Here is an example:
void InitializeComponent()
{
lstImages = new ImageList();
lstImages.ImageSize = new Size(256, 256);
Image[] images =
{
Image.FromFile(@"E:\Programs\image3.jpg"),
Image.FromFile(@"E:\Programs\Image4.jpg"),
Image.FromFile(@"E:\Programs\Image5.jpg")
};
lstImages.Images.AddRange(images);
}
2. In the Properties window, click Images and click the ellipsis button
3. In the Images Collection Editor, click Add, locate one of the pictures you
had saved, select it, and click Open
5. Click OK
To support the ability to display the pictures of an image list, the ImageList
class is equipped with a method named Draw. When calling this method,
because the image list doesn't know where it would be used, and because the
target control would not define where the picture is coming from, the primary
argument to this method is the platform on which to display the picture. This
platform is a Graphics object. Once you have decided on the receiving
graphics, you must specified the location where the picture would be
Alternatively, you can specify the location by a Point value. In this case, you
would use the following version of the method:
public void Draw(Graphics g, Point pt, int index);
In both cases, the last argument is the index of the desired picture within the
collection.
1. Under the form, double-click timer1 and change the file as follows:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace ImageViewer1
{
public partial class Form1 : Form
{
static int index = 0;
public Form1()
{
InitializeComponent();
}
Introduction
Microsoft Visual Basic 6.0 provides a convenient text box that allows you
to assist the user with text entry in a text box. This control is called MaskEdit.
To use this control, you must explicitly add it as a COM Component of the
Microsoft Masked Edit Control.
MaskEdit Characteristics
The most important property of a MaskEdit control, which sets it apart from
the (traditional) text box control, is its ability to control what the user can and
If none of the masks in the list suits you, you still have two alternatives. You
can type your own desired mask in the Format field. The characters you can
use are:
Date
Format Used For Description
Time
Format Used For Description
Besides the Format property, you can create a mask using the Mask field of
the Properties window. Both allow you to use many other characters to create
custom masks.
Introduction
As opposed to directly printing a file, a user may want to perform some
preliminary preparation on the document or the printer. Microsoft Windows
provides another dialog box used to control printing. It is called Page Setup:
After selecting the printer, the user can click OK. The options of the Page
Setup dialog box depend on the driver of the printer selected in the Name
combo box. The Page Setup dialog box allows the user to customize the
appearance of the paper on which the document would be printed.
On the Page Setup, the user can click the arrow of the Size combo box and
select one of the configured sizes of paper. The characteristics of the paper
are controlled by the PageSettings class that we mentioned earlier. For
example, if the printer has many trays, as indicated by the driver of the
selected printer, the user can select which tray would be used when printing.
As it happens, one printer can have only one tray while another printer can
have 3, 5, or more trays.
If the desired printer is on a network, the user can click the Network button
to locate it. To programmatically show or hide the Network button, specify a
false or true result to the PageSetupDialog.ShowNetwork Boolean property.
The user also has the option to print the document in Portrait (vertical) or in
Landscape (horizontal) position. The option to allow the user to select Portrait
or Landscape is controlled by the AllowOrientation Boolean property.
Description
A progress bar is a control that displays (small) rectangles that are each filled
with a color. These (small) rectangles are separate but adjacent each other so
that, as they display, they produce a bar. To have the effect of a progress
bar, not all these rectangles display at the same time. Instead, a numeric
value specifies how many of these (small) rectangles can display at one time.
public Exercise()
{
InitializeComponent();
}
Controls.Add(progress);
Introduction
The progress bar shares the various characteristics of other graphical controls
(that is, the objects derived from the Control class). These include the
location, the size, the back color, the size, the cursor, the ability to be
anchored, the ability to the docked, the ability to be shown or hidden, and the
ability to be enabled or disabled, etc.
Here is an example:
Controls.Add(progress);
progress.Minimum = 0;
progress.Maximum = 255;
Controls.Add(progress);
}
The small rectangles would be drawn from the left (the Minimum value) to the
right (the Maximum value) sides of the control.
After clicking OK, the value of the Minimum would be reset to that of the
Value property. In the same way, if you set the value of Value to a value
higher than Maximum, you would receive an error.
At run time, you can assign the desired value to the Value property. Once
again, avoid specifying a value that is out of range. Here is an example:
private void InitializeComponent()
{
Text = "Progressive Studies";
Size = new Size(282, 80);
progress.Minimum = 0;
progress.Maximum = 255;
progress.Value = 88;
Controls.Add(progress);
}
progress.Minimum = 0;
progress.Maximum = 255;
progress.Value = 88;
progress.Step = 12;
Controls.Add(progress);
}
When the control draws one of its rectangles based on the Step value, it calls
the PerformStep(). Its syntax is:
public void PerformStep();
After a small rectangle has been drawn, the current value is incremented by
the value of the Step property. If you want to increase the value of the
control to a value other than that of the Step property, you can call the
Increment() method. Its syntax is:
public Exercise()
{
InitializeComponent();
void InitializeComponent()
{
Text = "Progressive Studies";
Size = new Size(284, 115);
progress.Minimum = 0;
progress.Maximum = 255;
progress.Value = 88;
progress.Step = 12;
Controls.Add(progress);
Controls.Add(btnIncrement);
}
If you decide to use the Marquee style, the progress bar will continually show
its animation of small rectangles moving at a speed set from the
MarqueeAnimationSpeed integral property and you cannot get the value of
the progress bar.
Introduction
A splitter is an object that divides a container in two vertical or two
horizontal sections. It makes it possible for one section to be enlarged,
narrowed, heightened, or shrunk while the other section is narrowed,
enlarged, shrunk, or heightened. Based on this behavior, one section gets
more room while the other gets smaller. You are probably familiar with this
description if you have used Windows Explorer. In most cases, a splitter is
made obvious by displaying a bar that divides the sections.
To use the splitter, the user can click its bar and drag it left, right, up, or
down, depending on the orientation of the splitter and what the user is trying
to accomplish. After getting the desired position, the user can release the
mouse.
Creating a Splitter
To support splitters, the .NET Framework provides the split container. It is
represented in the library by the SplitContainer class and in the Toolbox
by the SplitContainer object. To add a split container to your application,
from the Containers section of the Toolbox, click the SplitContainer object
and click a form of your application. Once you do this, an object called a
split container fills the form, divides itself in two, and gets equipped with two
objects named Panel1 and Panel2. In reality, a split container is an object
made of two panels separated by a bar. In each panel, you can then add the
controls as you see fit. A control added to one of the panels would become a
child of that panel.
Then, when you add a split container, it can use only the remaining area of
the form:
In the same way, before adding a split container, you should prepare the
form for objects you want to place on the form but that would not belong to
the split container.
Just you can have a split container made of two parts, you can have more
than two resizable sections. To do this, after adding a split container, add
another split container to one of the panels of an existing split container.
Introduction
After adding a split container to a form, it may become difficult to select it
from the form. To select, use the combo box above the Properties window. If
you click an area of the split container, the corresponding panel becomes
selected and you can change its characteristics using the Properties window
but you can neither move nor delete a panel from the split container.
As mentioned already, after adding a split container to a form, it sets its Dock
property to Fill. This is the default behavior. If you do not want the
container to fill the available area of the form, you can change the value of its
Dock property.
Because each panel has the ability to show a picture and to hold their
controls, their backgrounds take priority over the background of the split
container.
To prevent the user fromdragging the bar, you can set the
SplitContainer.IsSplitterFixed property to True. If you do this, when
the user positions the mouse on the bar, the cursor would keep its pointing
arrow shape.
Fixing a Panel
After adding a split container and if the Dock property of the control is to a
value other than None, when the user resizes the form, the border of the split
container follows the movement of the mouse and the bar also moves by a
certain rate to resize the opposite panel:
Introduction
A timer is a non-spatial object that uses recurring lapses of time in a
computer or in your application. To work, every lapse of period, the
control sends a message to the operating system. The message is something
to the effect of "I have counted the number of lapses you asked me to
count".
As opposed to the time that controls your computer, a timer is partly but
greatly under your control. Users do not see nor do they use a timer as a
control. As a programmer, you decide if, why, when, and how to use this
control.
To support timers, the .NET Framework provides the Timer control from the
Toolbox and it is implemented through the Timer class. To add it to your
application at design time, on the Toolbox, click Timer and click the form.
namespace ScreenSaver1
{
public partial class Form1 : Form
{
static int MoveCounter = 0;
public Form1()
{
InitializeComponent();
}
if (MoveCounter == 20)
Close();
MoveCounter++;
}
}
}
5. Display the form again and, in the Events section of the Properties
window, double-click KeyDown
Characteristics of a Timer
A timer is an object used to count lapses of time and send a message when it
has finished counting. Each count is called a tick. When a tick occurs, the
control fires a Tick event. This Tick event is of type EventArgs, meaning
that it doesn't provide more information than to let you know that a lapse has
occurred.
In order for a timer to count, you must tell it when it should start counting. In
some applications, you may want the control to work full-time while in some
other applications, you may want the control to work only in response to an
intermediate event. The ability to stop and start a Timer control can be set
using the Enabled Boolean property. When, or as soon as, this property is set
to true, the control starts counting. You can also make it start by calling the
Timer.Start() method. Its syntax is:
If, when, or as soon as, the Enabled property is set to false, the control stops
and resets its counter to 0. You can also stop the timer by calling the
Timer.Stop() method. Its syntax is:
1. From the Components section of the Toolbox, click the Timer control
and click the form
4. In the top section of the file, under the other using System lines, type
using System.Drawing.Drawing2D;
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.Cross,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DarkDownwardDiagonal,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DarkHorizontal,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DarkUpwardDiagonal,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DarkVertical,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DashedDownwardDiagonal,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DashedHorizontal,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DashedUpwardDiagonal,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DashedVertical,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DashedVertical,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DiagonalBrick,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DiagonalCross,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.Divot,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DottedDiamond,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DottedGrid,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.ForwardDiagonal,
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row1[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row1[i]);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row2[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row2[i]);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row3[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row3[i]);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row4[i]);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row5[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row5[i]);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row6[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row6[i]);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row7[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row7[i]);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row8[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row8[i]);
}
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row1a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row1a);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row2a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row2a);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row3a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row3a);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row4a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row4a);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row5a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row5a);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row6a);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row7a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row7a);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row8a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row8a);
}
Introduction
A tree view is a control that resembles an upside
down tree and displays a hierarchical list of items.
Like a normal tree, a tree view starts in the top
section with an object referred to as the root. Under
the root, a real tree is made of branches and leaves.
In an application, a tree view is only made of
branches and each branch is called a node. In real
world, a leaf cannot have a branch as its child, only
a branch can have another branch as its child and a
branch can have a leaf as a child. In an application,
a node (any node) can have a node as a child.
Most of the time, a tree has only one root but a tree
in an application can have more than one root.
using System;
using System.Drawing;
using System.Windows.Forms;
public Exercise()
{
InitializeComponent();
}
Controls.Add(tvwCountries);
}
}
Panel Height: 2
TreeView tvwAutoParts
GroupBox
colPartNumber Part #
Columns
colPartName Part Name 300
Label Part #
Label Qty
TextBox txtPartNumber1
TextBox txtPartName1
TextBox txtPartNumber2
TextBox txtPartName2
TextBox txtPartNumber3
TextBox txtPartName3
TextBox txtPartNumber4
TextBox txtPartName4
TextBox txtPartNumber5
TextBox txtPartName5
TextBox txtPartNumber6
TextBox txtPartName6
As its name indicates, the Nodes property carries all of the branches of a tree
view. This means that the Nodes property in fact represents a collection. Each
member of this collection is called a node and it is an object based on the
TreeNode class.
This method takes as argument the string that the branch will display. This
method is also the prime candidate to create a root node. Here is an example
of calling it:
tvwCountries.Nodes.Add("World");
Controls.Add(tvwCountries);
}
2. To create the first node of the tree, implement the event as follows:
private void Central_Load(object sender, EventArgs e)
{
TreeNode nodRoot = tvwAutoParts.Nodes.Add("College
Park Auto-Parts");
7. To create a class that can holds a structured item of a list, change the
class as follows:
using System;
namespace CollegeParkAutoParts2
{
public class PartDescription
{
// These members will be used to define a car part
private long ID;
private int yr;
public PartDescription()
{
this.ID = 0;
this.yr = 1960;
this.mk = "";
this.mdl = "";
this.name = "Unknown";
this.price = 0.00M;
}
Introduction
The other version of the TreeNodeCollection.Add() method uses the
following syntax:
public virtual int Add(TreeNode node);
The TreeNode class is equipped with various constructors you can use to
instantiate it. Its default constructor allows you to create a node without
This constructor takes as argument the string that the node will display. Here
is an example of using it and adding its newly create node to the tree view:
private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 280);
Controls.Add(tvwCountries);
}
Controls.Add(tvwCountries);
}
tvwCountries.Nodes.Add("World");
tvwCountries.Nodes.Add("Jupiter");
tvwCountries.Nodes.Add("Neptune");
tvwCountries.Nodes.Add("Uranu");
Controls.Add(tvwCountries);
}
Alternatively, if you have many branches to add to the tree, you can first
create them as an array of TreeNode values, then called the
TreeNodeCollection.AddRange() method. The syntax of this method is:
TreeNode[] nodPlanets =
{
new TreeNode("World"),
new TreeNode("Jupiter"),
new TreeNode("Neptune"),
new TreeNode("Uranu")
};
tvwCountries.Nodes.AddRange(nodPlanets);
Controls.Add(tvwCountries);
}
At run time, to create a child node, first get a reference to the node that will
be used as its parent. One way you can get this reference is to obtain the
returned value of the first version of the TreeNodeCollection.Add()
method. As its syntax indicates, this method returns a TreeNode object.
We have used the default constructor of the TreeNode class and the
constructor that takes as argument a string. The TreeNode class provides
another constructor whose syntax is:
public TreeNode(string text, TreeNode[] children);
The first argument of this method is the string that the new node this
constructor creates will display. The second argument is a collection of the
child nodes of this branch. The collection is passed as an array. Based on this,
you use this constructor to create a new node including its children. After
creating the new node, you can pass it to the TreeNodeCollection.Add()
method as we did earlier. Here is an example:
private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 280);
TreeNode[] nodContinents =
{
new TreeNode("Africa"),
new TreeNode("America"),
new TreeNode("Asia"),
new TreeNode("Europe")
};
Controls.Add(tvwCountries);
}
Controls.Add(tvwCountries);
}
namespace CollegeParkAutoParts2
{
public Central()
{
InitializeComponent();
}
if ((nodYear.Text ==
part.CarYear.ToString()) &&
(nodMake.Text == part.Make))
{
if (!lstModels.Contains(part.Model))
lstModels.Add(part.Model);
}
}
lstCategories.Add(part.Category);
}
}
2. Save all
Here is an example:
private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 320);
. . . No Change
If you create a node and add it to a branch that already contains another
node, the new node is referred to as a sibling to the existing child node.
Node Selection
Besides looking at a node, probably the primary action a user performs on a
tree is to select an item. To select a node in the tree, the user can click it. To
programmatically select a node, assign its reference to the
TreeView.SelectedNode property. Here is an example:
tvwCountries.SelectedNode = nodAmerica;
Controls.Add(tvwCountries);
}
After selecting a node, the tree view indicates the item selected by
highlighting it. In the following picture, the America node is selected:
To programmatically find out what item is selected in the tree, get the value
of the TreeView.SelectedNode Boolean property. If no node is selected,
this property produces null. Alternatively, you can check the value of a node's
TreeNode.IsSelected Boolean property to find out if it is currently selected.
Node Edition
After locating a node, the user may want to change its text. To change the
string of a node, it must be put to edit mode. To do this, you can call the
TreeNode.BeginEdit() method. Its syntax is:
When a node is in edit mode, the caret blinks in its edit box section. The user
can then type a new string or edit the existing string. After setting the (new)
string, the user can press Enter or may click somewhere. At this time, you
need to indicate that the user has finished this operation. To do this, you can
call the TreeNode.EndEdit() method. Its syntax is:
public void EndEdit(bool cancel);
Just before this method, you can check the content of the string that was
added or edited. This allows you to accept or reject the change. The
argument to the EndEdit() method allows you to validate or cancel the
editing action.
Node Location
The first argument to this method is the index that the new node will occupy
when created. The second argument is a reference to the new node to be
created. Here is an example of using it:
private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 320);
TreeNode[] nodContinents =
{
new TreeNode("Africa"),
new TreeNode("America"),
new TreeNode("Asia"),
new TreeNode("Europe")
};
Controls.Add(tvwCountries);
}
To use this method, you must know either the Point location or the x and y
coordinates of the node. If you provide valid arguments to this method, it
returns a reference to the TreeNode located at the argument. Here is an
example:
private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 320);
TreeNode[] nodContinents =
{
new TreeNode("Africa"),
new TreeNode("America"),
new TreeNode("Asia"),
new TreeNode("Europe")
};
tvwCountries.ExpandAll();
TreeNode nodBranch = tvwCountries.GetNodeAt(22, 48);
Controls.Add(tvwCountries);
Text = nodBranch.Text;
}
After creating a tree, to get a reference to the first child node, you can
retrieve the TreeNode.FirstNode property. You would use code as follows:
Text = nodFirst.Text;
}
To get a reference to the sibling above a node, if any, you can retrieve its
TreeNode.PrevNode property. To get a reference to the sibling below a
node, if any, you can retrieve its TreeNode.NextNode property.
To find whether a tree view contains a certain node, you can call the
TreeNodeCollection.Contains() method. Its syntax is:
This method expects as argument a reference to the node to look for. If the
tree contains that node, the method returns true. If the node is not found,
this method returns false.
if( nodClicked.Level == 4 )
lvwAutoParts.Items.Clear();
try
{
try
{
foreach (PartDescription part in parts)
{
if ((part.Category == nodClicked.Text)
&&
(part.Model ==
nodClicked.Parent.Text) &&
(part.Make ==
nodClicked.Parent.Parent.Text) &&
(part.CarYear.ToString() ==
nodClicked.Parent.Parent.Parent.Text))
{
ListViewItem lviAutoPart = new
ListViewItem(part.PartNumber.ToString());
lviAutoPart.SubItems.Add(part.PartName);
lviAutoPart.SubItems.Add(part.UnitPrice.ToString());
lvwAutoParts.Items.Add(lviAutoPart);
}
}
}
catch (NullReferenceException)
{
}
}
catch (NullReferenceException)
{
}
}
5. In the Properties window, click the Events button and, in the Events
section, double-click DoubleClick
try
{
subTotal2 =
decimal.Parse(this.txtSubTotal2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal3 =
decimal.Parse(this.txtSubTotal3.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
subTotal4 =
decimal.Parse(this.txtSubTotal4.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
try
{
subTotal6 =
decimal.Parse(this.txtSubTotal6.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
if (lvwAutoParts.SelectedItems.Count == 0 ||
lvwAutoParts.SelectedItems.Count > 1)
return;
if (txtPartNumber1.Text == "")
{
txtPartNumber1.Text = lviAutoPart.Text;
txtPartName1.Text =
lviAutoPart.SubItems[1].Text;
txtUnitPrice1.Text =
lviAutoPart.SubItems[2].Text;
txtQuantity1.Text = "1";
txtSubTotal1.Text =
lviAutoPart.SubItems[2].Text;
txtQuantity1.Focus();
}// If the previous Part # text box is not empty,
then use the next one
else if (txtPartNumber2.Text == "")
{
txtPartNumber2.Text = lviAutoPart.Text;
txtQuantity2.Text = "1";
txtSubTotal2.Text = txtUnitPrice2.Text;
txtQuantity2.Focus();
}
else if (txtPartNumber3.Text == "")
{
txtPartNumber3.Text = lviAutoPart.Text;
txtPartName3.Text =
lviAutoPart.SubItems[1].Text;
txtUnitPrice3.Text =
lviAutoPart.SubItems[2].Text;
txtQuantity3.Text = "1";
txtSubTotal3.Text = txtUnitPrice3.Text;
txtQuantity3.Focus();
}
else if (txtPartNumber4.Text == "")
{
txtPartNumber4.Text = lviAutoPart.Text;
txtPartName4.Text =
lviAutoPart.SubItems[1].Text;
txtUnitPrice4.Text =
lviAutoPart.SubItems[2].Text;
txtQuantity4.Text = "1";
txtSubTotal4.Text = txtUnitPrice4.Text;
txtQuantity4.Focus();
}
else if (txtPartNumber5.Text == "")
{
txtPartNumber5.Text = lviAutoPart.Text;
txtPartName5.Text =
lviAutoPart.SubItems[1].Text;
txtUnitPrice5.Text =
lviAutoPart.SubItems[2].Text;
txtQuantity5.Text = "1";
txtSubTotal5.Text = txtUnitPrice5.Text;
txtQuantity5.Focus();
}
else if (txtPartNumber6.Text == "")
{
txtPartNumber6.Text = lviAutoPart.Text;
txtPartName6.Text =
lviAutoPart.SubItems[1].Text;
txtUnitPrice6.Text =
lviAutoPart.SubItems[2].Text;
txtQuantity6.Text = "1";
txtSubTotal6.Text = txtUnitPrice6.Text;
txtQuantity6.Focus();
CalculateOrder();
}
11. Return to the form and click the second text box under Qty
try
{
qty = int.Parse(this.txtQuantity2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice =
decimal.Parse(this.txtUnitPrice2.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
CalculateOrder();
}
13. Return to the form and click the third text box under Qty
14. In the Events section of the Properties window, double-click the Leave
field and implement the event as follows:
private void txtQuantity3_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity3.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
CalculateOrder();
}
15. Return to the form and click the fourth text box under Qty
16. In the Events section of the Properties window, double-click the Leave
field and implement the event as follows:
private void txtQuantity4_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity4.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice =
decimal.Parse(this.txtUnitPrice4.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
CalculateOrder();
}
17. Return to the form and click the fifth text box under Qty
try
{
qty = int.Parse(this.txtQuantity5.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
{
unitPrice =
decimal.Parse(this.txtUnitPrice5.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
CalculateOrder();
}
19. Return to the form and click the sixth text box under Qty
20. In the Events section of the Properties window, double-click the Leave
field and implement the event as follows:
private void txtQuantity6_Leave(object sender, EventArgs e)
{
int qty = 0;
decimal unitPrice = 0.00M, subTotal = 0.00M;
try
{
qty = int.Parse(this.txtQuantity6.Text);
}
catch (FormatException)
{
MessageBox.Show("Invalid Value");
}
try
CalculateOrder();
}
22. Double-click the first Remove button and implement its event as follows:
private void btnRemove1_Click(object sender, EventArgs e)
{
txtPartNumber1.Text = "";
txtPartName1.Text = "";
txtUnitPrice1.Text = "0.00";
txtQuantity1.Text = "0";
txtSubTotal1.Text = "0.00";
CalculateOrder();
}
24. Double-click the second Remove button and implement its event as
follows:
private void btnRemove2_Click(object sender, EventArgs e)
{
txtPartNumber2.Text = "";
txtPartName2.Text = "";
txtUnitPrice2.Text = "0.00";
txtQuantity2.Text = "0";
txtSubTotal2.Text = "0.00";
CalculateOrder();
}
26. Double-click the third Remove button and implement its event as
follows:
private void btnRemove3_Click(object sender, EventArgs e)
{
CalculateOrder();
}
28. Double-click the fourth Remove button and implement its event as
follows:
private void btnRemove4_Click(object sender, EventArgs e)
{
txtPartNumber4.Text = "";
txtPartName4.Text = "";
txtUnitPrice4.Text = "0.00";
txtQuantity4.Text = "0";
txtSubTotal4.Text = "0.00";
CalculateOrder();
}
30. Double-click the fifth Remove button and implement its event as follows:
private void btnRemove5_Click(object sender, EventArgs e)
{
txtPartNumber5.Text = "";
txtPartName5.Text = "";
txtUnitPrice5.Text = "0.00";
txtQuantity5.Text = "0";
txtSubTotal5.Text = "0.00";
CalculateOrder();
}
32. Double-click the sixth Remove button and implement its event as
follows:
private void btnRemove6_Click(object sender, EventArgs e)
{
txtPartNumber6.Text = "";
txtPartName6.Text = "";
txtUnitPrice6.Text = "0.00";
txtQuantity6.Text = "0";
txtSubTotal6.Text = "0.00";
34. Double-click the Close button and implement its Click event as follows:
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
Deleting Nodes
This method expects a reference to the node you want to delete. Another
solution you can use would consist of locating the node by its index. To do
this, you would call the TreeNodeCollection.RemoveAt() method. Its
syntax is:
public virtual void RemoveAt(int index);
When calling this method, pass the index of the node to be deleted. If you
are already at that node and you want to remove it, you can call the
TreeNode.Remove() method. Its syntax is:
One of the characteristics of a tree in the real world is that, if you cut a
branch, the branches attached to it and their leaves are cut too. In the same
way, if you call any of these Remove() or RemoveAt() methods to delete a
node, its children, if any, would be deleted too.
Hot Tracking
In order to select an item, the user must click it or navigate to it using the
keyboard. Alternatively, if you want the items to be underlined when the
mouse passes over them, set to true the TreeView.HotTracking Boolean
property. Its default value is false. Here is an example:
private void InitializeComponent()
{
Text = "Countries Statistics";
Size = new Size(242, 320);
tvwCountries.HotTracking = true;
Controls.Add(tvwCountries);
tvwCountries.ShowLines = false;
Controls.Add(tvwCountries);
}
Node Indentation
Indentation is the ability for a child node to be aligned to the right with
regards to its parent. The general distance from the left border of the parent
to the left border of the child is partially controlled by the TreeView.Indent
property which is an integer. If the default distance doesn't suit you, you can
change it by assigning a positive number to the control's Indent property.
tvwCountries.HotTracking = true;
tvwCountries.ShowLines = false;
tvwCountries.FullRowSelect = true;
This method only expands the node that calls it but if its children have their
own children, they are not expanded. To expand a node and its children that
have nodes, you can call its TreeNode.ExpandAll() method. Its syntax is:
public void ExpandAll();
To find out if a
node is expanded, check the value of its
TreeNode.IsExpanded property.
The user can do this for each node that is expanded. To programmatically
collapse all nodes of a tree view, call its TreeView.CollapseAll() method.
Its syntax is:
public void CollapseAll();
tvwCountries.CheckBoxes = true;
Controls.Add(tvwCountries);
}
When a check mark has been placed in a node's check box, the tree view
fires an AfterCheck event, which is handled by the TreeViewEventHandler
delegate. The AfterCheck event is carried by the TreeViewEventArgs class.
One of properties of this class is called Action, which specifies why or how
the event occurred. The Action property is in fact a value based on the
TreeViewAction enumerator. Its members are:
ByKeyboard: This indicates that the event was fired by pressing a key
ByMouse: This indicates that the event was fired based on an action on the
mouse
Collapse: This indicates that event was fired when the tree collapsed
Expand: This indicates that the event was fired when the tree expanded
Unknown: None of the above reasons caused the event, but the event was
fired
When creating a node, if you plan to display an icon next to it, you can use
the following constructor of the TreeNode class:
This constructor allows you to specify the text that the node will display, the
index of the picture it will use in the ImageList property, and the picture it
will display when it is selected.
If you are creating a node with its children and you want to specify its
pictures, use the following constructor of the TreeNode class:
public TreeNode(string text,
int imageIndex,
int selectedImageIndex,
TreeNode children[]);
Just as done previously, after defining the TreeNode object, you can add it to
the tree by passing it to the TreeNodeCollection.Add() method. In the
same way, you can create an array of TreeNode objects and pass it to the
TreeNodeCollection.AddRange() method.
1. To create an icon, on the main menu, click Project -> Add New Item...
11. Right-click the white area and click Delete Image Type
15. On the main menu, click Project -> Add New Item...
18. Right-click the white area and click Delete Image Type
22. On the main menu, click Project -> Add New Item...
25. Right-click the white area and click Delete Image Type
29. On the main menu, click Project -> Add New Item...
32. Right-click the white area and click Delete Image Type
36. On the main menu, click Project -> Add New Item...
39. Right-click the white area and click Delete Image Type
43. On the main menu, click Project -> Add New Item...
46. Right-click the white area and click Delete Image Type
50. On the main menu, click Project -> Add New Item...
53. Right-click the white area and click Delete Image Type
57. On the main menu, click Project -> Add New Item...
60. Right-click the white area and click Delete Image Type
64. On the main menu, click Project -> Add New Item...
67. Right-click the white area and click Delete Image Type
75. Locate the folder that contains the icons you created and display it in the
Look In combo box
77. In the same way, add the other pictures in the following order:
cpap2.ico, year1.ico, year2.ico, make1.ico, make2.ico, model1.ico,
model2.ico, category1.ico, and category1.ico
78. Click OK
80. In the Properties window, click ImageList, then click the arrow of its
combo box and select imgAutoParts
81. Access the Central.cs source file and change the code of the Load event
as follows:
private void Central_Load(object sender, EventArgs e)
{
TreeNode nodRoot = tvwAutoParts.Nodes.Add("College
Park Auto-Parts",
"College
Park Auto-Parts", 0, 1);
. . . No Change
if ((nodYear.Text ==
part.CarYear.ToString()) &&
(nodMake.Text == part.Make))
{
if (!lstModels.Contains(part.Model))
lstModels.Add(part.Model);
}
}
if ((nodYear.Text ==
part.CarYear.ToString()) &&
lstCategories.Add(part.Category);
}
}
tvwAutoParts.SelectedNode = nodRoot;
}
Introduction
To provide the selection of colors on Microsoft Windows applications, the
operating system provides a common dialog box appropriate for such tasks.
You can use the Color dialog box for various reasons such as letting the user
set or change a color of an object or specifying the background color of a
control or the color used to paint an object. When it displays, by default, the
dialog box appears as follows:
The expanded Color dialog box allows the user either to select one of the
preset colors or to custom create a color by specifying its red, green, and blue
values.
The user can change the color in four different areas. The top left section
displays a list of 48 predefined colors. If the desired color is not in that
section, the user can click and drag the mouse in the multi-colored palette.
The user can also drag the right bar that displays a range based on the color
dlg.ShowDialog();
}
When the user has finished using the Color dialog box and clicks OK, you can
find out what color was selected by retrieving the value of the
ColorDialog.Color property. Here is an example:
A bitmap is a series of colored adjacent pixels. Put another way, for a group
of pixels to be considered a bitmap, these pixels must constitute a group. A
bitmap is made by specifying the color of each pixel. This means that the
pictures we have used so far were simply made of pixels and each pixel held
an appropriate color.
Actually, when you have a bitmap, you can access any pixel of the picture
and then you can either specify its color or get its current color.
To allow you to specify the color of a pixel, the Bitmap class provides a
method named SetPixel and its syntax is:
public void SetPixel(int x, int y, Color color);
The x and y arguments represent the left and top values of the location of the
pixel. The 3rd argument specifies the new color that the pixel will hold. Here
is an example:
private void Form1_Paint(object sender, PaintEventArgs e)
{
Bitmap bgDrawingArea = new Bitmap(Width, Height);
e.Graphics.DrawImage(bgDrawingArea, 0, 0);
Graphics painter =
Graphics.FromHwnd(Handle);
painter.DrawImage(bgDrawingArea, 0, 0);
}
}
The x and y arguments represent the left and top values of the location of the
pixel whose color you want to get. This method returns the color of that
pixel.
Description
A spin button, also called an up-down control, is usually made to display a
numeric value that can then be increased or decreased when the user clicks
public Exercise()
{
InitializeComponent();
}
Controls.Add(spnNames);
}
}
If you want the buttons to be positioned on the left, set this property to Left.
The values of this property are managed through the LeftRightAlignment
enumeration of the UpDownBase parent class. Here is an example of aligning
the buttons to the left:
private void InitializeComponent()
{
nudCounter = new NumericUpDown();
nudCounter.Location = new Point(12, 12);
nudCounter.UpDownAlign = LeftRightAlignment.Left;
Controls.Add(nudCounter);
}
When the value of an spin button has been changed, the control fires a
ValueChanged() event. This event simply uses an EventArgs class as
argument. If the user decides to manually edit the value of the control by
typing a number in the text box part of the control, the spin button fires a
TextChanged() event.
Controls.Add(nudCounter);
}
If you use large numbers in the thousands, they may become difficult to read:
Controls.Add(nudCounter);
}
Controls.Add(nudCounter);
}
This causes the control to check the value used as the thousands separator in
the Control Panel of the computer that is using the application. The thousands
separator for US English is the comma ",". Here is an example:
Controls.Add(nudCounter);
}
Applications:
Pledge Distribution
Introduction to Labels
Description
A label is a control that serves as a guide to the user. It provides static text that the user
cannot change but can read to get information on a form. The programmer can also use
it to display simple information to the user. Most controls on the form are not explicit at
first glance and the user may not know what they are used for. Therefore, you can assign
a label to a control as a help to the user.
Creating a Label
To add a label to a container, click the Label button from the Toolbox and
click the object that would host it.
public Exercise()
{
InitializeComponent();
}
System.Windows.Forms.Application.Run(new Exercise());
return 0;
}
}
2. From the Common Control section of the Toolbox, click Label and click
the form
3. From the Common Control section of the Toolbox, click the Label again
and click the form
4. From the Common Control section of the Toolbox, click the Label again
and click the form
Characteristics of a Label
The Caption
The most important characteristic of a label control is the text it displays. That
text is also referred to as its caption and this is what the user would read.
The text of a label is its Text property and is its default. To set a label’s
caption, after adding the control to a container, click Text in the Properties
window and type the desired value. As we mentioned when studying controls
characteristics, at design time, the text you type in the Text field is
considered “as is”. If you want to create a more elaborate and formatted
string, you would have to do it programmatically. Here is an example:
public class Exercise : System.Windows.Forms.Form
{
Label lblMessage;
public Exercise()
{
InitializeComponent();
}
When it comes to its caption, one of the most valuable characteristics of the
text of a label is the variance of the font. When designing a caption. you can
change the default font to make it more attractive.
4. Click TextAlign and the arrow of its combo box to select Center
5. Click the + button of the Font field and change the characteristics as
follows:
Name: Tahoma
Size: 48
Bold: True
6. On the form, click the second label and, in the Properties window,
change its characteristics as follows:
Text: +
TextAlign: Center
(Name): lblOPeration
Font -> Name: Arial
Font -> Size: 50
Font -> Bold: True
7. On the form, click the third label and, in the Properties window, change
its characteristics as follows:
Text: 00
TextAlign: Center
(Name): lblOperand2
Font -> Name: Arial
Font -> Size: 50
Font -> Bold: True
public Exercise()
{
InitializeComponent();
}
1. Click an unoccupied area of the form and press Ctrl + A to select all
three labels
Content Alignment
After typing the caption of a label whose AutoSize property is set to False,
you can resize its allocated space to your liking. This is because a string
occupies a rectangular area. Here is an example:
Pictures on a Label
Other fancy characteristics you can apply to a label include its font and color.
For example, a label is primarily meant to display a string. To make it fancier,
you can display a (small) picture next to it. To do this, at design time, use the
Image field of the Properties window to select a picture. You can also specify
the picture at run time by assigning an Image value to the Label.Image
property. After adding a picture that would accompany the label, you can
specify what position the picture would hold with regards to the label. To do
this, select the desired position of the ImageAlign field in the Properties
window.
Instead of using a picture from the Image property, you can create a list of
images using an ImageList control and assign it to the label. In fact, the
advantage of an ImageList is that, unlike the Image property, it allows you
to use more than one picture.
A Label's Mnemonic
A label provides another property called UseMnemonic. This property is
valuable only when the label accompanies another control.
Name:
Tahoma
Label 00 lblOperand1 Center Size: 48 ForeColor: Blue
Bold:
True
Name:
Arial
Label + Center Size: 50 ForeColor: Maroon
Bold:
True
Name:
Tahoma
Label 00 lblOperand2 Center Size: 48 ForeColor: Blue
Bold:
True
Name:
Arial
Label = Center Size: 50 ForeColor: Green
Bold:
True
Name:
BorderStyle:
Tahoma,
New Fixed3D
Label lblNewOperation Center Size: 28
Operation ForeColor: White
Bold:
BackColor:Maroon
True
Name:
Tahoma,
BorderStyle:
Label Quit lblQuit Center Size: 28
FixedSingle
Bold:
True
2. To be able to use the Visual Basic library, in the Solution Explorer, right-
click References -> Add References...
4. Click OK and OK
operand1 = rnd.Next(99);
operand2 = rnd.Next(99);
int result = operand1 + operand2;
lblOperand1.Text = operand1.ToString();
lblOperand2.Text = operand2.ToString();
lblResult.Text = "0";
string strPrompt = lblOperand1.Text + " + " +
lblOperand2.Text + " =";
try
{
answer =
int.Parse(Microsoft.VisualBasic.Interaction.InputBox(
strPrompt,
"Elementary Addition",
"000",
100,
100));
lblResult.Text = answer.ToString();
if (answer == result)
MessageBox.Show("WOW - Good Answer");
else
MessageBox.Show("PSSST - Wrong Answer");
}
catch (FormatException)
{
}
}
9. Click the Close button to close the form and return to your programming
environment
Introduction
When it comes to a restaurant, a menu is a list of food items that the
business offers to its customers. For a computer application, a menu is a list
of actions that can be performed on that program. To be aware of these
actions, the list must be presented to the user upon request. On a typical
DOS application, a menu is presented with numerical or character options
that the user can select from. An example would be:
The user would then enter the number (or character) that corresponds to the
desired option and continue using the program. For a graphical application, a
menu is presented as a list of words and, using a mouse or a keyboard, the
user can select the desired item from the menu.
To use a menu, the user first clicks one of the words that displays on top.
When clicked, the menu expands and displays a list of items that belong to
that category. Here is an example:
To graphically create a main menu, in the Menus & Toolbars section of the
Toolbox, you can click the MenuStrip button and click the form that will
use the menu. After clicking the form, an empty menu is initiated:
Like every control, the main menu must have a name. After adding the menu
strip to a form, you can accept the suggested name or, in the Properties
window, click (Name) and type the desired name. You can then use the menu
placeholder to add the necessary menu item(s)..
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
mnuMain = new MenuStrip();
Controls.Add(mnuMain);
}
}
Menu Categories
In our introduction, we saw that a main menu was made of categories
represented in the top section. After adding a MenuStrip, you can start
creating the desired menu categories. To graphically create a menu category:
In the menu strip, you can click the Type Here line and type the desired
string
In the menu strip, you can click Type Here. Then, in the Properties
window, click the Text field and type the desired string
To create the next menu category, you can click Type Here on the right side of
the previous menu category. In the same way, you can continue creating the
desired menu categories.
Here is an example:
Under the form, you can click the menu strip object and, in the
Properties window, you can click the ellipsis button of the Items field
Under the form, you can right-click the menu strip and click Edit Items...
To create a menu category, in the Select Item And Add To List Below combo
box, select MenuItem and click the Add button. In the right list, configure the
menu item. At a minimum, you should specify its caption in the Text field.
Like every control, each menu item has a name. To make sure you can easily
recognize it in your code, when creating a menu item, you should give it a
name unless you are contempt with the suggested one. After creating the
menu categories, you can click OK and keep the dialog box opened for more
options.
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
mnuMain = new MenuStrip();
mnuFile = new ToolStripMenuItem();
Controls.Add(mnuMain);
}
}
To specify the caption that will be displayed on a menu category, you can use
the following constructor of the ToolStripMenuItem class:
public ToolStripMenuItem(string text);
Here is an example:
public class Exercise : System.Windows.Forms.Form
{
MenuStrip mnuMain;
ToolStripMenuItem mnuFile;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
mnuMain = new MenuStrip();
mnuFile = new ToolStripMenuItem("File");
Controls.Add(mnuMain);
}
}
If you had instantiated the class using its default constructor, to specify its
caption, the ToolStripMenuItem class is equipped with the Text property.
Therefore, assign a string to this property. Here is an example:
public class Exercise : System.Windows.Forms.Form
{
MenuStrip mnuMain;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
mnuMain = new MenuStrip();
mnuFile = new ToolStripMenuItem("File");
mnuEdit = new ToolStripMenuItem();
mnuEdit.Text = "Edit";
Controls.Add(mnuMain);
}
}
In the same way, you can create as many menu categories as you judge
necessary for your application.
Under a category, click Type Here and type the desired caption.
In the same way, to create the next menu item, under the same category, click
the next Type Here and type the desired caption or change the Text value in
the Properties window.
Right-click the menu category and click Edit Drop Down Items...
Click the menu category. Then, in the Properties window, click the
ellipsis button of the DropDownItems field
To create a menu item, in the Select Item And Add To List Below combo box,
select MenuItem and click Add. On the right side, configure the menu item as
you see fit. At a minimum, you should specify its caption in the Text field.
Both the menu category and the menu item are created using the
ToolStripMenuItem class. Here are examples:
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
mnuMain = new MenuStrip();
mnuFile = new ToolStripMenuItem("File");
mnuNew = new ToolStripMenuItem("New");
mnuExit = new ToolStripMenuItem("Exit");
mnuEdit = new ToolStripMenuItem("Edit");
mnuCopy = new ToolStripMenuItem("Copy");
Controls.Add(mnuMain);
}
}
To specify that a menu item will be part of a menu category, call the Add()
method of the ToolStripItemCollection class. This method is overloaded
with various versions. One of the versions uses the following syntax:
public int Add(ToolStripItem value);
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
mnuMain = new MenuStrip();
mnuEdit = new ToolStripMenuItem("Edit");
mnuCopy = new ToolStripMenuItem("Copy");
mnuEdit.DropDownItems.Add(mnuCopy);
Controls.Add(mnuMain);
}
}
This method takes as argument the text that the menu item would display
and it returns the ToolStripItem item that was created. Here is an example:
public class Exercise : System.Windows.Forms.Form
{
MenuStrip mnuMain;
ToolStripMenuItem mnuEdit;
ToolStripMenuItem mnuCopy;
ToolStripMenuItem mnuPaste;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
mnuMain = new MenuStrip();
mnuEdit = new ToolStripMenuItem("Edit");
mnuCopy = new ToolStripMenuItem("Copy");
mnuEdit.DropDownItems.Add(mnuCopy);
mnuPaste =
(ToolStripMenuItem)mnuEdit.DropDownItems.Add("Paste");
Controls.Add(mnuMain);
}
}
Instead of adding one menu item at a time, you can create an array of menu
items and then add it to a category in one row. To support this, the
ToolStripItemCollection class implements the AddRange() method. This
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
mnuMain = new MenuStrip();
Controls.Add(mnuMain);
}
After creating the menu categories, you can add them to the main menu. To
support this, the ToolStrip class is equipped with a property named Items
and it makes this property available to the MenuStrip class. The Items
property is of type ToolStripItemCollection. This class implements the
IList, the ICollection, and the IEnumerable interfaces. Therefore, to add
a menu category to a MenuStrip object, you can call the Add() method of
the ToolStripItemCollection class. This method is overloaded with
various versions and one of them uses the following version:
public int Add(ToolStripItem value);
You can call this version and pass it a ToolStripItem-type of object, such as
a ToolStripMenuItem value. Here is an example:
public class Exercise : System.Windows.Forms.Form
{
MenuStrip mnuMain;
ToolStripMenuItem mnuFile;
ToolStripMenuItem mnuNew;
ToolStripMenuItem mnuOpen;
ToolStripMenuItem mnuExit;
ToolStripMenuItem mnuEdit;
ToolStripMenuItem mnuCopy;
ToolStripMenuItem mnuPaste;
ToolStripMenuItem mnuHelp;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
mnuMain = new MenuStrip();
mnuMain.Items.Add(mnuFile);
Controls.Add(mnuMain);
}
}
In the same way, you can add the other items. Alternatively, you can create
an array of menu categories and add them in a row. To support this, the
ToolStripItemCollection is equipped with the AddRange() method that is
overloaded with two versions. One of the versions uses the following syntax:
public void AddRange(array<ToolStripItem>toolStripItems);
ToolStripMenuItem mnuView;
ToolStripMenuItem mnuHelp;
public Exercise()
{
InitializeComponent();
}
void InitializeComponent()
{
mnuMain = new MenuStrip();
mnuMain.Items.Add(mnuFile);
mnuMain.Items.AddRange(mnuAccessories);
Controls.Add(mnuMain);
}
}
3. From the Menus & Toolbars section of the Toolbox, click the MenuStrip
button and click the form
4. While the menu strip is still selected, in the Properties window, click
(Name), type mnuMain and press Enter
5. On the form, click Type Here, type File and press Enter
7. On the form, click File and under it, click the Type Here box
10. On the form, click File and, under New Property, click the Type Here box
MenuStrip
ListView lvwProperties
colPropertyNumber Prop # 50
colCity City 80
14. On the main menu, click Project -> Add Windows Form...
Control
Label Property #:
Property
Label
Type:
Label Address:
Label City:
Label State:
Modifiers: Public
Items:
DC
ComboBox cbxStates MD
PA
VA
WV
Label Bedrooms:
DialogResult:
Button Cancel btnCancel
Cancel
Form
FormBorderStyle: FixedDialog
StartPosition: CenterScreen
AcceptButton: btnOK
CancelButton: btnCancel
MaximizeBox: False
MinimizeBox: False
ShowInTaskBar: False
dlgProperty.txtPropertyNumber.Text = propNumber;
dlgProperty.Text = "Altair Realtors - New Property";
if (dlgProperty.ShowDialog() == DialogResult.OK)
{
string strPropertyType =
dlgProperty.cbxPropertyTypes.Text;
string strAddress = dlgProperty.txtAddress.Text;
string strCity = dlgProperty.txtCity.Text;
string strState = dlgProperty.cbxStates.Text;
string strZIPCde = dlgProperty.txtZIPCode.Text;
string strBedrooms = dlgProperty.txtBedrooms.Text;
string strBathrooms = dlgProperty.txtBathrooms.Text;
string strMarketValue = dlgProperty.txtMarketValue.Text;
ListViewItem lviProperty =
new
ListViewItem(dlgProperty.txtPropertyNumber.Text);
lviProperty.SubItems.Add(strPropertyType);
lviProperty.SubItems.Add(strAddress);
lviProperty.SubItems.Add(strCity);
lviProperty.SubItems.Add(strState);
lviProperty.SubItems.Add(strZIPCde);
lviProperty.SubItems.Add(strBedrooms);
lviProperty.SubItems.Add(strBathrooms);
lviProperty.SubItems.Add(strMarketValue);
lvwProperties.Items.Add(lviProperty);
}
}
Introduction
The panel is a rectangular object that can provide various valuable services
for application design. A panel allows you to design good-looking forms by
adjusting colors and other properties. A panel can also be used as control
delimiter for objects that behave as a group. An example would be a set of
radio buttons.
Panels are not transparent. Therefore, their color can be changed to control
their background display. A panel is a complete control with properties,
methods, and events.
Creating a Panel
To add a panel to a container, you can click the Panel button from the
Toolbox and click the desired location on the container. Unlike the form,
during design, a panel must primarily be positioned on another container
which would be a form or another panel.
public Exercise()
{
InitializeComponent();
}
Width = 320;
Height = 210;
Location = System.Drawing.Point(140, 100);
StartPosition = FormStartPosition.CenterScreen;
return 0;
}
}
Characteristics of a Panel
By default, a panel object is drawn without borders. If you want to add
borders to it, use the BorderStyle property. It provides three values that you
can set in the Properties window: None, FixedSingle, and Fixed3D and their
effects are as follows:
Design
Run
To programmatically specify the border style, assign the desired value to the
Panel.BorderStyle property. Here is an example:
Controls.Add(pnlContainer);
}
A property that is highly used on panels (and forms) is the Color. If you
change the BackColor property, the new color would cover the face of the
panel.
Description
A radio button, sometimes called an option button, is a circular control that
comes in a group with other radio buttons. Each radio button is made of a
small empty circle O. From the group, when the user clicks one of them, the
radio button that was clicked becomes filled with a big dot . When one of the
radio buttons in the group is selected and displays its dot, the others display
empty circles. To guide the user as to what the radio buttons mean, each is
accompanied by a label.
Here is an example of a form with three radio buttons: Small, Medium, and
Large
public Exercise()
{
InitializeComponent();
}
grpPizzaSize.Controls.Add(radSmall);
grpPizzaSize.Controls.Add(radMedium);
grpPizzaSize.Controls.Add(radLarge);
Controls.Add(grpPizzaSize);
}
}
}
grpPizzaSize.Controls.Add(radSmall);
grpPizzaSize.Controls.Add(radMedium);
grpPizzaSize.Controls.Add(radLarge);
Controls.Add(grpPizzaSize);
}
}
At design time, to select a radio button, in the Properties window, set its
Checked property to True. At run time, to programmatically select a radio
button, assign a true value to its Checked property. To find out whether a
particular radio button is selected, get the value of its Checked property. You
can also programmatically check a radio button. Here is an example:
private void Form1_Load(object sender, System.EventArgs e)
{
radioButton2.Checked = true;
}
Controls.Add(grpPizzaSize);
}
Besides the alignment of the check box, you can also control the alignment of
the text with regards to the bounding rectangle of the control. This
characteristic is controlled by the TextAlign property of the RadioButton
class. The TextAlign property also is of type ContentAlignment.
grpPizzaSize.Controls.Add(radSmall);
grpPizzaSize.Controls.Add(radMedium);
grpPizzaSize.Controls.Add(radLarge);
Controls.Add(grpPizzaSize);
}
As you can see, you can apply the Appearance property to a radio button that
does not have a caption. You can also use a caption. If you do, make sure
you align the caption to make is good to see. Here are examples:
private void InitializeComponent()
{
grpPizzaSize = new GroupBox();
grpPizzaSize.Text = "Pizza Size";
grpPizzaSize.Size = new Size(150, 120);
grpPizzaSize.Location = new Point(20, 10);
grpPizzaSize.Controls.Add(radSmall);
grpPizzaSize.Controls.Add(radMedium);
grpPizzaSize.Controls.Add(radLarge);
Controls.Add(grpPizzaSize);
}
If you configure your application and give the user the ability to change the
appearance of the radio button from a round circle to a rectangular object
and vice-versa, and if the user decides to change this appearance, when this
is done, the control whose appearance was changed fires an
AppearanceChanged event. The AppearanceChanged event is of type
EventArgs, meaning that it does not carry any significant information other
than to let you know that the appearance of the button was changed.
Applications:
Compound Interest
Description
As your application becomes crowded with various controls, you may find its
form running out of space. To solve such a problem, you can create many
controls on a form or container and display some of them only in response to
some action from the user. The alternative is to group controls in various
containers and specify when the controls hosted by a particular container
must be displayed. This is the idea behind the concept of property pages. A
property page is a control container that appears as a form or a frame.
In most other cases, a property page appears in a group with other pages. It
functions like a group of pieces of paper placed on top of each other. Each
piece is represented by a tab that allows the user to identify it:
The pages are grouped and hosted by an object called a property sheet. Like
a form, the property pages of a property sheet are simply used to carry or
hold other controls. The major idea of using a property sheet is its ability to
have many controls available in a relatively smaller area.
public Exercise()
{
InitializeComponent();
}
Controls.Add(tclPropertySheet);
}
}
If you want the property sheet to occupy the whole form or to occupy a
section of it, you can specify this using the Dock property.
Introduction
As mentioned previously, a tab control is made of tabs. These are the actual
objects that make up a tab control. A tab control can have one or more of
them. If you create only a tab control in your application, it is useless and
does not play its intended role. To make it useful, you must add property
pages to it.
If you create a tab control at design time by taking it from the Toolbox and
adding it to a form, the tab control gets automatically equipped with two
tabs. Here is an example:
If the tab control does not yet have any tabs, you can right-click its body
and click Add Tab:
If the tab control already has one or more tabs, right-click the right side
to its tabs and click Add Tab
If the tab control already has at least one tab, first select the tab control
(in the next sections, we will learn how to select the tab control). If the
control does not yet have tabs, click its body to select it.
If you create the tab pages at design time, like all other controls, the names
of tab pages are cumulative. As you add them, the first would be named
tabPage1, the second would be named tabPage2, etc. If you plan to
programmatically refer to the tab pages, you should give each a more
meaningful name. As done with any other control, to set the name of a
property page, after selecting it, in the Properties window, change the value
of the (Name) field.
public Exercise()
{
InitializeComponent();
}
Controls.Add(tclPropertySheet);
}
}
public Exercise()
{
InitializeComponent();
}
Controls.Add(tclPropertySheet);
}
}
2. On the form, right-click the right side of tabPage2 and click Add Page
You can right-click the TabControl control and click Remove Tab
You can select the tab control, click the arrow button on its top-right
section and click Remove Tab
While the undesired tab page is selected on the tab control, you can
press Delete
While the undesired tab page is selected on the tab control, in the lower
section of the Properties window, you can click the Remove Tab link
You can right-click the body of the undesired page and click Delete
To select the TabControl control itself, you have three main options:
In the top combo box on top of the Properties window, select the name
of the tab control
Click an unoccupied area on the right side of the most right tab
At run time, neither the user nor you would really need to select a tab
control. On the other hand, with code, you can refer to the tab control using
its name.
1. On the form, click on the right side of tabPage3 to select the tab control.
In the Properties window, click (Name) and type tclAlgebra
To select a tab page on the form, first click its tab, then click its body
In the top combo box of the Properties window, select the name of the
desired property page
As described in our introduction, to select a property page, the user can click
its tab. To programmatically select a tab page, you have various options.
We mentioned already that the tab pages are added cumulatively. The
application keeps track of their position. To keep track of the positions of
the tab pages, the TabControl class is equipped with a property named
SelectedIndex. Based on this, to select a tab page using its position, assign
the desired index to this property. Here is an example:
private void button1_Click(object sender, EventArgs e)
{
tabControl1.SelectedIndex = 1;
}
You can also call the TabControl.SelectTab() method. In this case, pass
the tab index to the method.
An alternative is to select a tab page using its object name. To support this,
the TabControl class is equipped with the SelectedTab property. Using it,
to select a tab page, assign its name to the SelectedTab property. Here is
an example:
private void button1_Click(object sender, EventArgs e)
{
tabControl1.SelectedTab = tabPage3;
}
You can also call the TabControl.SelectTab() method. In this case, pass
the name of the tab to the method.
Introduction
Like any other visual window, the tab control uses such properties as the the
Location (Right and Top values), the Size (Width and Height values), the
tab stop (TabStop), the tab index (TabIndex), the cursor (Cursor), etc.
After adding the TabControl control to your form and after adding one or
more tab pages, the property pages are created where the TabControl
control is positioned and their dimensions are used by the tab control. This
means that, if you want a different position, a smaller or larger property
sheet, you must modify the dimensions of the TabControl control and not
those of the tab pages, even though each tab page has a Location property
and dimensions (the Size property).
To programmatically find out the location and size of a property sheet, the
TabControl class is equipped with a property named DisplayRectangle
that produces a Rectangle value. Here is an example of using it:
private void Exercise_Load(object sender, EventArgs e)
{
Rectangle rctLocationSize =
tabControl1.DisplayRectangle;
textBox1.Text = rctLocationSize.Left.ToString();
textBox2.Text = rctLocationSize.Top.ToString();
textBox3.Text = rctLocationSize.Width.ToString();
textBox4.Text = rctLocationSize.Height.ToString();
}
To display a custom title for a property page, on the form, select the tab
control:
Click the tab of the desired page. In the Properties window, change the
value of the Text property
In the Properties window, click the ellipsis button of the TagePages field
to open the TabPages Collection Editor. In the Members list, click the
name of the tab page. In the right list, click Text and change the string
using System;
using System.Drawing;
using System.Windows.Forms;
public Exercise()
{
InitializeComponent();
}
Controls.Add(tclPropertySheet);
}
}
return 0;
}
}
Controls.Add(tclPropertySheet);
}
During design, to specify the amount of padding, select the tab control on the
form. In the Properties window, click the + button of the Padding field, type
A Picture on a Tab
Besides, or instead of, the caption, you can display an icon on the tab of one
or more or some selected tabs of your control. To start, you should create an
image list and add some images or icons to it. After creating the image list, to
associate it with the tab control, on the form, select the control. In the
Properties window, click the arrow of the ImageList field and select the image
list.
To specify the image list with code, first create the image list, visually or
programmatically. To associate the image list with the tab control, assign the
name of the image list to the ImageList property of the tab control. Here is an
example:
On the form, select the desired tab page. In the Properties window, click
ImageIndex and click the arrow of its combo box to select the index of
the picture from the image list
On the forms, select the tab control. In the Properties window, click the
ellipsis button of the TagePages field to open the TabPages Collection
Editor. In the Members list, click the name of the tab page. In the right
list, click ImageIndex and click the arrow of its combo box to select the
index of the picture
Before programmatically using the images on a tab control, you must first
create an ImageList object and then assign it to the tab control. Here is an
example:
public class Exercise : System.Windows.Forms.Form
{
TabControl tclPropertySheet;
public Exercise()
{
InitializeComponent();
}
lstImages.Images.Add(Image.FromFile(@"E:\Programs\image1.jpg"));
lstImages.Images.Add(Image.FromFile(@"E:\Programs\Image2.jpg"));
lstImages.Images.Add(Image.FromFile(@"E:\Programs\Image3.jpg"));
tclPropertySheet.ImageList = lstImages;
}
}
public Exercise()
{
InitializeComponent();
}
lstImages.Images.Add(Image.FromFile(@"E:\Programs\image1.jpg"));
lstImages.Images.Add(Image.FromFile(@"E:\Programs\Image2.jpg"));
lstImages.Images.Add(Image.FromFile(@"E:\Programs\Image3.jpg"));
tclPropertySheet.ImageList = lstImages;
Controls.Add(tclPropertySheet);
}
}
To control the size mode at design time, on the form, select the tab control.
In the Properties window, click SizeMode and select the desired option:
Fixed: The designer would find out what tab has the longest caption. It
would then use that length as the common width of all the other tabs:
That length would be used as the common length to all the tabs on all rows:
public Exercise()
{
InitializeComponent();
}
Controls.Add(tclPropertySheet);
}
}
public Exercise()
{
InitializeComponent();
}
Controls.Add(tclPropertySheet);
}
}
Introduction
As opposed to the time that controls your computer, a timer is partly but
greatly under your control. Users do not see nor do they use a timer as a
control. As a programmer, you decide if, why, when, and how to use this
control.
To support timers, the .NET Framework provides the Timer control from the
Toolbox and it is implemented through the Timer class. To add it to your
application at design time, on the Toolbox, click Timer and click the form.
namespace ScreenSaver1
{
public partial class Form1 : Form
{
static int MoveCounter = 0;
public Form1()
{
InitializeComponent();
}
if (MoveCounter == 20)
Close();
MoveCounter++;
}
}
}
5. Display the form again and, in the Events section of the Properties
window, double-click KeyDown
7. Execute the application to test it (to close the form, you will just move
the mouse or press Esc)
Characteristics of a Timer
A timer is an object used to count lapses of time and send a message when it
has finished counting. Each count is called a tick. When a tick occurs, the
control fires a Tick event. This Tick event is of type EventArgs, meaning
that it doesn't provide more information than to let you know that a lapse has
occurred.
In order for a timer to count, you must tell it when it should start counting. In
some applications, you may want the control to work full-time while in some
other applications, you may want the control to work only in response to an
intermediate event. The ability to stop and start a Timer control can be set
using the Enabled Boolean property. When, or as soon as, this property is set
If, when, or as soon as, the Enabled property is set to false, the control stops
and resets its counter to 0. You can also stop the timer by calling the
Timer.Stop() method. Its syntax is:
1. From the Components section of the Toolbox, click the Timer control
and click the form
2. In the Properties window, set the Enabled property to True and set the
Interval to 200
4. In the top section of the file, under the other using System lines, type
using System.Drawing.Drawing2D;
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.Cross,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DarkDownwardDiagonal,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DarkHorizontal,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DarkUpwardDiagonal,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DarkVertical,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DashedDownwardDiagonal,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DashedHorizontal,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DashedUpwardDiagonal,
curColor[rndNumber.Next(curColor.Length)],
curColor[rndNumber.Next(curColor.Length)]),
new HatchBrush(HatchStyle.DashedVertical,
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row2[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row2[i]);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row3[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row3[i]);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row4[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row4[i]);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row5[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row5[i]);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row6[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row6[i]);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row7[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row7[i]);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row8[i]);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row8[i]);
}
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row1a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row1a);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row3a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row3a);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row4a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row4a);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row5a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row5a);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row6a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row6a);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row7a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row7a);
graph.FillRectangle(curBrush[rndNumber.Next(curBrush.Length)],
row8a);
graph.DrawRectangle(new
Pen(curBrush[rndNumber.Next(curBrush.Length)]), row8a);
}
Introduction
The form is the most fundamental object used in an application. By itself, a
form does nothing. Its main role is to host other objects that the user uses to
interact with the computer:
Form Creation
There are various ways you can get a form to your application:
In Lesson 2, we saw that a was based on the Form class that is defined in the
System.Windows.Forms namespace created in the
System.Windows.Forms.dll assembly. Therefore, if you start an application
from scratch and you want to use a form in it, you can include the
System.Windows.Forms.dll library to your application. To refer to a form,
you can include the System.Windows.Forms namespace in your application.
public Exercise()
To change the name of a form, in the Solution Explorer, right-click the name
of the form and type a new name with the .cs extension.
On the left side of the title bar, the form displays a small picture called an icon or the
system icon. Microsoft Visual Studio 2005 provides a default icon for all forms. If you
want to use a different icon, while the form is selected, in the Properties window, you can
click the Icon field and then click its ellipsis button . This would launch the Open dialog
box from where you can locate an icon and open it.
Whether you had assigned an icon to the for or not, you can control whether
the form should display an icon. To support this, the Form class is equipped
with a Boolean property named ShowIcon. If you set this property to false,
the icon would not appear in the title bar of the form. If the Form.ShowIcon
property is set to true, which is its default value, the form's title bar would
display an icon.
5. To continue with the icon design, on the main menu, click Image ->
New Image Type...
6. On the New Icon Image Type, click 16x16, 256 colors line:
7. Click OK
8. Design it as follows:
9. To save the icon, on the Standard toolbar, click the Save All button
10. Close the window tab that contains the icon designed
12. On the Open dialog box, locate the folder in which you had saved the
project and select the cpas icon
1. While the form is selected, in the Properties window, click Text and type
College Park Auto Shop - Customer Repair Order
2. Press Enter
ControlBox = true;
MinimizeBox = true;
MaximizeBox = false;
}
1. To make sure that the user cannot maximize the form, on the Properties
window, click the MaximizeBox field to reveal its combo box and select
False
Like every control on an application, a form has a parent: the desktop. The
desktop is the wide area of the monitor easily seen when the computer
comes up. Everything on the computer is located with regards to this main
parent. In the same way, a form uses the desktop to determine its "physical"
location. Based on this, when an application is launched, its form occupies an
area of the desktop. To locate its children, the desktop uses a Cartesian
coordinate system whose origin is located on the top-left corner of the
screen:
The distance from the the desktop’s left border to the form’s left border is
represented by the form's Left property. The distance from the desktop’s top
border to the form’s top border is specified by the Top property. Therefore,
If you want to programmatically set the location of the form, you can assign a
value to its Left and/or its Top properties. Here is an example:
public class Exercise : System.Windows.Forms.Form
{
public Exercise()
{
InitializeComponent();
}
Left = 228;
Top = 146;
}
Value Result
CenterScreen The form will be positioned in the middle of the desktop even if
this form is part of an application that is made of various forms.
The form will use the values of the X, Y, Left, and/or Top
Manual
properties of the Location
WindowsDefaultLocation
The operating system will specify the form's position using a
value known in Win32 as CW_USEDEFAULT
Based on this, to set the default relative location of a form when it comes up,
change the value of its StartPosition combo box in the Properties window.
To specify this characteristic when programmatically creating a form or to
change this property at run time, call the FormStartPosition enumeration
to select the desired value and assign it to the StartPosition property of
the form. Here is an example:
using System;
using System.Windows.Forms;
StartPosition =
FormStartPosition.WindowsDefaultLocation;
}
}
WindowState = FormWindowState.Maximized;
}
}
If you want to check the state of a window before taking action, simply use a
conditional statement to compare its WindowState property with the Normal,
the Maximized, or the Minimized values.
If you create an application made of various forms, you may not want to
show all of its forms on the taskbar. Usually the first or main form would be
enough. To prevent a button for a form to display on the taskbar, set its
ShowInTaskbar property to False.
Here is an example:
private void InitializeComponent()
{
Icon = new Icon(@"C:\Programs\RedBook.ico");
Text = "Windows Fundmentals - Programming";
ShowInTaskbar = false;
}
Unless you have a good reason, and it is hard to see what that reason
could be, you should not set the ShowInTaksbar property of the first or
main form of an application to false.
When you create a form, it assumes a default size. To set or change the size
of a form, at design time, first click it to select it. Then, position the mouse on
its right, bottom, or bottom-right handles. This changes the mouse cursor in
one of three shapes:
If you don't want to be able to resize a form and you want to prevent this by
accident, at design time, set the form's Locked property to True. If you do
this:
Besides resizing the form by dragging one of its handles, to change the size
of a form, select it and, in the Properties window, click the + button of the
Width = 425;
Height = 308;
}
Alternatively, you can assign a Size value to the Size property of the form.
Here is an example:
private void InitializeComponent()
{
Icon = new Icon(@"C:\Programs\RedBook.ico");
Text = "Windows Fundmentals - Programming";
If you want the operating system to specify the size of the form, set its
StartPosition property to WindowsDefaultBounds. In this case, a value
called CW_USEDEFAULT would be assigned to both the Width and the Height
properties.
1. Position the mouse to the small square on the right border of the form
2. Click and drag in the right direction to make sure the caption in the title
bar can appear completely
If you set both the MinimizeBox and the MaximizeBox properties to False,
we saw that the form would have only the system Close button, but the form
can still be resized. If you want the form to display only the system Close
button and to prevent the user from resizing it, set its FormBorderStyle
property to FixedDialog. Here is an example:
private void InitializeComponent()
{
Icon = new Icon(@"C:\Programs\RedBook.ico");
Text = "Windows Fundmentals - Programming";
FormBorderStyle = FormBorderStyle.Fixed3D;
}
Introduction
When a form has been created, you can add Windows controls to it. These
controls can be positioned only in a specific area, the body of the form. The
body spans from the left border of the form, excluding the border itself, to
the right border of the form, excluding the border. It also spans from the top
side, just under the title bar, to the bottom border, excluding the bottom
border, of the form. The area that the form makes available to the controls
added to it is called the client area:
To know the amount of space that a form is making available to its child
control, you can access the form's ClientSize property.
BackColor = Color.BurlyWood;
}
}
Introduction
If you prefer to cover the client area with a picture, use the
BackgroundImage property instead. To specify the background picture at
design time, in the Properties window, click BackgroundImage and click its
ellipsis button. This would open the Select Resource dialog box. To locate a
picture, click one of the Import buttons, select the picture from the chosen
folder and click Open. The picture would be imported in the dialog box:
BackgroundImage =
Image.FromFile(@"E:\Programs\beach.jpg");
}
BackgroundImage =
Image.FromFile(@"E:\Programs\FireWall.png");
BackgroundImageLayout = ImageLayout.None;
}
Center: The picture will display once, in the middle-center of the client
area of the form. Here is an example:
private void InitializeComponent()
{
Icon = new Icon(@"C:\Programs\RedBook.ico");
Text = "Fire Wall";
MaximizeBox = false;
BackgroundImage =
Image.FromFile(@"E:\Programs\FireWall.png");
BackgroundImageLayout = ImageLayout.Center;
}
BackgroundImage =
Image.FromFile(@"E:\Programs\FireWall.png");
BackgroundImageLayout = ImageLayout.Tile;
}
BackgroundImage =
Image.FromFile(@"E:\Programs\FireWall.png");
BackgroundImageLayout = ImageLayout.Stretch;
}
BackgroundImage =
Image.FromFile(@"E:\Programs\FireWall.png");
BackgroundImageLayout = ImageLayout.Zoom;
}
If the form's width is lower than its height, then the picture will be
positioned in the middle of the form:
Form Creation
The form is implemented by the Form class from the System.Windows.Forms
namespace. The Form class is equipped with a constructor that allows you to
dynamically create it. After a form has been created, it must be loaded to
display on the screen. When a form is being loaded, it fires the Load() event
which is of type EventArgs. This event is fired when a form is about to be
displayed for the first time. Therefore, it can be used to perform last minute
initializations.
In order to use a form other than the one that is active, you must activate it.
To do this, you can call the Activate() method. Its syntax is:
public void Activate();
Form Deactivation
If there is more than one form or application on the screen, only one can be
in front of the others and be able to receive input from the others. If a form is
not active and you want to bring it to the top, you must activate it, which
fires the Activated() event. When a form is being activated, the one that
was on top would become deactivated. The form that was on top, as it looses
focus, would fire the Deactivate() event which is an EventArgs type.
Form Closure
When the user has finished using a form, he or she must be able to close it.
Closing a form is made possible by a simple call to the Close() method. Its
syntax is:
public void Close();
When this method is called, the process of closing a form starts. At this time,
the Closing() event is fired. The Closing() event is implemented by the
CancelEventArgs class through the CancelEventHandler delegate. The
CancelEventArgs class is equipped with only the Cancel property. The
CancelEventArgs.Cancel property allows you to cancel or to continue with
the closing of the form. If you set the CancelEventArgs.Cancel property to
true, the event will be ignored as if it were not fired. If you want the event
to continue closing the form, you can set this property to false. This event
occurs before the form is actually closed, giving you time to let the form be
closed, prevent the form from being closed, or take any other necessary
action.
Dialog Boxes
Description
A dialog box is a form defined with particular properties. Like a form, a dialog
box is referred to as a container. Like a form, a dialog box is mostly used to
host child controls, insuring the role of dialog between the user and the
machine. Here is an example of a dialog box:
It is usually modal, in which case the user is not allowed to continue any
other operation on the same application until the dialog box is
dismissed
2. From the Common Controls section of the Toolbox, click ListView and
click the form
3. While the list view is still selected, in the Properties window, change the
following characteristics
(Name): lvwProperties
View: Details
4. Still in the Properties window, click Columns and click its ellipsis button
7. Click Add.
In the right list, click Text and type Property Type
8. Click Add.
In the right list, click Text and type Bedrooms
9. Click Add.
In the right list, click Text and type Bathrooms
11. Click OK
13. To add another form to the project, on the main menu, click Project ->
Add Windows Form...
Width = 320;
Height = 150;
Location = new Point(140, 100);
StartPosition = FormStartPosition.CenterScreen;
}
}
Here is an example:
private void InitializeComponent()
{
Width = 320;
Height = 150;
Location = new Point(140, 100);
StartPosition = FormStartPosition.CenterScreen;
FormBorderStyle = FormBorderStyle.FixedDialog;
}
FormBorderStyle = FormBorderStyle.FixedDialog;
MinimizeBox = false;
MaximizeBox = false;
}
TextBox txtPropertyType
Label Bedrooms:
TextBox txtBedrooms
Button OK btnOK
Label Bathrooms:
TextBox txtBatrooms
TextBox txtMonthlyRent
Accepting an Action
Often the user will be presented with various options on a dialog box and may
be asked to make a decision on the available controls. Most of the time, if you
are creating such a dialog box, besides the OK button, it should also have a
Cancel button. The OK button should be the default so that if the user
presses Enter, the dialog box would be closed as if the user had clicked OK.
Clicking OK or pressing Enter would indicate that, if the user had made
changes on the controls of the dialog box, those changes would be
To fulfill this functionality of the OK button, after adding it to a dialog box (or
form), open the AcceptButton combo box in the Properties window for the
form and select the name of the button.
2. In the Properties window, click the arrow of the AcceptButton field and
select btnOK
Cancelling an Action
The Cancel button is used to allow the user to dismiss whatever changes
would have been made on the controls of the dialog box. The dialog box
should also be configured so that if the user presses Esc, the dialog box
would be closed as if the user had clicked Cancel.
To fulfill this functionality of the Cancel button, after adding it to a dialog box
(or form), open the CancelButton combo box in the Properties window for
the form and select the name of the button.
Besides the OK and the Cancel buttons, a dialog box can be created with
additional buttons such as Finish or Help, etc. It depends on its role and the
decision is made by the application developer.
1. In the Properties window, click the arrow of the CancelButton field and
select btnCancel
FormBorderStyle = FormBorderStyle.FixedDialog;
MinimizeBox = false;
MaximizeBox = false;
HelpButton = true;
}
When the user clicks the help button, the mouse cursor becomes equipped
with a question mark. Here is an example:
A Modal dialog box is one that the user must first close in order to have
access to any other framed window or dialog box of the same application.
One of the scenarios in which you use a dialog box is to create an application
that is centered around one. In this case, if either there is no other form or
dialog box in your application or all the other forms or dialog boxes depend
on this central dialog box, it must be created as modal. Such an application is
referred to as dialog-based.
The Date and Time dialog box of WordPad is modal: when it is displaying, the
user cannot use any other part of WordPad unless he or she closes this object
first
Here is an example:
The Find
(and the
Replace)
dialog box of
WordPad
(also the Find
and the
Since the modeless dialog box does not display its button on the task bar, the
user should know that the dialog box is opened. To make the presence of a
modeless dialog box obvious to the user, it typically displays on top of its host
application until the user closes it.
A modeless dialog box is created from a form but it should look like a regular
dialog box or a tool window. Therefore, to create a modeless dialog box, set
the FormBorderStyle property to an appropriate value such as
FixedSingle, FixedToolWindow, Sizable or SizableToolWindow. Also,
set its ShowInTaskbar property to False.
After creating the dialog box, to display it as modeless, call the Show()
method. The fundamental difference between the ShowDialog() and the
Show() methods is that the former displays a modal dialog box, which makes
sure that the called dialog box cannot go in the background of the main
application. By contrast, the Show() method only calls the dialog box every
time it is requested. For this reason, it is up to you to make sure that the
modeless dialog box always remains on top of the application. This is easily
taken care of by setting the Boolean TopMost property of the form to True.
There are two main ways a normal modeless dialog box can be dismissed:
If the user has finished using it, he or she can close it and recall it at will
When the form or application that owns the modeless dialog box is closed, the
form or application closes the modeless dialog if it is opened; this means that
you don't need to find out whether a modeless dialog box is still opened when
the application is being destroyed: either the user or the application itself will
take care of closing it
On the main menu, you can click Project -> Add New Item...
On the main menu, you can click File -> Add New Item...
In Solution Explorer, you can right-click the name of the project, position
the mouse on Add, and click Add New Item...
In the Add New Item dialog box and in the Templates section, click Window
Form (.NET), provide a name in the Name edit box then click Open.
If your application is using various forms and you want to display a particular
one at design time:
In the Forms Designer, you can click the tab that corresponds to the
desired form and that has [Design]
On the main menu, you can click Window and click the name of the form
in the list under Close All Documents
If you visually add two (or more) forms to your application, you may need to
link them, allow one to call the other. To do this, in the top section of the file,
type #include followed by the name of the header file in which the form was
defined. In the section where you want to access the form, declare a handle
to the class of the form and use the new operator to allocate memory for it.
To display the other form, you can call its Show() method.
2. Double-click the New Property... button and implement the event as follows:
private void btnNewProperty_Click(object sender,
EventArgs e)
{
Random rnd = new Random();
PropertyEditor dlgEditor = new
PropertyEditor();
if (dlgEditor.ShowDialog() ==
lvi.SubItems.Add(dlgEditor.txtPropertyType.Text);
lvi.SubItems.Add(dlgEditor.txtBedrooms.Text);
lvi.SubItems.Add(dlgEditor.txtBathrooms.Text);
lvi.SubItems.Add(dlgEditor.txtMonthlyRent.Text);
}
}
4. Create a property
5. Press Enter
Message Boxes
Introduction
A message box is a special dialog box used to display a piece of information to the user.
As opposed to a regular form, the user cannot type anything in the dialog box. The .NET
Framework inherently supports message boxes through its own MessageBox class.
Besides this, you can also use functions from either the Visual Basic or the Win32
libraries.
If the User
The Method Returns
Clicks
DialogResult.Abort
DialogResult.Cancel
DialogResult.Ignore
DialogResult.No
DialogResult.OK
DialogResult.Retry
DialogResult.Yes
In this case, the message to display must be passed as a string to the Show()
method. Here is an example:
This version allows you to specify a custom caption for the message box. With
this version, the first argument is the string that the user will see displaying
on the message box. You can pass it as a string. You can also create it from
other pieces of strings.
The second argument, caption, will be the sentence to display in the title bar
of the message box. Here is an example:
public class Program
{
static int Main()
{
MessageBox.Show("Welcome to the Wonderful World of
Visual C#",
"Visual C#
Tutorials");
return 0;
}
}
This version allows you to display one or more buttons on the message box.
The available buttons are defined through the MessageBoxButtons
enumeration. Its members are:
MessageBoxButtons Display
OK
OKCancel
YesNo
YesNoCancel
RetryCancel
AbortRetryIgnore
MessageBoxIcon Description
None
Asterisk
Error
Exclamation
Hand
Information
Question
Stop
Warning
Based on this, you can specify the default button using the last argument that
provides values through the MessageBoxDefaultButton enumerator whose
values are:
Button2: If the message box displays two buttons, the right button will be the
default. If the message box displays three buttons, the middle button will be
the default. Here is an example:
public class Program
{
static int Main()
{
MessageBox.Show("Your order appears to be correct" +
"\nAre you ready to provide your credit
card information?",
"Customer Order Processing",
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Information,
MessageBoxDefaultButton.Button2);
return 0;
}
}
Introduction
There are two main ways you will manipulate an object of your application, visually or
using code. In future sections, we will explore details of visually designing a control. As
you should have found out from learning C#, code of an application is ASCII text-based,
written in plain English and readable to human eyes. For an application, you can use any
text editor to write your code but one of Visual Studio's main strengths is the code
editor. It is very intuitive.
Once in the Add New Item dialog box, in the Templates section, click the type
of file you want to create, type a name in the Name text box, and press
Enter. After the file has been created, it is represented by a tab in the top
On the main menu, you can click Window and click the name of the
desired tab
By default, the tabs display in the order their files were created or added to the
project, from left to right. If you don't like that arrangement, click and drag its
tab either left or right beyond the next tab
3. To create a new class, on the main menu, click Project -> Add Class...
5. To access the Circle tab, on the main menu, click Window -> Circle
namespace Exercise1
{
class Circle
{
private double rad;
namespace Exercise1
{
class Triangle
{
private double bas;
private double hgt;
class Kite
{
}
}
9. Save all
If you select an item from the Members combo box, the Code Editor jumps to
that members and positions the cursor to the left of the member.
namespace Exercise1
{
class Circle
{
private double rad;
. . . No Change
}
3. Save all
Code Colors
Code is written in a wide area with a white background. This is the area you
use the keyboard to insert code with common readable characters. The
Code Editor uses some colors to differentiate categories of words or lines of
text. The colors used are highly customizable. To change the colors, on the
main menu, you can click Tools -> Options... In the Options dialog box, in the
Environment section, click Fonts and Colors. To set the color of a category, in
the Display Items section, click the category. In the Item Foreground combo
box, select the desired color. If you want the words of the category to have a
colored background, click the arrow of the Item Background combo box and
select one:
Regions
When code of a file is long, it can be tiresome to scroll up and down. The
Visual Studio .NET's Code Editor allows you to create sections that allow the
code to behave like the tree arrangement of the left pane of Windows
Explorer. This means that you can expand or collapse section of code. The
Code Editor supports this feature automatically by adding + buttons at the
beginning of the lines of sections that can be expanded or collapsed. This is
the case for namespaces, classes, methods, interfaces, properties, etc. The
end of an expandable section displays a - button to the beginning of the line.
Besides the default sections that the Code Editor is intuitively aware of, you
can create your own region. A region must have a beginning and an end. To
specify the start of a section, type #region. You can optionally add a label to
the right of #region to name the region. After creating a region with
#region, the Code Editor adds a + button to its left. To expand a region, you
can click its + button. This changes it into a - button. To collapse the region,
click the - button.
If you don't specify the end of the region, the code from #region to the end
of the file would be considered as belonging to the to the region. Therefore,
you should specify the end of the region you created. To mark the end of the
region, in the desired line, type #endregion.
namespace GeometricFormulas
{
interface IGeometry
{
double Length { get; set; }
double Height { get; set; }
}
class Square
{
#region Formulas to Calculate a Square's Perimeter
and Area
public double Perimeter(double side)
{
return side * 4;
}
class Trapezoid
{
private double _base1;
}
public Rectangle()
{
this.len = 0.00;
this.hgt = 0.00;
}
#endregion
The Code Editor can help you specify the beginning and end of a region.
Introduction
A method is a procedure created as a member of a class. Methods are used
to access or manipulate the characteristics of an object or a variable. There
are mainly two categories of methods you will use in your classes:
If you are using a control such as one of those provided by the Toolbox,
you can call any of its public methods. The requirements of such a
method depend on the class being used
If none of the existing methods can perform your desired task, you can
add a method to a class.
public Exercise()
{
InitializeComponent();
Application.Run(new Exercise());
}
}
If you are not planning to use a control straight from the .NET Framework,
you can also create your own class that is derived from the class of the
control, as we have mentioned in previous lessons.
using System;
using System.Windows.Forms;
public Exercise()
{
InitializeComponent();
}
This method takes one argument, disposing, that indicates how the resources
would be released. If this argument is passed with a false value, only the
unmanaged resources would be released. If it is passed as true, then both
managed and unmanaged resources would be released.
Control's Visibility
In the previous lesson, we saw that you can call the Visible property to hide
a visible control or to display a hidden control. Besides the Visible property,
you can also display a control using the Show() method. Its syntax is:
Public Sub Show()
When you use this method, if the control is visible, nothing would happen. If
it were hidden, then it would be revealed. In the following example, a text
box named textBox1 is asked to display:
private void button1_Click(object sender, EventArgs e)
{
this.textBox1.Visible = false;
}
The Show() method internally sets the Visible property to true. We also
saw that, to hide a control, you can set its Visible property to False. In the
same way, to hide a control, you call can the Control.Hide() method. Its
syntax is:
Public Sub Hide()
Keep in mind that hiding a control does not close or destroy it.
Control's Focus
Once a control is visible, the user can use it. Some controls allow the user
only to read their text or view what they display. Some other controls allow
the user to retrieve their value or to change it. To perform such operations,
the user must first give focus to the control. The focus is a visual aspect that
indicates that a control is ready to receive input from the user. Various
controls have different ways of expressing that they have received focus.
To give focus to a control, the user can press a key such as Tab. To
programmatically give focus to a control, call the Focus() method. Here is an
example:
private void button2_Click(object sender, EventArgs e)
{
this.textBox1.Focus();
}
When one control is positioned on top of another, they use a third axis whose
origin, like that or the other axes, is on the top-left corner of the parent. This
third axis, also considered the z-axis, is oriented so that it moves from the
monitor towards the user. The operating system is in charge of positioning
and drawing the objects on the screen. You as the programmer can direct the
operating system as to what object should be on top and what object should
be behind. To support these changes the Control class uses two methods
that its appropriate children derive also.
After the controls have been positioned, at any time, when you access a
control, if you want to know whether that control is the most top object, you
can call its GetTopLevel() method. Its syntax is:
proteced bool GetTopLevel();
In the same way, if you derive a class from one of the existing classes
because you want to get a custom control from it, you can declare a new
method as you see fit and use it appropriately.
Probably the best way is to let the Code Editor insert the new method based
on your specifications. To do that, in the Class View, first expand the name of
the project. Then, right-click the name of the class where you want to add a
new method, position the mouse on Add, and click Add Method. This would
open the C# Method Wizard dialog box you can fill out and click Finish. After
the method's body has been defined you
Introduction
The Windows controls featured in the .NET Framework are highly varied and
provide all the necessary regular functionality a normal application would
need. They do this through various properties and their different methods. To
enhance their functionality and speed up application development, you can
either create your own new library or use a library created in another
language.
Using a Library
If the .NET Framework doesn't have a class you are looking for, you can
create one and be able to use it over and over again in different programs.
You can even create a commercial class and be able to distribute or sell it. To
make this possible, you can "package" one or more classes in a library. A
library is a program that contains classes and/or other resources that other
programs can use. Such a program is created with the same approach as the
programs we have done so far. Because a library is not an executable, it
doesn't need the Main() function. A library usually has the extension .dll.
A library can be made of a single file or as many files as necessary. A file that
is part of a library can contain one or more classes. Each class should
implement a behavior that can eventually be useful and accessible to other
classes. The classes in a library are created exactly like those we have used
so far. Everything depends on how you compile it.
To create a library, start by typing its code in a text file. Once the library is
ready, to compile it, at the Command Prompt, you would type:
and press Enter. After doing this, a library with the name of the file and the
extension .dll would be created. If you want a custom name, use the
following syntax:
csc /target:library /out:DesiredNameOfLibrary.dll NameOfFile.cs
class Program
{
[DllImport("Kernel32.dll")]
public static extern bool SetConsoleTitle(string
strMessage);
return 0;
}
}
Introduction
The C and C++ concept of function pointer was very useful when
programming for the Microsoft Windows operating systems because the
Win32 library relies on the concept of callback functions to process messages.
For this reason and because of their functionality, callback functions were
carried out in the .NET Framework but they were defined with the name of
delegate.
Declaring a Delegate
To declare a delegate, you use the delegate keyword. The basic formula
used to create a delegate is:
[attributes] [modifiers] delegate result-type identifier
([formal-parameters]);
The ReturnType can be any of the data types we have used so far. It can also
be a type void or the name of a class.
Announce();
this.InitializeComponent();
}
Application.Run(form);
}
}
this.InitializeComponent();
txtBox.Text = Add().ToString();
}
return a + b;
}
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication2
{
delegate double Multiplication();
public Cube()
{
_side = 0;
}
public Cube(double s)
{
_side = s;
}
InitializeComponent();
txtSide.Text = SmallBox.Side.ToString();
txtArea.Text = AreaDefinition().ToString();
txtVolume.Text = VolDefinition().ToString();
}
}
}
Delegates Compositions
One of the characteristics that set delegates apart from C/C++ function pointers
is that one delegate can be added to another using the + operation. This is
referred to as composition. This is done by adding one delegate variable to
another as in a = b + c.
When defining the associated method, besides returning the same type of
value if not void, make sure that the method takes the same number of
arguments. Here is an example:
class Exercise
{
private static double Plus(double a, double b)
{
return a + b;
}
Notice that only the name of the method is passed to the delegate. To actually
use the delegate, when calling it, in its parentheses, provide a value for the
argument(s) conform to the type specified when declaring the delegate.
namespace GeometricFormulas
{
public delegate double Squared(double x);
namespace GeometricFormulas
{
public delegate double Squared(double x);
namespace GeometricFormulas
{
public delegate double Squared(double x);
You can also define the associated method in another class, not necessarily in
the class where the delegate would be needed. Once the method that
implements the delegate is known, you can use the delegate as you see fit.
To do that, you can declare a variable of the type of that delegate and pass
the implementing method to its constructor. Here is an example:
namespace GeometricFormulas
{
public delegate double Squared(double x);
This declaration gives life to the delegate and can then be used as we have
proceed with delegates so far.
Introduction
Providing help is one of the most neglected areas of application development. There are
various reasons to this. Some programmers tend to think that help is such a small job
that it should be left to non-programmers. This is not a valid argument since the person
who creates an application knows it better than anybody. Asking someone else to create
help for your application would only slow the process because the other person would
need to have new and more information about the application. Another reason is that,
most programmers who want to take care of programming when creating an application
think that they are working double to create a single program. This drives them to set this
There are various small but effective techniques you can use to provide help in your application: ne
3. In the Properties window, change the form's Text to Clarksville Ice Cream
GroupBox grpIceCream
Label Flavor:
ComboBox cboFlavors
Label Container:
ComboBox cboContainers
Label Ingredient:
ComboBox cboIngredients
Label Scoops:
5. Click the combo box to the right of the Flavor label. Then, in the Properties, click the ellips
property and create the list with:
Vanilla
Cream of Cocoa
Chocolate Chip
Cherry Coke
6. Click OK
7. Click the combo box to the right of the Container label. Then, in the Properties, click the e
Items property and create the list with:
Cone
Cup
Bowl
8. Click OK
9. Click the combo box to the right of the Ingredient label. Then, in the Properties, click the e
Items property and create the list with:
None
Peanuts
Mixed Nuts
M&M
Cookies
10. Click OK
11. Double-click the New Order button to access its Click event and implement it as follows:
private void btnNewOrder_Click(object sender, EventArgs e)
{
// If the user clicks New Order, we reset the form
with the default values
this.dtpOrderDate.Value = DateTime.Today;
this.dtpOrderTime.Value = DateTime.Now;
this.cboFlavors.Text = "Vanilla";
this.cboContainers.Text = "Cone";
this.cboIngredients.Text = "None";
this.txtScoops.Text = "1";
this.txtOrderTotal.Text = "0.00";
}
try {
// Get the number of scoops
NumberOfScoops = int.Parse(this.txtScoops.Text);
if( NumberOfScoops == 2 )
PriceScoops = 2.55;
else if( NumberOfScoops == 3 )
PriceScoops = 3.25;
else
PriceScoops = 1.85;
}
catch(FormatException)
{
MessageBox.Show("The value you entered for the scoops
is not valid" +
"\nOnly natural numbers such as
1, 2, or 3 are allowed" +
"\nPlease try again");
}
this.txtOrderTotal.Text = OrderTotal.ToString();
16. Double-click the Close button and implement its Click event as follows:
private void btnClose_Click(object sender, EventArgs e)
{
Close();
}
2. On the Toolbox, click StatusStrip and click the bottom section of the form
3. In the Properties window, click Items and click its ellipsis button
4. In the Select Item and Add to List Below combo box, select StatusLabel if necessa
On the right side, set the Text to Ready
6. On the form, click the dtpOrderDate control; that is, the combo box on the right side of th
7. In the Properties window, click the Events button and double-click MouseMove
9. In the same way, initiate the MouseMove event of the dtpOrderTime date time picker, the
box, the cboContainers combo box, the cboIngredients combo box, the txtScoops text box
11. Return to the form and click a border of the group box
12. In the Events section of the Properties, generate the event of the MouseHover field, and implement
13. Return to the form and click an area of its body away from any control on it
14. In the Events section of the Properties, generate the event of the Move field, and implement it as fo
private void grpIceCream_MouseHover(object sender, EventArgs e)
{
this.statusStrip1.Items[0].Text = "Ready";
}
16. After using it, close the form and return to Visual Studio
Tool Tips
A tool tip is a small yellow box that displays a word or a group of words when the user positio
of a control:
To create a tool tip system in a Visual Studio 2005 application, first add a ToolTip control to a
ToolTip control, the form and all controls on it receive a new field in the Properties window
1. To prepare for tool tips, on the Toolbox, click ToolTip and click the form
2. On the form, click each control and, in the Properties window, set its ToolTip On ToolTip property
Click each section, then click one of the arrows to change its
dtpOrderTime
value
cboFlavors Click the arrow to display a list, then select a flavor from the list
cboIngedients Display the list of ingredients and make the customer's choice
Online Help
Introduction
Online help is the system of providing help files with an application. Online help is
usually available from the main menu through a menu group created under a Help
category.
In the past, the techniques to provide or program online help were not always easy. The
early implementations of help were created in a system called WinHelp. This required
using a Rich Text Format (rtf) file and appropriately formatting it. It is possible that,
when folks at Microsoft developed WinHelp, they had only Microsoft Word in mind. It
was difficult to get the required file ready if you were using another application such as
WordPad or WordPerfect...
Creating the help file was not enough. Once the file was ready, it had to be added to
application, and appropriately. This back and forth gymnastic was a great motivation for neg
As if these difficulties were not enough, or because of these difficulties, Microsoft created ano
system called HTML Help. This neither solved most problems nor created an easier solution
this time, this HTML Help is widely used and many companies, such as AutoDesk (AutoCAD)
Macromedia to name just two, have adopted it . Many companies such as Borland, Jasc, jus
2. In the Add New Item dialog box, set the name of the form to Calculation, and click Add
TextAlign: Right
TextBox txtOrderTotal 0.00
Modifier: Public
Amount
Label
Tended:
Label Difference:
try
{
// The amount tended will be entered by the user
AmountTended =
double.Parse(this.txtAmountTended.Text);
}
catch(FormatException)
{
MessageBox.Show("The amount you entered is not " +
"valid - Please try again!");
}
6. Add a new button to the bottom side of the form between the other buttons
8. Double-click the Difference button and implement its Click event as follows:
9. Change the Click events of the Calculate Total and the New Order buttons as follows:
private void btnNewOrder_Click(object sender, EventArgs e)
{
// If the user clicks New Order, we reset
// the form with the default values
this.dtpOrderDate.Value = DateTime.Today;
this.dtpOrderTime.Value = DateTime.Now;
this.cboFlavors.Text = "Vanilla";
this.cboContainers.Text = "Cone";
this.cboIngredients.Text = "None";
this.txtScoops.Text = "1";
this.txtOrderTotal.Text = "0.00";
this.btnDifference.Enabled = false;
}
try
if (NumberOfScoops == 2)
PriceScoops = 2.55;
else if (NumberOfScoops == 3)
PriceScoops = 3.25;
else
PriceScoops = 1.85;
}
catch (FormatException)
{
MessageBox.Show("The value you entered for the scoops is not
valid" +
"\nOnly natural numbers such as 1, 2, or 3 are
allowed" +
"\nPlease try again");
}
this.txtOrderTotal.Text = OrderTotal.ToString();
this.btnDifference.Enabled = true;
}
This help is easier to provide in a dialog box because a dialog has a feature not available o
form. It consists of adding a button with a question mark and then creating the words that w
display eventually. When you create this type of dialog box, the user can click the question ma
button and click a control. The user can also press Shift+F1. This causes the mouse pointer t
equipped with a question mark. The user can then click a control and a yellow box would ap
for that control, providing help.
3. In the Components section of the Toolbox, click HelpProvider and click the form
4. Using the Properties window, change the following values for the indicated controls:
This displays the difference between the amount tended and the
txtDifference
total of the order
6. When it displays, process an order and click the Calculate Difference button
7. In the Calculation dialog box, click the question mark button in the title bar and click on the text bo
or buttons
8. After using the application, close the forms and return to Visual Studio
10. To add a menu to the application, on the Toolbox, click MenuStrip and click the form
11. On the form, click Type Here. Type &File and press the down arrow key
13. On the right side of File (on the form), click Type Here
20. Test the application then close it and return to Visual Studio
To provide online help in a Visual Studio 2005 application, you can use an external system.
consists of creating a complete application whose only purpose is to describe another applica
.maintitle
{
font-weight: bold;
font-size: 24pt;
color: blue;
font-family: Garamond, Georgia, 'Times New Roman' ,
Serif;
}
<head>
<body>
<p> </p>
<center><img border="0" src="images/main1.gif"
alt="The main window of the application"
width="416" height="284"></center>
<p>Clarksville Ice Cream is a computer application used to
process customers
orders. It allows an employee to receive requests from a
customer, based on what
is available in the menu. When the order is complete, an ice
cream is
"prepared" and handed to the customer. As a
commercial business, the
application calculates the total amount. The amount is read to
</body>
</html>
7. Save it as introduction.htm
<head>
<body>
<p> </p>
<p>The main or opening window of this application displays a
form used to
process customers orders. The top section of the form, also
called the title
bar, is equipped with a menu called the main menu. this menu
allows the user to
start a new order or to close the application. To use this main
menu, you can
click one of the top-level words such as File. This causes the
menu category of
your choice to expand:</p>
<center>
<img border="0" src="images/main2.gif"
alt="The main menu" width="416" height="284"></center>
<p>After using a menu item, you can click it or click somewhere
else to collapse
it.</p>
<p>The other objects on the main form allow the user to process
an order by
<p>To start a new customer order, the user can click the New
Order button. This
resets all controls on the form:</p>
<center>
<img border="0" src="images/main3.gif"
alt="Customer Form Reset" width="416"
height="284"></center>
<p>When an order has been calculated, the user can click the
Calculate
Difference button to evaluate the diffence.</p>
</body>
</html>
9. Save it as mainform.htm
<head>
<title>Difference Calculation</title>
</head>
<body>
<p> </p>
<p>The Calculation dialog box allows a user to easily calculate
the amount of
money owed to a customer. After a customer has placed an order
</body>
</html>
<head>
<body>
<h1>Clarksville Ice Cream</h1>
<p><a href="introduction.htm">Introduction</a></p>
<p><a href="mainform.htm">The Main Form</a></p>
<p><a href="calculation.htm">The Difference Calculation Dialog
Box</a></p>
</body>
</html>
15. On the main menu of HTML Help Workshop, click File -> New
17. In the first page of the New Project wizard, click Next
19. Locate the cic folder you created and display it in the Save In combo box
23. In the third page, read the text. Click the HTML files (.htm) check box and click Next
25. In the Open dialog box, press and hold Ctrl. Then click each htm file to select them all
30. Click OK
34. In the Table Of Contents Entry dialog box, in the Entry Title text box, type Clarksville
Cream and click Add
35. In the Path Or URL dialog box, select the Clarksville Ice Cream - Home and click OK
36. Click OK
39. In the Entry Title text box, type Introduction and click Add
40. In the Path Or URL dialog box, select the Overview of Clarksville Ice Cream and click OK
42. In the same way, create new pages under the Introduction heading using the following table
Customer Order
Customer Order Form
Form
Difference
Difference Calculation
Calculation
43. In HTML Help Workshop, click the Index tab. In the dialog box that comes up, make sure
top radio button is selected
45. Accept the suggested name of the file and press Enter
47. In the Keyword text box, type Calculation and click Add
48. In the Path Or URL dialog box, click Difference Calculation and click OK twice
49. In the same way, create new keywords using the following table (sometimes you may receive a
message box asking whether you want to create the keyword above the other; it doesn't matter, for t
exercise, whether you click Yes or No):
Amount
Difference Calculation
Tended
55. Click the Buttons tab then click the Home and the Locate check boxes
61. Click the Search Tab and the Advanced check boxes
63. When the Resolve Window Definition wizard comes up, in the first page, make sure the
window defined previously is selected in the Window Type combo box and click Next
66. In the second page, accept the defaults and click Next
67. In the third page, accept the default and click Finish
68. To create the help file, click the Save All Files And Compile button
HTML Help can be provided to a Visual Studio 2005 application through the Help class.
overloaded ShowHelp() method is used to specify the help file to display and possibly additi
information. Notice that all versions take a first argument as a Control type. This is the pa
control from where the online help will be provided.
The first version allows you specify the help file. It can be the help file specified in
HelpProvider.HelpNamespace property mentioned above.
The second and the fourth versions allow you to specify the tab of the HTML Help window
display when the method is called. This is done through the HelpNavigator enumerator that
a value for each tab of the HTML Help window. the fourth version can be used to open the H
Help window from its Find tab and specify a keyword to search for.
The ShowHelpIndex() method can be used to open the Index tab of the HTML Help window.
2. In the cic folder, copy the cicoh.chm file to the clipboard and paste it in the folder of the
current project (ClarckvilleIceCream1)
4. In the Components section of the Toolbox, click HelpProvider and click the form
5. In the Properties window, change its Name to hpvIceCream and click HelpNamespace
7. From the CIC1 folder of the current project, select the cicoh.chm file
8. Click Open
9. On the main menu of the form, click Help and double-click Contents
11. Display the main form. On the main menu of the form, double-click Index
13. Display the main form. On the main menu of the form, double-click Search
15. Test the application. When it displays, click the Help menu of the form and click one of the
menu items
The Toolbox
Introduction
A Windows control is a graphical object that allows the user to interact with the
By default, the Toolbox is positioned on the left side of the IDE. To change
that position, you can drag its title bar away and dock it to another side of the
IDE. The Toolbox also uses a default width to show the items on it. If the
width is too narrow or too wide, you can change it. To do this, position the
mouse to its right border and drag left or right.
Besides the objects in the Common Controls section, other controls are left
out but are still available. Some of the left out controls were created with
the .NET Framework but are not installed by default because they are judged
hardly used. To add one or more of these left out controls, right-click
anywhere in the Toolbox and click Choose Items... In the Choose Toolbox
Items dialog box, click the .NET Framework Components tab, then click the
check box of the desired control before clicking OK:
If the available list of categories is not enough, you can add a new section of
your choice. By default, Visual Studio hides some categories because they are
If you still want an additional tab not included in the list, you can add one (or
more). To do that, right-click anywhere in the Toolbox and click Add Tab. You
would be prompted to provide a name. After typing the new name, press
Enter.
Once you have rearranged items alphabetically, the Toolbox forgets the
previous arrangement and you cannot restore it. Alternatively, you can right-
click the button of a control and click either Move Up or Move Down.
Introduction to
Application Design
Introduction
To add a control to your application, you can select it from the Toolbox and
click the desired area on the form. Once added, the control is positioned where
your mouse landed. In the same way, you can add other controls as you judge
them necessary for your application. Here is an example of a few controls
added to a form:
Alternatively, to add a control, you can also double-click it from the Toolbox
and it would be added to the top-left section of the form.
If you want to add a certain control many times, before selecting it on the
Toolbox, press and hold Ctrl. Then click it in the Toolbox. This permanently
selects the control. Every time you click the form, the control would be added.
Once you have added the desired number of this control, on the Toolbox,
click the Pointer button to dismiss the control.
2. To create a new application, on the main menu, click File -> New
Project...
6. Click the Label button and position the mouse on the form
9. To add another control, position the mouse again on the Toolbox word
until the Toolbox has expanded
11. To use a hidden area of the form, position the mouse on the Toolbox
word. When the Toolbox has expanded, click the Auto Hide button
12. On the Toolbox, click the TreeView button and click the left section
of the form
13. After using the Toolbox, to hide it, click the Auto Hide button
14. To execute the application, on the main menu, click Debug -> Start
Without Debugging
15. After using it, close the form and return to your programming
environment
Right-click the control and click Copy. Right-click another area of the
form and click Paste
Press and hold Ctrl. Then drag the selected control to another area of
the form. The mouse cursor would display a + plus indicating that the
control is being duplicated:
Once you get to another area of the form, release the mouse and Ctrl
Dynamic Control
Creation
Introduction
using System;
using System.Windows.Forms;
public Exercise()
{
}
}
public class Program
{
public static int Main()
{
Application.Run(new Exercise());
return 0;
}
}
After declaring the variable, you can use the new operator to allocate memory
for it:
public class Exercise : Form
{
private Button btnSubmit;
public Exercise()
{
btnSubmit = new Button();
}
}
public Exercise()
{
btnSubmit = new Button();
Controls.Add(btnSubmit);
}
}
This makes it possible for the control to appear on the form when the form
displays to the user:
These two techniques of visual addition of objects and dynamic creation are
the most used to add Windows controls to an application. The Windows
controls are also called components.
public Exercise()
{
InitializeComponent();
}
}
Like the source file of a C++ application, the second file that serves a class
can then be used to define or implement the methods. Here is an example:
public Exercise()
{
InitializeComponent();
}
}
In Microsoft Visual C#, the name of the first file of a form starts with the
name of the form, followed by a period, followed by Designer, followed by a
period, and followed by the cs extension.
After this declaration, the compiler can keep track of the components that
are part of the form.
To derive a class from an existing control, you can use your knowledge of
inheritance. Here is an example:
public class Numeric : System.Windows.Forms.TextBox
{
}
Besides the constructor, in your class, you can add the fields and methods as
you see fit. You can also use it to globally set a value for a field of the parent
class. Once the control is ready, you can dynamically use it like any other
control. Here is an example:
using System;
using System.Windows.Forms;
public Exercise()
{
InitializeComponent();
}
}
This produce:
Control Selection
Introduction
When designing an application, you will manipulate the windows controls on a
form. After adding a control to a form, before performing any operation on that
Control Deletion
If there is a control on your form but you don't need it, you can remove it from
the application. To delete a control, first select it and then click or press Delete.
You can also right-click a control and click Cut. To remove a group of controls,
first select them, then click or press Delete or right-click the selection and click
Cut.
Introduction
On the main menu, you can click View -> Properties Window
On the form, you can right-click anything (either the form itself or any
control positioned on it) and click Properties
Description
The Properties window uses the behaviors we reviewed in Lesson 1 about
auto-hiding, docking, floating or tabbing the tools that accompany Microsoft
Visual Studio 2005. This means that you can position it on one side of the
screen or to have it float on the screen as you wish.
The Properties window starts on top with a title bar, which displays the string
Properties. If the window is docked somewhere, it displays the Window
Under the title bar, the Properties window displays a combo box. The content
of the combo box is the name of the form plus the names of the controls
currently on the form. Besides the technique we reviewed earlier to select a
control, you can click the arrow of the combo box and select a control from
the list:
Under the combo box, the Properties displays a toolbar with 4 buttons.
Under the toolbar, the Properties window displays the list of properties of the
selected control(s). On the right side, the list is equipped with a vertical scroll
bar. The items in the Properties window display in a list set when installing
Microsoft Visual Studio. In the beginning, you may be regularly lost when
looking for a particular property because the list is not arranged in a strict
order of rules. You can rearrange the list. For example, you can cause the
items to display in alphabetic order. To do this, on the toolbar of the
Properties window, click the Alphabetic button . To restore the list, you
can click the categorized button .
Two lists share the main area of the Properties window. When the list of
properties is displaying, the Properties button is clicked . The second is the
list of events. Therefore, to show the events, you can click the Events button
. If the events section is displaying, to show the list of properties, you can
click the Properties button .
Under the list of properties, there is a long bar that displays some messages.
The area is actually a help section that displays a short description of the
property that is selected in the main area of the Properties window.
You can also change some characteristics of various controls at the same
time. To do this, first select the controls on the form and access the
Properties window:
The Properties window displays only the characteristics that are common
to the selected controls
Some fields of the Properties appear empty because the various controls
that are selected have different values for those properties
1. To create a new application, on the main menu, click File -> New
Project...
Properties Categories
Introduction
Each field in the Properties window has two sections: the property’s name and
the property's value:
The box on the right side of each property name represents the value of the
property that you can set for an object. There are various kinds of fields you
will use to set the properties. To know what particular kind a field is, you can
click its name. To set or change a property, you use the box on the right side
of the property’s name: the property's value, also referred to as the field's
value.
To display the Properties windows, on the main menu, click View ->
Properties Window
Empty Fields
By default, these fields have nothing in their value section. Most of these
properties are dependent on other settings of your program. For example, you
can set a menu property for a form only after you have created a menu.
To set the property on such a field, you can type in it or select from a list.
Text Fields
There are fields that expect you to type a value. Most of these fields have a
default value. Here is an example:
While some properties, such as the Text, would allow anything, some other
fields expect a specific type of text, such as a numeric value.
1. In the Properties windows, click Text and notice that it contains a string
in bold characters
Numeric Fields
Some fields expect a numeric value. In this case, you can click the name of
the field and type the desired value. Here is an example:
. If you type an invalid value, you would receive a message box notifying you
of the error:
When this happens, click OK and type a valid value. If the value is supposed
to be an integer, make sure you don't type it as a decimal number.
2. While the control is still selected on the form, in the Properties windows,
click Value and notice that it contains a number string in bold characters
3. Click the DecimalPlaces, the Increment, the Maximum, and the Minimum
fields to see that they contain numeric values:
Date-Based Fields
Some fields expect you to enter a date. You must type a valid date
recognized by the operating system and the Regional and Language Settings
in Control Panel. If you enter an invalid date, you would receive an error.
2. While the control is still selected on the form, in the Properties windows,
click Value and notice that it contains a date and time value
Expandable Fields
Some of the properties are numeric based, such as the Location or the
Size. With such a property, you can click its name and type two numeric
values separated by a comma. Some other properties are created from an
enumeration or a class. If you expand such a field, it would display various
options. Here is an example from the Font property:
2. In the Properties window, click the + button of the Font field to expand
it and notice that it display some previously hidden items
Boolean Fields
1. In the Properties window click Enabled and notice that it displays True
Action Fields
Some fields would require a value or item that needs to be set through an
intermediary action. Such fields display an ellipsis button . When you click
2. While the control is still selected on the form, in the Properties windows,
click Image and notice that the field displays an ellipsis button
3. Click the ellipsis button and notice that a dialog box comes up
4. Click Cancel
List-Based Fields
To change the value of some of the fields, you would use their combo box to
display the available values. After clicking the arrow, a list would display:
3. Press Alt and the down arrow key to display the list
4. Press Esc
Area-Selection Fields
Some properties provide a window from where you can select the desired
option. The field primarily displays the arrow of a combo box. To use the
field, you click the arrow of the combo box and the window appears. Here are
examples:
2. In the Properties window, click Dock and click the arrow of its combo box