Você está na página 1de 794

C# LANGUAGE FUNDAMENTALS Welcome to Visual C# Express 2010

It is essential to know the different parts of the Visual C# Express environment. You also need to know the different tools and features that this IDE can offer to you. Open Visual C# Express 2010, if this is your first time running the IDE, you need to wait for it to configure the initial settings for the user.

After the initial configuration, the Start Page of Visual C# Express 2010 will show up.

The numbered labels will be used to identify the different parts of the IDE.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Menu Bar


The Menu Bar(1) is where the different menus for creating, developing, maintaining, debugging, and executing programs can be found. Clicking a menu will reveal another set of related menus. Note that the menu bar still has hidden menu items which will only show on certain conditions. For example, the Project menu item will show if a project is currently active. Here are some of the description of each menu item. The following are some of the menus and their description. Menu Item File Description

Contains commands to create new projects or files, open or save projects, exit or close projects, printing, and many file or project related tasks. Contains commands which are related to editing such as selecting, copying, pasting, Edit finding, and replacing. Allows you to open more windows that are initially hidden or add more toolbars items View to the toolbar. Project Contains commands related to the projects you are working on. Debug Allows you to compile, debug(testing), and run the project. Contains command for connecting or creating different datasources for use in your Data application. Contains commands for arranging the layout of GUI components while in the Design Format View. Tools Contains the different tools, settings, and options for VS/VCE. Window Allows you to adjust the view or layout of the windows inside VS/VCE. Allows you to view the documentation and help topics, product registration details, Help and product version details.

The Toolbars
The Toolbars(2) contain commonly used commands which are also found in the menu bar. The toolbars serve as a shortcut to commands located in the menu bar. Each buttons has an icon that represents their functionality. You can hover each button to show a tool tip that describes their functionality. Some commands are initially hidden and will only show up on appropriate situations. You can also right click to any blank area of the toolbar to add more commands. Alternatively, you can go to View > Toolbars and check items to show up more toolbars. Some buttons have arrows beside them that when clicked, shows more related commands. You can also click the arrows beside each toolbar that will allow you to add or remove more buttons to tool bar. The left side of each toolbar allows you to move or change the arrangement of toolbars.

The Start Page

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You will see some tips, tutorials and news in the Start Page(3) section of the IDE. You can also create or open projects from here. If you have created some projects, then they will show up here in the Recent Projects section so you won't have a hard time finding each project. You can access the latest news related to .NET and Visual Studio by going to the Latest News tab. You can open VS/VCE's internal browser by going to View > Other Windows > Web Browser. There is more to explore in Visual C# Express and more parts of the program and features will be explained in the following lessons.

Registering Visual C# Express 2010


Visual C# Express is free, but you need to register the product to be able to use it permanently. You need to obtain a key from Microsoft to activate your copy of Visual C# Express. Note that this key will be given to you for free after following the steps in this lesson. Open Visual C# Express and on the Menu Bar, go to Help > Register Product.

You will be presented with a window asking for a Registration Key. Click "Obtain a registration key online" to begin the process of obtaining the key. An internet connection is required for the following process.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You will be taken to a page where you will be asked to log in your Windows Live ID. If you already have a Windows Live ID account, then you can sign in. If you currently don't have an account, you need to sign up for a new one by clicking the "Sign up now" button.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Copy the registration key and go back to Visual C# Express. Paste the key to the text box in the Registration Window and then click "Register Now". That's it, you can now use Visual C# Express permanently.

Exploring Visual C# Express 2010


Visual C# Express has lots of windows and components that provides functionality or displays certain informations. Let's further explore the different parts of Visual C# Express by going deeper into the IDE. Create a new Windows Forms Application by going to File > New Project or using the shortcut Ctrl+Shift+N.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You will be presented with the New Project Window.

To the left is a list of categories of installed templates. Since you are using Visual C# Express, only C# is available. The center of the window shows the installed template for the specified category. Templates are precreated project files which are provided to you so you will not create them from scratch. All you have to do is create a project from a template and start programming. The number of templates listed varies depending on the templates installed in your computer. You can sort the name of the templates by ascending or descending order by using the combo
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

box(drop down box) found at the top center. You can change the view of the templates by clicking the buttons next to that combo box. The right side shows a search box for searching installed templates and the description of the selected template. Choose Windows Forms Application from the list of templates. You can name your project using the text box found at the bottom. For now, leave it as it is. Click OK to generate a project from the selected template.

Figure 1 - Newly created Windows Forms Application Project

The Designer
The Designer(1) is like your canvas or drawing area for designing windows forms. Windows forms are graphical user interfaces and you see them everywhere when you use computers. You add controls to the form such as buttons, text boxes, labels, and many more. A more detailed look at windows forms, controls, and visual programming is located at the Windows Forms Section of this site. But it is recommended to finish the basic and fundamental lessons first before creating windows forms application.

The Solution Explorer.


The Solutions Explorer(2) shows the different projects and the files associated with the solution. A solution represents the application you are creating. It may compose of a single

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

project, or multiple projects, and each project is composed of files such as source code files and images. When you create a project, a solution is automatically created containing the project you have chosen. If the Solution Explorer is not visible, go to View > Other Windows > Solution Explorer or you can use the shortcut Ctrl+Alt+L. If multiple projects are present, the project in bold text is considered the Startup Project which is considered as the default project and the one that will run when you start debugging (more on this later). If the project you want to execute is not the startup project, right click the project in the Solution Explorer and then choose "Set as StartUp Project". Below is the Solution Explorer showing a Solution with 2 Projects. Each project contains files and folders associated to them.

The first button in its top bar allows you to edit the properties of the project. Some files located in the project directory are hidden in the Solution Explorer. You can click the second button to show all the hidden files.The third button refreshes the Solution Explorer in case files are added, deleted or modified. More buttons will show up depending on the current project or view you are working on. You can double click the files in the solution explorer to open them up or check their contents. You can also click the arrows to the left of each node to reveal child nodes they contain.

The Properties Window

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Properties Window(3) shows the different properties or events of any selected item such as files, projects, the form, or controls. If it is not visible to you, go to View > Other Windows > Properties Window or use the shortcut F4. We will have an in-depth discussion of properties and events in upcomming lessons. Properties can be considered as characteristics or attributes of objects. For example, a car has properties color, speed, size, and brand. If you are selecting a form or control in the Design View, or projects or files in the Solution Explorer, the Properties Window will show the properties available for them.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Properties Window also allows you to view the events of a selected control or form. An event is something that happens when certain conditions occur such as when a button is clicked or when the text inside the text box is modified. The top combo box(A) allows you to choose the object whose properties will be shown in the Properties Window. This is useful when you can't select certain controls(probably because of their small size) in the Designer. Below the combo box shows some helpful buttons(B). Some buttons only appear on certain instances. The first button will arrange the properties in different categories. The second button will arrange the properties in alphabetical order. I recomend pressing this button as I found it easier to find the properties you want when it is alphabetized. The third and fourth buttons only appear when you are selecting a control or a form in the designer view. The third button allows you to view the available properties of the current selected control or form. The fourth button (indicated by the thunder bolt icon) shows the available events for the selected control or form. The bottom box shows the description of the selected property or event. The main part of the properties window(C) contains the properties or the events. The left column specifies names of the properties or event. The right column shows the values of the properties and events. There are simple properties that require a single value, but there are also complex properties that consist of more properties. These can be identified with an arrow on the left of those properties. If you click that arrow, subproperties of the property are shown. Some properties opens up special tools or windows when normal text input cannot be accepted. The bottom part of the Properties Window is the Description Box(D) which shows the description of functionality of the selected property or event.

Changing the Layout of Visual C# Express


If you don't like the position of the windows, or the layout of the IDE, you have the ability to arrange them. By clicking and dragging the title bar of each window, you can make them float as shown below.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 - Guides are shown to aid in docking the windows While still draging the window, a guide used for docking will show up. This allows you to dock the window on certain locations of the IDE. For example, you can drag the window to the topmost box to dock it to the top. The area where the item being dragged will be docked will turn blue.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 2 - The area where the window will be docked is colored with blue

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 3 - Window is docked at the top portion of the IDE The central cross guide containing different boxes allows you to dock the window to certain parts of another window. For example, dragging the window to the left-most part of the cross while in the design view will dock the control to the left side of the Design View.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Dragging the window to the center of the cross will combine the window being dragged to the destination Window, in the case above, the Design Window and you can access the Properties Window via a tab.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

If you drag the Properties Window over the Solution Explorer for instance, another cross guide will show up. Draging the the window to the bottom of the guide will dock the Properties Window below the Solution Explorer.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The destination where your window will be docked will be partially filled with a blue color to notify you how it will be docked. Visual C# Express also offers a space saving feature called autohide which automatically hides the window. Each window has a pin icon next to the close button.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Clicking this icon will "unpin" the window and activate the auto-hide feature. You can now access the windows by hovering your mouse or clicking the tabs at the side of the IDE. Notice the large space saved by using the autohide feature.

To "pin" or disable the autohide feature of a window, simply access the window and clicked the pin icon again.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Notice that the pin is now horizontal. A vertical pin indicates that the window is pinned while a horizontal pin indicates that the window is unpinned and will auto-hide.

Creating a Simple Program


Let's create our very first program using the C# programming language. The program will print a line of message in the console window. Note that we will be using Console Application as the project type for the following tutorials. This is just an overview of what you will learn in the following lessons. I will explain here the structure and syntax of a simple C# program. Open up Visual C# Express. Go to File > New Project to open the New Project Window. You will be presented with a window asking you of the type and name of project you want to create.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 - New Project Window Choose Console Application as the project type and name it MyFirstProgram. A Console Application is a program that runs in command prompt(console) and has no visual or graphical interface. You will deal with this type of project because it will be easier to demonstrate the language concepts compared to using windows forms. We will begin with visual programming once we are finished with the fundamentals of this language. After pressing OK, Visual C# Express will create a solution file in a temporary directory. A solution is a collection of projects but for most of the tutorials, solutions only contain 1 project. The solution file with file extension .sln contains details about the projects and files associated with it and many more. Creating a new project also creates a .csproj file which contains details about the project and its associated files. Since we choosed Console Application as the project type, there will be no Designer. Instead, we are presented with the Code Editor.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 2 - Code Editor The Code Editor is where you type your codes. Codes typed in the editor are color coded so it will be easier for you to recognize certain parts or components of your code. Color Coding is another great feature of the Visual Studio family. The combo box to the top left(1) will list all the classes, structures, enumerations, and delegates in the code and the combo box to the top right(2) will list all the members of the class, structure, or enumeration where the cursor is positioned inside. Don't worry about the terms I used, they will be discussed in later lessons. A .cs file named Program.cs is created and is contained by the project. It will contain the codes for your program. All C# code files has .cs file extensions. You will be presented with a prewritten code to get you started, but for now, delete everything and replace it with the following code:
1 namespace MyFirstProgram 2 { 3 class Program 4 { 5 static void Main() 6 { 7 System.Console.WriteLine("Welcome to Visual C# Tutorials!"); 8 } 9 }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

10}

Example 1 - A Simple C# Program The numbers to the right are not part of the actual code. They are only there so it will be easier to reference which code is being discussed by simply telling their associated line number(s). In Visual C# Express, you can go to Tools > Options > Text Editor > C# and then check the Line Numbers check box to show line numbers in your Visual C# Express or Visual Studio code editor.

Structure of a C# Program
The code in Example 1 is the simplest program you can make in C#. It's purpose is to display a message to the console screen. It has a nice structure which is easy on the eyes compared to other programming languages. Every language has its own basic syntax, which are rules to follow when writing your code. Let's try to explain what each line of code does. Line 1 is a namespace declaration, which declares a namespace used as containers for your codes and for avoiding name collisions. Namespaces will be covered in detail in another lesson. Right now, the namespace represents the name of your project. Line 2 is a { symbol which is called a curly brace. Curly braces defines a code block. C# is a block-structured langauge and each block can contain statements or more valid code blocks. Note that each opening curly brace ( { ) should have a matching closing brace ( } ) at the end. Everything inside the curly braces in Line 2 and 10 is the code block or body of the namespace. Line 3 declares a new class. Classes are a topic of object oriented programming and you will learn everything about it in later lessons. For now, the codes you write should be contained inside a class. You can see that it also has its own pair of curley braces (Line 4 and 9), and everything between them is the class' code block. Line 5 is called the Main method. A method encapsulates a code and then executes it when the method is called. Details in creating a method will be explained in a later lesson. The Main method is the starting point of the program. It means that it is the entry point of execution and everything inside the Main method are the first ones to execute after all the initializations have been completed. Picture the Main method as the front door of your house. You will learn more about the Main method in a later lesson. The Main method and other methods you will create also has a set of curly braces which defines its code block and inside it are the statements that will be executed when the method is called. Statements are another term for a line of code in C#. Each statements must end with a semicolon (;). Forgetting to add the semicolon will result in a syntax error. Statements are located inside code blocks. An example of a statement is the following code (Line 7):
System.Console.WriteLine("Welcome to Visual C# Tutorials!");

This is the code that displays the message "Welcome to Visual C# Tutorials!". We need to use the WriteLine() method and pass the string message inside it. A string or string literal, is a group
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

of characters and they are enclosed in double quotes ("). A character is any letter, number, symbol, or punctuation. For now, the whole line simply means "Use the WriteLine method located in the Console class which is located in the System namespace". More of these will be explained in the upcoming lessons. C# ignores spaces and new lines. Therefore, you can write the same program in Example 1 in just one line. But that will make your code extremely hard to read and debug. Also keep in mind that statements don't necessarily need to be in one line. One common error in programming is adding semicolons at every end of a line even though multiple lines represent a single statement. Consider the following example.
System.Console.WriteLine( "Welcome to Visual C# Tutorials!");

Since C# ignores white space, the above snippet is acceptable. But the following is not.
System.Console.WriteLine( ; "Welcome to Visual C# Tutorials!");

Notice the semicolon at the end of first line. This will produce a systax error because the two lines of code are considered as one statement and you only add a semicolon at the end of a single statement. Some statements such as the if statement can have their own code blocks and you don't have to add semicolons at the end of each block. Always remember that C# is a case-sensitive language. That means you must also remember the proper casing of the codes you type in your program. Some exceptions are string literals and comments which you will learn later. The following lines will not execute becase of wrong casing.
system.console.writeline("Welcome to Visual C# Tutorials!"); SYSTEM.CONSOLE.WRITELINE("Welcome to Visual C# Tutorials!"); sYsTem.cONsoLe.wRItelIne("Welcome to Visual C# Tutorials!");

Changing the casing of a string literal doesn't prevent the code from running. The following is totally okay and has no errors.
System.Console.WriteLine("WELCOME TO VISUAL C# TUTORIALS!");

But what will be displayed is exectly what you have indicated in the string literal. Also notice the use of indention. Everytime you enter a new block, the codes inside it are indented by 1 level.
{ statement1; }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

This makes your code more pleasing to the eyes because you can easily determine which code belongs to which block. Although it is optional, it is highly recommended to use this practice. One great feature of Visual C# Express and Visual Studio is its auto-indent feature so you don't have to worry about indention when entering new blocks.

Saving Your Project and Solution


To save your project and solution, you can go to File > Save All or use the shortcut Ctrl+Shift+S. You can also access this command in the toolbar. It is represented by multiple diskettes.

You will then be prompted with Save Project Window.

The Name field will already be filled with the Name you provided when you created the project. The Location field specifies where you want to save the project. Click the Browse button to select a location in your disk. The Solution Name field specifies the name for the solution. Leave the checkbox checked so VCE will create a folder for your solution located on the specified path in the Location field. Click Save to finish saving. If you simply want to save a single file, go to File > Save (FileName) where FileName is the name of the file to be saved. You can use the shortcut Ctrl+S or click the single diskette icon in the toolbar beside the Save All icon. To open a project or solution file, go to File > Open, or find the folder icon in the toolbar right before the save icon. Browse for the project of solution file. A solution file has an extension name of .sln and a project file has an extension name of .csproj. When opening a solution file, all the linked project to that solution will be opened as well together with the files associated for each of the projects.

Compiling the Program


We learned that our code needs to be compiled first to Microsoft Intermediate Language before we can run it. To compile our program, go to Debug > Build Solution or simply hit F6. This

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

will compile all the projects within the solution. To build a single project, go to the Solution Explorer and right click a project, then select Build.

Rebuild simply recompiles a solution or project. I will not require you to always build the project if you will simply run the program because executing the program (as described next) automatically compiles the project. You can now find the executable program of your project with .exe extension. To find this, go to the solution folder at the location you specified when you saved the solution/project. You will find here another folder for the project, and inside, find the folder named bin, then enter the Release folder. There you will finally find the executable file. (If you can't find it in the Release folder, try the Debug folder).

Executing the Program


When we execute a program, Visual C# Express automatically compiles our code to Intermediate Language. There are modes of executing/running a program, the Debug Mode and the NonDebug Mode. The Non-Debug Mode runs or executes the program disabling the debugging features of the IDE. The program will be executed the same way it will be executed when it is run by the user who will use your program. By running the program in Non-Debug mode you will be prompted to enter any key to continue once the program reaches the end. By default, the command for running in Non-Debug Mode is hidden if you are using the Basic Settings. We need to switch to

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Expert Settings to expose more options in the menu. Go to Tools > Settings then check Expert Settings. Wait for the IDE to finish adjusting settings. You can now run in Non-Debug mode by going to Debug > Start Without Debugging in the menu bar. You can also use the shortcut Ctrl+F5. You will get the following output:
Welcome to Visual C# Tutorials! Press any key to continue . . .

Note that the message "Press any key to continue..." is not part of the actual output. This will only show if you run your program in Non-Debug mode. It is only there to prompt you to press any key to exit or continue the program. The Debug Mode is easier to access and is the default for running programs in Visual C# Express. This mode is used for debugging(testing for errors) which will be discussed in a future lesson. You will be able to use break points and helper tools when exceptions are encountered when your program is running. Therefore, I recommend you to use this mode when you wan't to find errors in your program during runtime. To run using Debug Mode, you can go to Debug > Start Debugging or simply hit F5. Alternatively, you can click the green play button located at the toolbar.

Using Debug Mode, you program will show and immediately disappear. This is because during Debug Mode, once the program reaches the end of code, it will automatically exit. To prevent that from happening, you can use the System.Console.ReadKey() method as a workaround which stops the program and asks the user for an input. (Methods will be discussed in detail in a later lesson.)
namespace MyFirstProgram { class Program { static void Main() { System.Console.WriteLine("Welcome to Visual C# Tutorials!"); System.Console.ReadKey(); } } }

Example 2 - Using the Console.ReadKey() Method Now run the program again in Debug Mode. The program will now pause to accept an input from you, simply hit Enter to continue or exit the program. I would recommend to use the NonDebug mode just so we don't need to add the additional Console.ReadKey() code at the end. From now on, whenever I say run the program, I will be assuming that you use the Non-Debug mode unless otherwise noted. We will use Debug mode when we reach the topic of Exception Handling.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Importing Namespaces
Namespaces in a nutshell are container of codes that you can use in a program. We defined our own namespace named MyFirstProgram but there are thousands of namespaces inside the .NET Framework Class Library. An example is the System namespace which contains codes that are essential for a basic C# application. The Console class we are using to print lines is actually inside the System namespace. We are using the fully qualified name of the Console class which includes the namespace System throughout this lesson.
System.Console.WriteLine("Welcome to Visual C# Tutorials!"); System.Console.ReadKey();

This can be tedious if you will be repeatedly typing this over and over. Fortunately, we can import namespaces. We can use using statements to import a namespace. Here's the syntax:
using namespace;

This is an example of a using statement which imports a namespace and instructs the whole program that you are using the contents of that namespace. So instead of using the following line of code:
System.Console.WriteLine("Hello World!");

We can simply write the following code when we imported the System namespace:
Console.WriteLine("Hello World");

Using statements which imports namespaces are typically placed at the topmost part of your code. Here is the updated version of Example 2 which imports the System namespace.
using System; namespace MyFirstProgram { class Program { static void Main() { Console.WriteLine("Welcome to Visual C# Tutorials!"); Console.ReadKey(); } } }

Example 3 - Importing a Namespace You can still use the full name of a class though if there are other class which has the same name. Namespaces will be discussed in greater detail in another lesson.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You are now familiar with the workflow of creating as well as the basic structure and syntax of a simple C# program. The next lessons will sharpen you knowledge of C# even further.

Using the IntelliSense


Perhaps one of the most important feature of the Visual Studio family is the IntelliSense. IntelliSense serves as an autocompletion tool as well as a quick reference for classes, methods, and many more. I remember using an old IDE for C++ and I have to memorize the neccessary codes I have to use. With IntelliSense, I learn as I type because you actually see a brief description of each components describing how to use them. IntelliSense is activated the moment you type a letter in the Code Editor. Type the following code inside the Main method of the program.
System.Console.WriteLine("Welcome to Visual C# Tutorials!");

Typing the first letter of the statement automatically activates IntelliSense.

IntelliSense gives you a list of recommendations with the most relevant one on the first of the list. You can press tab to accept the selected recommendation. Typing a dot will bring you another list of recommendations. The list is based on all the components that are contained inside the preceding namespace.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

If you stay the selection for a short amount of time, the description about the selected item will show up. This allows you to learn what each item does without going to the full documentation. As you type the code, the list is narrowed down. For example, typing the letter W make IntelliSense to only show items with W's in it.

Typing more letters will narrow the list even further.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

If IntelliSense cannot find something that matches what you are typing, then nothing will be shown. You can press Ctrl while a list is shown to make the list transparent. It's useful when the list box is blocking some of your codes. When working with methods with multiple overloads(versions), you can use the arrow heads to see all the possible overloads of the method.

You will also see the different parameters required by the method and their individual descriptions. Methods and parameters will be discussed in a later lesson. IntelliSense is such a great feature, and for every release of Visual Studio, IntelliSense becomes even more intelligent in suggesting codes for you. It is one of the time-saving tools Visual Studio offers.

Troubleshooting Errors
Most of the time, errors are encountered when creating a program. Almost all of the programs you see today suffered at least one error. Errors can be devastating if not fixed immediately. In C# there are 3 types of errors you can encounter.

Compilation Error - This type of error prevents you from compiling and executing your program. Such errors include syntax errors which means that you violate the rule of the programming language. Another compilation error is using something that does not exist or has not been created yet. Missing files or incomplete information about the project and solution may also cause compilation error. Compilation error will also occur when the program cannot be ran because another process is already using it. Compilation errors are the easiest to fix using Visual Studio tools. Logic Error - This type of error changes the proper logic of the code which defines how the program will behave. This is the hardest error to fix as you need thorough testing to discover this type of error. An example of a logic error is a program that is suppose to add 2 numbers but subtracts them instead. The cause might be the programmer typed a wrong arithmetic symbol during the coding of the program. Exception - This type of error occurs while the program is running. A typical event where this error can occur is if the user provides an invalid input to the program that the program cannot process. Another example is when the program accesses a null (nothing) value.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Visual Studio and Visual C# Express has tools for finding and fixing these types of errors. When typing in the Code Editor, one of the features of these IDE's is to detect possible errors before you even compile the program. Codes that may cause compilation errors have red squiggly lines below them.

Hover your mouse to these squiggly lines to see a description of the error. You might encounter green squiggly lines. They indicate warnings in code but will still allow you to run the program. An example is when you declare a variable and never use it within the program (variables will be discussed later).

Logic errors and exceptions can be handled using the debugging tools and exception handling which will be discussed in a later lesson.

The Error List Window


The Error List window allows you to see all the errors and warnings of the current solution. To open the Error List window, go to View > Other Windows > Error List. By default, the Error List window is located at the bottom area of the IDE. Like the other windows, you can unpin the Error List to enable auto-hide by clicking the pin beside the close button.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You will see the errors and warning reported here whenever errors are detected in your program.

You can see the number of errors and warnings as well as some messages regarding the solution. The Error List consist of multiple columns that provide you in-depth details about the errors. Column Description Description The description of the message File The file where the error is located. Line The line number of the error within the file. Column The column or the horizontal position of the error within the line.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Column Description Project The project name where the error is located. Figure 1 - Error List Window Columns If you run the program with errors, you will be presented with an error window.

Do not check the check box located below this window because this window is useful for notifying us that errors exist when we run the code. Clicking Yes will run the previous version of the program that has no errors. Clicking No will halt execution of the program so that you fix the errors presented in the Error List window. Another great feature of the Error List window is it automatically brings you to the part of your solution that has the error. Simply click an error listed in the Error List and you will be brought to the part of solution where the error exists.

Understanding Errors and Fixing Them


Once all the errors are listed in the Error List window, you need to be able to understand what each error means so you can fix them. The following common errors together with their solution are listed below. The name 'sample' below will be substituted with a different name depending on the error you encounter. Error ; expected The name 'sample' does not exist in the current context. Description Solution You forgot to add a semicolon at Add a ; to fix this error. the end of a statement. It simply means that the name Delete it or declare it in your 'sample' was not declared or code. does not exist in your code. Delete the statement. Assign a value to the variable

Only assignment, call, increment, decrement, and new It means that the code is not a object expressions can be used valid C# statement. as a statement. Use of unassigned local The variable 'sample' is not

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Error variable 'sample'

Solution before the statement that calls or use it. You need to create a class or The type or namespace name It means that there is no type or namespace named 'sample', or 'sample' could not be found (are namespace declared which has a add a reference to your you missing a using directive or name of 'sample' program and import with a an assembly reference?) using statement. This means that the method 'MyMethod()' which is supposed 'MyMethod()': not all code Be sure that all the paths of to return value, does not return a paths return a value code will return a value. value on all the paths of the code. Try using casting or use This means that a variable of conversion methods. If it still Cannot implicitly convert type type2 cannot be converted to yields an error, then a 'type1' to 'type2' type1 without using a cast or conversion for those types is conversion methods. currently not possible. Figure 2 - Some error messages and how to fix them Don't worry if some terms are not clear to you as they will be explained in later chapters. Use the Edit List window's feature of automatically bringing you to the location where the error exists so you can easilly fix it.

Description assigned with an initial value.

Comments
When writing code, you might want to add some text that will serve as a reminder or a note for you or for anyone who will read your code. In C# (and most programming languages), you can do that using comments. Comments are ignored by the compiler and are not part of the actual C# code. Their main purpose is to make it easy for you or to anyone who reads your code to determine the role of your code inside your program. Suppose you want to describe what a particular code is going to do, then you can place a comment above or beside it. It is also used for documentation purposes. Here is an example of a program with a comment:
1 namespace CommentsDemo 2 { 3 class Program 4 { 5 public static void Main(string[] args) 6 { 7 // This line will print the message hello world 8 System.Console.WriteLine("Hello World!"); 9 } 10 } 11}

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Example 1 - Using a Comment Line 7 shows an example of a single line comment. There are two types of comments, single line comments and multiline comments as presented below:
// single line comment /* multi line comment */

Single line comments as the name implies, are comments good for one line only. A single line comment starts with // and everything to its right will be part of the comment. Single line comments are often placed above or to the right of a single line of code. This comments are ideal for describing the functionality of a single line of code. If your comment is longer and requires multiple lines, use the multiline comment. A multiline comment starts with /* and ends with */. Everything between /* and */ will be considered comments. This type of comment is useful for adding details about the program at the source code's header or any long comments that spans multiple lines. There is another type of comment which is called XML comment. It is represented by three slashes (///). It typically functions as a single line comment but it is commonlly used for creating automatic documenation for your code. You will learn more about XML comment and how to use it in a separate lesson.

Escape Sequences
Escape sequences are character combinations starting with a backslash (\) and followed by a letter or digits inserted in a string literal to produce a modified output. For example, to produce a newline when outputting a string, we can use the \n escape sequence.
System.Console.WriteLine("Hello\nWorld!"); Hello World

You can see that once the compiler encounters the \n character, it puts the cursor of the output to the next line and continue showing the output of the rest of the string. In fact, the WriteLine() method automatically adds \n to the end of the string so:
System.Console.WriteLine("Hello World!");

is equivalent to:
System.Console.Write("Hello World!\n");

The Write() method functions the same as the WriteLine() except that it doesn't add a newline to the end f the string.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

The following table shows a list of escape sequences and their corresponding effect: Escape Sequence Output \' Single Quotation mark \" Double quotation mark \\ Backslash \0 Null \a Alert(beep sound) \b Backspace \f Form Feed \n New Line \r Carriage Return \t Horizontal Tab \v Vertical Tab \u Prints a unicode character Figure 1 We used the \ when indicating the start of an escape sequence. Since the backslash gives special meaning to a string literal, we can print a backslash by using the \\ escape sequence.
System.Console.WriteLine("We can print a \\ by using the \\\\ escape sequence."); We can print a \ by using the \\ escape sequence.

The \\ is also useful if you want to output, for example, a file path.
System.Console.WriteLine("C:\\Program Files\\Some Directory\\SomeFile.txt"); C:\Program Files\Some Directory\SomeFile.txt

Since we use the " character to enclose a string, we can print a double quotation using the \" escape sequence.
System.Console.WriteLine("I said, \"Motivate yourself!\"."); I said, "Motivate yourself!".

We can also use the \' to print single quotation marks (').
System.Console.WriteLine("The programmer\'s heaven."); The programmer's heaven.

Tabs can be made by using the \t escape sequence.


System.Console.WriteLine("Left\tRight"); Left Right

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The \r escape sequence causes a carriage return which puts the cursor to the beginning of the current line. Once the cursor is in the beginning of the line, it overwrites any characters it encounters with those following the \r.
System.Console.WriteLine("Mitten\rK"); Kitten

On the example above, the letter K is after the \r. When the \r is encountered, the cursor is brought to the beginning of the line and K overwrites the letter M producing the new word. To print any unicode character, you can use the \u escape sequence. To use the \u, write the 4digit hexadecimal value of the unicode symbol right after the escape sequence. For example, if you want to print the copyright symbol, you can use the \u00A9 escape sequence since 00A9 is the hexadecimal value for copyright symbol.
System.Console.WriteLine("\u00A9");

For a list of hexadecimal values for unicode, go to the link below: http://www.ascii.cl/htmlcodes.htm If the compiler finds an invalid escape sequence, an error will occur. One of the most common errors is when forgetting to use the \\ when a programmer wants to print a slash. As a result, the compiler interprets the very next letter following the \. The other escape sequences are rarely used and is therefore not discussed in this lesson.

String Verbatim
String Verbatim allows you to ignore escape sequences and makes writing strings more natural and readable. When using escape sequences in string literals, you sometimes make a mistake of typing \\ for the "backslash" and type \ instead. This will produce an error because the compiler will think that you are starting an escape sequence and it will read the next character after the \ and process it. If it doesn't find a matching escape sequence, then it will issue an error. Consider the following example:
System.Console.WriteLine("I want to have a cat\dog as a birthday present."); //Error

Although it would be proper to use the / instead as in "cat/dog" in the example above, I intentionaly used backslash for demonstration-this is not literature lesson after all. The compiler will issue an error and tell you that it did not recognize the escape sequence \d clearly because no such escape sequence exist. It will be worse if the next character following the backslash is something that the compiler can recognize such as \n as seen in the following example:
System.Console.WriteLine("Answer with yes\no:");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Answer with yes o

Using String Verbatim to Ignore Escape Sequences


We use string verbatim in certain situations where you don't want your backslashes to trigger an escape sequence. The syntax for string verbatim is simple. Just prefix the string literal with the @ symbol.
System.Console.WriteLine(@"I want to have a cat\dog as a birthday present."); I want to have a cat\dog as a birthday present.

String verbatim is commonly used when you are trying to output directories as string. Because directories contain a lot of backslashes, it would be justifiable to use string verbatim rather than using double backslash.
System.Console.WriteLine(@"C:\Some Directory\SomeFile.txt"); C:\Some Directory\SomeFile.txt

If you want to print double quotations, simply use two double quotations.
System.Console.WriteLine(@"Printing ""double quotations""..."); Printing "double quotations"...

Avoid using string verbatim and escape sequences at the same time as it will also print the escape sequences in the output.

Using String Verbatim to Preserve Formatting of Strings


You can also use string verbatim to print multiline strings without the user of \n escape sequence. For example, if we are to print the following message:
C# is a great programming language and it allows you to create different kinds of applications.

Then we have to write it in C# as follows:


System.Console.WriteLine("C# is a great programming language and\n" + "it allows you to create different\n" + "kinds of applications.");

Notice the use of \n at the end of each line. This is to seperate them in different lines as shown in the output sample of the message. The string was also divided into three just so we can save space. The + operator is used to combine the strings so that the three string literals will be combined into one. With string verbatim, we can make our lives easier when printing multiple lines of text.
System.Console.WriteLine(@"C# is a great programming language and

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

it allows you to create different kinds of applications.");

Notice that we with string verbatim, we can use one continuous string and it will be printed exactly the same as how it was typed in the editor. That's why the second and third lines has no indention because if we indent them, the output will also be indented. Be carefull to use string verbatim. Although it is useful in many circumstances, you should stick to the usual way of printing strings with escape sequences. Only use string verbatim when neccessary.

Variables
A variable is basically a storage in the computer's memory where you can put a value that will be used by your program. Picture it as a container that holds your data. The contents of the container can be removed or changed anytime. The variable has a name, which identifies it among other variables and allows you to access the value of the variable. It has an address which determines where in the memory it resides. It has a value which is either assigned by the user or a result of a calculation although a variable can have a value of null or nothing. A variable has a data type, which signifies what kind of data the variable contains. A variable has a lifetime which determines how long in the program the variable is usable. And finally, a variable has scope which tells you where in a program the variable is available for use. We use variables as temporary storage of data or values. When creating programs, we need means of storing results, values, or input data from user. This is the role of the variable. The variable got its name from the term variability which means changing or don't have a consistent state. This is because we can assign and change the value of a variable whenever it is neccessary. Variables are temporary and will only be usable when the program is running. When you close your program, values stored in variables are erased. The name of a variable is called an identifier. The variables content is accessed or inserted using its identifier. When naming variables in C#, there are some rules you must follow.

A variable should start with an alphabet (a-z or A-Z) It cannot contain odd characters such as #, ?, ^, $. You cannot use any of the reserved words in C# as names for your variables. A variable name cannot contain spaces.

Variable names are also case-sensitive. C# is a case-sensitive language, which means, a and A are two different characters. Two variables named myNumber and MyNumber are two different variables because the first one starts with 'm' and the other one starts with 'M'. You cannot declare a variable which is exactly the same as the name of another variable within the same scope. Scope means the block of code a variable is available for use. You will learn more about scope in a later lesson.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

A variable has a data type which is the format or kind of data that it is expected to hold. Data type is used to allow a computer to describe what kind of data it holds and what operations you can do to it. Most common data types are int, double, string, char, float, decimal and a lot lot more for storing different kinds of data depending on the situation. For example, if you are expecting a variable to hold a whole number, you will give it a type of int. If you are expecting a variable to hold string literals or message, you would want to give it a data type of string. More complex data types can be made in C# by making your own classes or structures.

Simple Types
Simple types are data types which include numbers, characters and strings, and boolean values. They are called primitive data types in other languages because you use them to build complex types such as classes and structures. Simple types contain clearly defined set of values and can store a fixed range of data. They are the fundamental building blocks of your application. Each simple type is mapped to a .NET type thanks to .NET's Common Type System. It makes data types from different languages to be considered as one by .NET. For example if you use the int data type, you are actually using the .NET type System.Int32. The following table shows some of the available simple types that you can use for storing numbers. Type .NET Type Value Range sbyte System.SByte Integer between -128 and 127 byte System.Byte Integer between 0 and 255 short System.Int16 Integer between -32768 and 32767 ushort System.UInt16 Integer between 0 and 65535 int System.Int32 Integer between -2147483648 and 2147483647 uint System.UInt32 Integer between 0 and 4294967295 Integer between -9223372036854775808 long System.Int64 and 922337203685477807 ulong System.UInt64 Integer between 0 and 18446744073709551615 Figure 1 You might notice the u at the beginning of some data types such as ushort. It means that the number it will store is "unsigned" and you can only store positive numbers(and 0) in them. They store larger values as a reward for forbidding negative values. Note that byte is the unsigned version of sbyte but it was not named usbyte. The next table shows simple types that can store "floating numbers" or numbers with fractional part or decimal points such as 1.5.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Type .NET Type Approximate Range Precission float System.Single 1.5E-45 to 3.4E38 7 digits double System.Double 5.0E-324 to 1.7E308 15 - 16 digits (-7.9 x 1028) / (100 to 28) to decimal System.Decimal 28 - 29 significant digits (7.9 x 1028) / (100 to 28) Figure 2 We used the shorthand version of scientific notations. Instead of writing 1.5 x 10-45, we wrote 1.5E-45 instead. There are other types of simple data types which are used for storing non-numerical data. They are shown in Figure 3. Allowed Values Single Unicode character, stored as an integer char System.Char between 0 and 65535 bool System.Boolean true or false string System.String A sequence of characters Figure 3 The char datatype is used for storing single unicode character. Characters must be enclosed by single quotation marks ('a'). The bool datatype can store true or false which is used mostly when making decisions in a program. The string is used for storing a sequence of characters such as a message. Values stored in string must be wrapped between quotation marks ("message") so it can be distinguish as a string by the compiler. Type .NET Type

Using Variables
Variables in C# are containers inside the computer's memory where you can place the data you need for your program. The term "variable" got its name from the fact that variables represent values that change. The data stored in these variables have different types called data types which determines the type of data a variable can store. For example, a variable with an int data type can only store whole numbers and a variable with a string data type can store string literals. Example 1 demonstrates how you can declare and assign values to the variables.
1 using System; 2 3 namespace VariableDemo 4 { 5 class Program 6 { 7 public static void Main() 8 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37}

//Declare variables int num1; int num2; double num3; double num4; bool boolVal; char myChar; string message; //Assign values to variables num1 = 1; num2 = 2; num3 = 3.54; num4 = 4.12; boolVal = true; myChar = 'R'; message = "Hello World!"; //Show the values of the variables Console.WriteLine("num1 = {0}", num1); Console.WriteLine("num2 = {0}", num2); Console.WriteLine("num3 = {0}", num3); Console.WriteLine("num4 = {0}", num4); Console.WriteLine("boolVal = {0}", boolVal); Console.WriteLine("myChar = {0}", myChar); Console.WriteLine("message = {0}", message); } }

Example 1 - Variables in Action


num1 = 1 num2 = 2 num3 = 3.54 num4 = 4.12 boolVal = true myChar = R message = Hello World!

Declaring Variables
Lines 8-14 declared variables with different data types and names. We declare variables so the program will know them and what data each of them can contain. It's like introducing those variables to the program. Always keep in mind that you need to declare variables first before you can use or assign values to them.
int num1; int num2; double num3; double num4; bool boolVal; char myChar; string message;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

When declaring variables, you need to indicate the data type followed by the name of the variable terminated by semicolon. Declaration of variables is simply called declaration. The following is the syntax of declaring a variable:
data_type identifier;

The date_type is the data type of the variable such as int, double or char. The identifier is the valid name of the variable and is used to access the variables content or add a new value to it. You can also declare multiple variables with the same data type in just one line. It uses the following syntax:
data_type identifier1, identifier2, ... indentifierN;

Take a look at the following example:


int num1, num2, num3, num4, num5; string message1, message2, message3;

The above declaration statements declares five integer variables and three string variables. We simply indicate the data type and a comma-separated list of identifiers.

Naming Variables
The identifier must start with an alphabet or an underscore, followed by alphabet or numbers. You cannot use special characters such as #, %, &, or start the identifier name with a number such as 2numbers. Identifiers can't contain spaces. As a workaround for multiple word names, you can use underscore(_) instead of space (you can't use the - sign). The following are examples of valid variable names.
num1 num2 name myNumber myChar counter studentCount average sum total amountDue isLeapYear first_name last_name color_of_car _minimum _maximum _age

The following are examples of invalid names for identifiers.


123 123abc my number #numbers# $money this&that #ofstudents first name last name 1abc2 ty.np 1:00

If you look at the examples of valid variable names, you will notice a convention used when naming them. Camel Casing is a naming practice which states that, the first letter of the first word should be a small letter. Each succeeding letters are small letters. For multiple-word variables, each succeeding word must have their first letter capitalized. For example, the identifier myNumber contains the words "my" and "number". Notice that the first letter of the word number in the indentifier is captialized. Another example is numberOfStudentsWhoGraduated which is quite a long name that uses camel casing. Notice how

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

each words after the first word has their first letter capitalized. More naming conventions will be introduced to you as we progress to future lessons.

Variable Scope
Notice that the variables are declared inside the block of the Main method. This limits these variables to be only accessible or usable inside the Main method. This is called scope which determines where in the code, variables can be used. Once the program reaches the end of the Main method, these variables go out of scope and becomes unusable while the program is running. There are more types of scopes. You will learn more about scopes in a later chapter. Determining the scope of variables is important so you can know where in your code can you use those variables. Another reason is that, two or more variables within the same scope cannot have an exact same name or identifier. The following will produce an error:
int num1; int num1;

This is a typical error and you will get an error message when compiling saying "A local variable named 'num1' is already defined in this scope". But because C# is case sensitive, you can provide the same names of variables as long as they have different cases. The following three variables are actually three different variables and will be accepted by the compiler.
int num1; int Num1; int NUM1;

Initializing Variables
You can assign values to variables immediately after they have been declared in the program. This is called initialization. The following is the basic syntax of intializing a variable with a value.
data_type identifier = value;

For example:
int myNumber = 7;

You can also initialize multiple variables. Simply seperate them with a comma.
data_type variable1 = value1, varaible2 = value2, ... variableN, valueN; int num1 = 1, num2 = 2, num3 = 3;

It is important to know the difference of declaration and initializaiton. Declaration simply declares the method by specifying the data type and the name of the identifier. If you try to use an undeclared variable, then you will receive an error message "Use of unassigned local variable 'myVariable'" where myVariable is the name of the unassigned variable. Initialization is similar

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

to declaration but values are assigned to the declared variables. This gives a variable an "initial value" hence the term initialization.

Assigning Variables with Values


Assigning a value to a variable is placing a value inside the variable. Think of it as putting some contents to an empty container. When assigning variables with a value, you use the following syntax.
variable = value;

You indicated the name of the variable followed by the assignment operator which is represented by the = sign then followed by the value to be assigned to the variable. The left of the assignment operator is often called an L-Value (left value) while the right side of the assignment operator is often called R-Value (right value). Lines 19-25 of Example 1 assigns values to each variables that we have declared.
num1 = 1; num2 = 2; num3 = 3.54; num4 = 4.12; boolVal = true; myChar = 'R'; message = "Hello World!";

Note that we cannot assign values to variables that has not been declared yet. You can only assign values to variables that are valid and can be accepted by the variable depending on its data type. For example, num1 and num2 are both declared int so they can only accept whole numbers as values. boolVal was declared bool so it can only accept either values true or false. message was declared string so it can accept a string literal. Failing to assign proper values can lead to errors. You will learn in a later lesson that some datatypes are related.

Format Placeholders
You noticed the new version of the WriteLine() method (lines 26-32). It now accepts two arguments. Arguments are the information needed by the method to supplement its job. Arguments are seperated by a comma. The first argument accepted by WriteLine() is the formatting string and the second one is the value to be used by the formatting string. If you look closely, the formatting string has {0}. They are called format placeholders. This will be substituted by the value of the next argument. For example, the placeholder {0} means that it will be replaced by the value of the first argument following the formatting string. The new version of WriteLine method can actually accept any number of arguments, with the first one being the string containing the format placeholders, and the following arguments are the values that will substitute the placeholders. For example, the following uses 4 placeholders.
Console.WriteLine("The values are {0}, {1}, {2}, and {3}.", value1, value2, value3, value4);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Format placeholders start with index 0. The number of placeholders must match the number of arguments following the formatting string. For example, if you have four placeholders as shown above, then you must provide four values right after the formatting string. The first placeholder {0} in the formatting string will be substituted by the second argument. The second placeholder {1} will be substituted by the third argument, and so on. It might be hard for beginners to understand this concept at first, but you will look at more examples of these in later lessons.

Constant Variables
Constant variables, or simply constants, are variables whose value cannot be changed once initialized. Given that fact, constants can only do initialization since forgetting to initialize a constant will produce an error. Constants must be assigned with an initial value, and after that, the value can never be changed at runtime. To declare a variable as constant, simply use the const keyword. Constant's name should be in all caps as part of C#'s naming convention. It is not required but it allows you to easily identify which are the constants. Here's the syntax for defining a constant.
const data_type identifier = initial_value;

Heres an example of using a constant.


namespace ConstantsDemo { class Program { public static void Main() { const int NUMBER = 1; NUMBER = 10; //ERROR, Cant modify a constant } } }

You can see that assigning a value to a constant once it has been declared leads to an error. Another thing to note is that you cannot initialize constants with variables who's value is not known during compilation. For example, doing the following produces an error.
int someVariable; const int MY_CONST = someVariable;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You might be wondering why do we need to use constants. If you are certain that a value will never change during runtime, make the variable constant. This will add a little bit of performance improvement to your program.

Implicit Conversion
Implicit conversion of variables is a kind of conversion that is automatically done by the compiler. A variable of one data type can be implicitly converted to another datatype provided that its content can be handled by the type it will be converted to. For example, a byte datatype can hold values from 0 to 255. You convert this variable to an int type like this:
byte number1 = 5; int number2 = number1;

We initialize the value of number1 to 5 and use its value to initialize number2. The int variable number2 can hold the byte value 5 because int data type can hold the value 5 without any problems as it falls within the range of values an int can hold. Therefore, number1 which is a byte, is implicitly converted to number2 which is an int. What if we switch the types of the two?
int number1 = 5;

byte number2 = number1;

This time, you will receive an error. Even though the value 5 of the int variable number1 falls in the range of values a byte can hold (1 - 255), the byte uses less memory than the int. The byte data type contains 8 bits or 8 digits of binary value while int contains 32 bits or binary digits. A binary number is a number that is composed of 0's and 1's. For example, we see the number 5 as 5 but the computer interprets it as a binary number 101. So when we store 5 in a byte variable, it will be represented as this:
00000101

And if we place it in an int, the binary representation of it will be as follows:


00000000000000000000000000000101

Therefore, placing an int value to a byte variable is like trying to shoot a bowling ball in a golf hole. You can still assign a byte variable with an int value by using explicit conversion which is discussed in the next lesson. Another thing to take note about is that you cannot convert floating point numbers or numbers with decimal part implicitly into a number that accepts a whole number such as int. This is because of the reason that you will lose the fractional part of the floating-point value.
double number1 = 5.25; int number2 = number1; //Error

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can also convert a char into a ushort because these two types has the same range of values they can store. Although each of them are interpreted differently by the compiler. The char is interpreted as a character and a ushort is interpreted as a number.
char charVar = 'c'; ushort shortVar = charVar; Console.WriteLine(charVar); Console.WriteLine(shortVar); c 99

Below is a table showing the numeric conversions the compiler can do implicitly: Source Type Can Safely Be Converted To byte short, ushort, int, uint, long, ulong, float, double, decimal sbyte short, int, long, float, double, decimal short int, long, float, double, decimal ushort int, uint, long, ulong, float, double, decimal int long, float, double, decimal uint long, ulong, float, double, decimal long float, double, decimal ulong float, double, decimal float double char ushort, int, uint, long, ulong, float, double, decimal Another thing to note, often, there is an ambiguity to what would be the type of a data. For example, how can we know if number 7 is int, uint, long, or ulong? We can append characters to the end of the number like this:
uint number1 = 7U; long number2 = 7L; ulong number3 = 7UL;

By default, the compiler will treat it as an int if no character is appended to the number. Also note that the casing doesn't matter and you can use u,l and ul. By default, a number with a decimal point is considered as double. You can indicate the it is a float by using the F character, and M if you want to treat it as a decimal.
double number1 = 1.23; float number2 = 1.23F; decimal number3 = 1.23M;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Explicit Conversion
Explicit conversion lets you force the program to convert a data into another data type if it doesn't support implicit conversion. Explicit conversion has a tendency of losing or resulting to a modification of value so be cautious when using this type of conversion. We do an explicit conversion in C# by doing a cast. Casting is just another term for explicit conversion and it follows the following syntax:
datatypeA variableA = value; datatypeB variableB = (datatypeB)variableA;

datatypeA is the type of the source data. datatypeB is the destination type. When doing a cast, we enclosed the target data type between parenthesis followed by the variable of another data type that we are going to convert. For example, we saw that you cannot implicitly convert an int into a byte. It's like downgrading the int variable. But we can use casting to have a successful conversion.
int number1 = 5; byte number2 = (byte)number1;

If you compile this code, you will not receive an error. We have "downgraded" an int data into a byte data. As I have said earlier, there are events where you can lose the originality of data you are converting. An example is when converting a floating-point number such as double in an int which can only hold whole numbers.
double number1 = 5.25; int number2 = (int)number1; Console.WriteLine(number2); 5

The code above will give as an output of 5 instead of 5.25. The fractional part or the part after the decimal point is lost because int data type cannot hold it. Another thing to keep in mind is if you are converting a variable containing a value which is not within the range of the values a target variable can hold, then odd results will be encountered. Consider the following code.
int number1 = 300; byte number2 = (byte)number1; Console.WriteLine("Value of number2 is {0}.", number2); Value of number2 is 44.

The output below shows that converting the int value 300 into byte resulted to 44. Byte can only hold a value 0 to 255. So why did we get 44 instead of 300? This has something to do with the number of bits each type can hold. byte can hold 8 bits (0's or 1's) and int can hold 32. If we look at the binary representation of the two values, we can see why we got 44.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

300 = 00000000000000000000000100101100 255 = 11111111 44 = 00101100

The representation above shows that the max value of byte which is 255 takes up eight bits (11111111) so only the first eight bits of the int value is transfered to the byte variable which are (00101100) or 44 in decimal representation. Fitting a data into a variable that cannot hold the value results to an overflow. Overflows can also occur if the result of a methematical expression is assigned to a variable that cannot hold a result. This is called arithmetic overflow.
byte sum = (byte)(150 + 150);

Even though we will lost some data because of the conversion, the compiler still accepts our code. To make the program issue an error when an expression results to an overflow, you can use the checked keyword.
int number1 = 300; byte number2 = checked((byte)number1); Console.WriteLine("Value of number2 is {0}.", number2); Unhandled Exception: System.OverflowException: Arithmetic operation resulted in an overflow ...

The program will throw a System.OverflowException which simply means that an overflow was detected. This will prevent the program to progress.

Conversion Using the Convert Class


The .NET Framework has a static class available that can be used for converting values from one type to another. The Convert class has some methods that can be used to convert to different target datatypes. You must import the System namespace before using the Convert class. Below shows the table of those methods Command Result

Convert.ToBoolean(val) val converted to bool Convert.ToByte(val) val converted to byte Convert.ToChar(val) val converted to char Convert.ToDecimal(val) val converted to decimal Convert.ToDouble(val) val converted to double Convert.ToInt16(val) val converted to short Convert.ToInt32(val) val converted to int Convert.ToInt64(val) val converted to long Convert.ToSByte(val) val converted to ushort Convert.ToSingle(val) val converted to float

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Command Convert.ToString(val) Convert.ToUInt16(val) Convert.ToUInt32(val) Convert.ToUInt64(val)

Result val converted to string val converted to ushort val converted to uint val converted to ulong

Figure 1 - Conversion Methods The following program shows you an example of converting variables.
double x = 9.99; int convertedValue = Convert.ToInt32(x); Console.WriteLine("Original value is: " + x); Console.WriteLine("Converted value is: " + convertedValue); Original value is: 9.99 Converted value is: 10

The value of val can be any data type but make sure that it can be converted to the target data type. If these commands cannot handle the conversion, then the compiler will tell you about this by issuing an error.

Expressions and Operators


Modern programming languages has operators which is one of the common elements of a programming language. C# offers different operators like mathematical operators, assignment operators, and comparison operators. There are different kinds of operators in C# and you might not be familiar to some of them. Basic operators are what we use for mathematical calculations such as addition and substraction. Then there are more complex ones use for combining two comparison expressions. There are three types of operators in C#:

Unary - requires a single operand Binary - requires at least two operands Ternary - requires three operands

The different kinds of operators in C# that this section will discuss includes the following:

Mathematical Operators Assignment Operators Comparison Operators Logical Operators Bitwise and BitShift Operators

Mathematical Operators
Bsc ABDULRAHIM ALI ATHUMAN

COMPILED BY:

C# has available operators for use in mathematical calculations. By combining operators and operands, we have an expression which is how C# makes calculations. Here is a table of available mathematical operators in C#. Result var1 is assigned with the sum of var2 and var3. var1 is assigned with the difference of var2 and var3. var1 is assigned with the product of var2 and var3. var1 is assigned with the quotient of var2 and var3. var1 is assigned with the remainder resulted from the division of var2 and var 3. var1 is assigned with the value of var2 var1 is assigned with the value of var2 multiplied by -1.

Operator Category Example Expression + * / % + Binary Binary Binary Binary Binary Unary Unary var1 = var2 + var3; var1 = var2 - var3; var1 = var2 * var3; var1 = var2 / var3; var1 = var2 % var3; var1 = +var2; var1 = -var2

Figure 1 - Mathematical Operators

The example above uses numeric types. But using this on other types such as string can have different results. Likewise, adding two char will result on the compiler converting their value to their respective numerical equivalents. If the + operator is used with string data, it will concantenate the two strings and combine them into one. Another set of operators in C# are the increment and decrement operators. These operators increases or decreases the value of a variable by 1. This operators are often used for looping. Result var1 is assigned the value of var2 + 1. var2 is incremented by 1. var1 is assgine the value of var2 - 1. var2 is decremented by 1. var1 is assigned the value of var2. var2 is incremented by 1. var1 is assigned the value of var2.. var2 is decrementday by 1.

Operator Category Example Expression ++ -++ -Unary Unary Unary Unary var1 = ++var2; var1 = --var2; var1 = var2++; var1 = var2--;

Figure 2 - Increment and Decrement Operators

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Note that the position of the two operators determines the effect of the calculation. If the operator is a prefix to the variable, the incrementation or decrementation took place first before being assigned to var1. Contrast to when you place it at the end of var2, the value assigned to var1 is the value of var2, the incrementation or decrementation for var2 will happen after it's value is assigned to var1. We will now try what we learned by creating a new program that tests the mathematical operators of C#.

using System; 1 public class Program 2 { 3 public static void Main() 4 { 5 //Variable declarations 6 int num1, num2; 7 string msg1, msg2; 8 9 //Assign test values 10 num1 = 5; 11 num2 = 3; 12 13 //Demonstrate use of mathematical operators 14 Console.WriteLine("The sum of {0} and {1} is {2}.", num1, num2, (num1 15+ num2)); 16 Console.WriteLine("The difference of {0} and {1} is {2}.", num1, 17num2, 18 (num1 - num2)); 19 Console.WriteLine("The product of {0} and {1} is {2}.", num1, num2, 20 (num1 * num2)); 21 Console.WriteLine("The quotient of {0} and {1} is {2:F2}.", num1, 22num2, 23 ((double)num1 / num2)); 24 Console.WriteLine("The remainder of {0} divided by {1} is {2}", num1, 25num2, 26 (num1 % num2)); 27 28 //Demonstrate concatenation on strings using the + operator 29 msg1 = "Hello "; 30 msg2 = "World!"; 31 Console.WriteLine(msg1 + msg2); } }

Example 1
The sum of 5 and 3 is 8. The difference of 5 and 3 is 2. The product of 5 and 3 is 15. The quotient of 5 and 3 is 1.67. The remainder of 5 divided by 3 is 2 Hello World!

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The program demonstrates the expected results for each expressions. Again, we use the overloaded version of the Console.Writeline() to make it easier to write and format. There is one odd thing you might notice when dividing the two integers. If we divide two integers, it will yield another integer. That would drop out all the fractional part of the result and give us only a whole number. In line 22, we convert at least one of the operand to double to get the right result. Then we format the result to only show 2 decimal places using {2:F2}. F means fixed and 2 means the number of decimal places to include. Note that the number is rounded. The statement is too long so we split it into two lines. C# ignores newlines, tabs and white spaces so there is no problem about this.

Line 29 shows string concatenation using the + operator on strings. When we used the + operator for the two string data, we get a different result. Adding "Hello " and "World!" gives us "Hello World!". Take note of the extra space added to the end of the first word. Omitting this will also omit the space between the two words in the final output.

Assignment Operators

There is another set of operators in C# and they are called assignment operators. They are use to modify the value of the left operand depending on the right operand. The table shows assignment operators and their functionality.

Operator Example Expression Result = var1 = var2; var1 is assigned a value of var2. var1 is assigned the value that is the sum of += var1 += var2; var1 and var2 var1 is assigned the value that is the difference of -= var1 -= var2; var1 and var2 var1 is assigned the value that is the product of *= var1 *= var2; var1 and var2. var1 is assigned the value that is the result of /= var1 /= var2; dividing var1 by var2 var1 is assigned the value that is the remainderr %= var1 %= var2; when var1 is divided by var2 Figure 1 - Assignment Operators

The += can also be used for concatenating strings. The table above shows that the assignment operators are actually a short hand of doing calculations on two operands. Consider var1 += var2, the original form of it would be var1 = var1 + var2. It would be more efficient to use assignment operators specially when you have very long variable names. The following program shows how to use assignment operators and their effect on variables. Since the concept for each of the assignment operators is the same, I'm not going to show all of them.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

1 using System; 2 3 public class Program 4 { 5 public static void Main() 6 { 7 int number; 8 9 Console.WriteLine("Assigning 10 to number..."); 10 number = 10; 11 Console.WriteLine("Number = {0}", number); 12 13 Console.WriteLine("Adding 10 to number..."); 14 number += 10; 15 Console.WriteLine("Number = {0}", number); 16 17 Console.WriteLine("Subtracting 10 from number..."); 18 number -= 10; 19 Console.WriteLine("Number = {0}", number); 20 } 21}

Example 1
Assigning 10 to number... Number = 10 Adding 10 to number... Number = 20 Subtracting 10 from number... Number = 10

The program uses three of the assignment operators. First, we declared a variable that will hold the value for manipulation. We then assign a value of 10 using the = operator. We added 10 to the number by using the += operator. Finally, we subtracted 10 from the number using = operator.

Comparison Operators
C# has comparison operators which are used when comparing values or references of variables. These operators yield boolean results. Values yielded by comparison expressions are either true if the comparison is in fact true, and false if the comparison is false. These comparison operators are commonly used in if statements and testing if the loop should continue or stop. The comparison operators are the key to make your programming decide and think. Below shows a list of comparison operators in C#. Operator Category == Binary Result var1 is assigned true if var2 is var1 = var2 == var3 equal to the value of var3, Example

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Operator Category

Example

Result

!=

Binary

<

Binary

>

Binary

<=

Binary

>=

Binary

false otherwise var1 is assigned true if var2 is not var1 = var2 != var3 equal to the value of var3, false otherwise var1 is assigned true if var2 is var1 = var2 < var3 less than the value of var3, false otherwise var1 is assigned true if var2 is var1 = var2 > var3 greater than the value of var3, false otherwise var1 is assigned true if var2 is var1 = var2 <= var3 less than or equal to the value of var3, false otherwise var1 is assigned true if var2 is var1 = var2 >= var3 greater than or equal to the value of var3, false otherwise

Figure 1 - Comparison Operators The program below demonstrates the functionality of comparison operators.
using System; 1 namespace ComparisonOperators 2 { 3 class Program 4 { 5 static void Main() 6 { 7 int num1 = 10; 8 int num2 = 5; 9 10 Console.WriteLine("{0} 11num2); 12 Console.WriteLine("{0} 13num2); 14 Console.WriteLine("{0} 15 Console.WriteLine("{0} 16 Console.WriteLine("{0} 17num2); 18 Console.WriteLine("{0} 19num2); 20 } } }

== {1} : {2}", num1, num2, num1 == != {1} : {2}", num1, num2, num1 != < {1} : {2}", num1, num2, num1 < num2); > {1} : {2}", num1, num2, num1 > num2); <= {1} : {2}", num1, num2, num1 <= >= {1} : {2}", num1, num2, num1 >=

Example 1

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

10 10 10 10 10 10

== != < > <= >=

5 5 5 5 5 5

: : : : : :

False True False True False True

We first create two variables that will be compared. We initialize them with values. Then, we used each comparison operators to compare the two variables and prints the result. It is important to note that when doing comparisons, you must use the == operator instead of the = operator. The = operator is the assignment operator and an expression such as x = y is read as assign the value of y to x. The == operator is the equality operator which tests for equality of two values so an expression such as x == y is read as x is equal to y.

Logical Operators
Logical operators typically involves boolean values and yields boolean results. There are often use to create multiple or complex conditions. We have learned that a boolean value can either be true or false. We can use the different logical operators available in C#. Suppose that var2 and var3 are boolean values. Operator Name Category Example && Logical AND Binary var1 = var2 && var3; || Logical OR Binary var1 = var2 || var3; ! Logical NOT Unary var1 = !var1; Figure 1 - Logical Operators

Logical AND Operator (&&)


An expression using the logical AND operator evaluates to true if both operands are true. If either or both of the operands are false, the expression evaluates to false. The following shows the truth table for the logical AND operator. X Y X && Y true true true true false false false true false false false false Figure 2 - Logical AND && Truth Table

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

To better understand the effect of logical AND, remember that it can only yield true if both operands are true. All other combinations yields false. When using logical AND operator, the moment that the program sees that the first operand is false, then the result is automatically false. You can use the logical AND operator on boolean expressions such as those using comparison operators. For example, the following expression assigns true to the result if age is greater than 18 and salary is less than 1000.
result = (age > 18) && (salary < 1000);

The logical AND operator is also useful when specifying range of values. For example, the mathematical notation 10 <= x <= 100 means the x can have a value of range 10 to 100. To test if a number falls at a certain range, we can simply use the logical AND operator.
inRange = (number <= 10) && (number >= 100);

You will see more useful examples of the logical AND in a later lesson.

Logical OR Operator (||)


The logical OR operator evaluates to true if either or both of the operators are true. It is the opposite of logical AND which evaluates to false if either or both of the operands are false. The following shows the truth table for the logical OR operator. X Y X || Y true true true true false true false true true false false false Figure 3 - Logical OR || Truth Table As you can see, an experssion with a logical OR operator only evaluates to false if both of the operands are false. As an example, the following code assigns true to the result if the student's final grade is greater than or equal to 75 or his final exam's grade is equal to 100.
isPassed = (finalGrade >= 75) || (finalExam == 100);

We will see some practical examples of using the logical OR operator in later lessons.

Logical NOT Operator (!)


Unlike the other two logical operators, the logical NOT operator is a unary operator and only requires one operand. The logical NOT operator negates a boolean expression or value. If the

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

expression or value is true, it is turned to false, and if false, it is turned to true. The following shows the truth table for the logical NOT operator. X !X true false false true Figure 4 - Logical NOT ! Truth Table The following code assings true to result if age is not greater than or equal 18.
isMinor = !(age >= 18);

We will later see a more practical use of the ! operator in a later lesson.

Bitwise and Bitshift Operators


The bitwise operators allow you to manipulate different kinds of data in their binary form. In order to follow this lesson, it is recommended that you know what binary system is and how to convert decimal numbers to binary. Binary system is what the computer actually uses since it represents everything in on or off state. On is represented by 1 and off is represented by 0. Therefore, binary numbers can only be 1's or 0's. Binary numbers are also called Base 2 numbers and decimal numbers are Base 10. A bit represents one binary digit. A byte represents 8 bits. The int for example, uses 32 bit or 4 bytes to store its content. It means, it represents the numbers using 32 digits of 0's and 1's. For example, the number 100 when stored in an int variable is read by the computer as this:
000000000000000000000000000001100100

The decimal number 100 is equivalent to 1100100 in binary. But since it is only 7 digits, we added 29 more digits to the left of it to fill the 32 bits required by int. Note that we read binary numbers from right to left so the beginning digit is actually the last one. We can then use the bitwise operators to the binary versions of the numbers or data. You don't have to convert them to binary as the computer automatically sees them as binary numbers. The following shows the bitwise operators you can use. Operator Name Category Example & Bitwise AND Binary x = y & z; | Bitwise OR Binary x = y | z; ^ Bitwise XOR Binary x = y ^ z; ~ Bitwise NOT Unary x = ~y; &= Bitwise AND Assignment Binary x &= y; | Bitwise OR Assignment Binary x |= y;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Operator Name Category Example ^= Bitwise XOR Assignment Binary x ^= y; Figure 1 - Bitwise Operators Bitwise operators are commonly used in bitwise comparisons of Flags enumerations which you will learn in several advance lessons in this site.

Bitwise AND (&) Operator


The bitwise AND operator does the AND operation to every bit of the binary representation of a value. When doing an AND operation (or ANDing) on two binary numbers, the result is 1 if both binary numbers are 1, and 0 otherwise. The AND operation has the following truth table. X Y X AND Y 1 1 1 1 0 0 0 1 0 0 0 0 Figure 2 - AND Truth Table As a demonstration of using the bitwise AND operator, let's take a look at the following code snippet.
int result = 5 & 3; Console.WriteLine(result); 1

We used the bitwise AND to the values 5 and 3 and as you can see, it yields the value 1. Let's take a look at how the computer came up with that result.
5: 00000000000000000000000000000101 3: 00000000000000000000000000000011 -----------------------------------1: 00000000000000000000000000000001

We first covert 5 and 3 to their binary equivalents. SInce int has 32-bits, we added leading 0's to fill the 32 slots. We then use the AND operation to each digit. By looking at the truth table in Figure 2, we came up with the binary representation of the number 1. The assignment version of the bitwise AND operator is also available.
myNumber &= 5;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The above statement applies the bitwise AND operator to whatever the value of myNumber and to the value of the right opearand (in this case 5). The result is then assigned to myNumber.

Bitwise OR (|) Operator


The bitwise OR operator uses the OR operation on every bit of the binary representation of two values. The result of an OR operation is shown in the following truth table. X Y X OR Y 1 1 1 1 0 1 0 1 1 0 0 0 Figure 3 - OR Truth Table The OR operation yields 0 only if both operands are 0. If at least one value is 1, then it automatically yields 1. Let's take a look at an example of using this operator.
int result = 7 | 9; Console.WriteLine(result); 15

In binary representation, you can see how the computer yields 15 when we used the bitwise OR operator on the two values.
7: 00000000000000000000000000000111 9: 00000000000000000000000000001001 ----------------------------------15: 00000000000000000000000000001111

We looked at the truth table in Figure 3 to determine the results of doing the OR operation on each digit of their binary representations. We came up with binary number 1111 which is equivalent to 15. The assignment version of the bitwise OR operator is also available.
myNumber |= 5;

The above statement applies the bitwise OR operator to whatever the value of myNumber and to the value of the right operand (in this case 5). The result is then assigned to myNumber.

Bitwise XOR (^) Operator

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Bitwise XOR (Exculsive OR) performs XOR operations to each digit of the binary representation of two values. The following is the truth table for the XOR operation. X Y X XOR Y 1 1 0 1 0 1 0 1 1 0 0 0 Figure 4 - XOR Truth Table The XOR operation yields 0 if both operands are the same, that is, if both are 0's or both are 1's. Otherwise, it yields 1. The following example shows the effect of using the bitwise XOR operator on two values.
int result = 5 ^ 7; Console.WriteLine(result); 2

The following shows their binary representations and how we arrived at the result value using the bitwise XOR operator.
5: 00000000000000000000000000000101 7: 00000000000000000000000000000111 ----------------------------------2: 00000000000000000000000000000010

By looking at the XOR truth table and applying the XOR operation on each binary digit pairs, we arrived at the final value which is the binary representation of 2. The assignment version of the bitwise XOR operator is also available.
myNumber ^= 5;

The above statement applies the bitwise XOR operator to whatever the value of myNumber and to the value of the right operand (in this case 5). The result is then assigned to myNumber.

Bitwise NOT (~) Operator


The bitwise NOT operator performs the NOT operation (inversion) to each binary digit of a number. It is a unary operator so it only needs one operand. The following is the truth table for the NOT operation. X NOT X 1 0

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

X NOT X 0 1 Figure 5 - NOT Truth Table The NOT operation simply inverts the value of a binary digit. The following shows an example of using the not operator.
int result = ~7; Console.WriteLine(result);

Let's look at their binary representations.


7: 00000000000000000000000000000111 ------------------------------------8: 11111111111111111111111111111000

Inverting every binary digit of 7 results on the binary representation of -8. Binary representations of negative numbers are quite tricky. You need to use the Two's Compliment Notation to the binary form of -8 to see why the computer reads it as -8 (instead of a very big number).

Bitwise Operators Example Usage


To show a practical example of using the bitwise operators, suppose you want to specify a certain style of a font. First, we can give specific numeric codes for each font style. Style Code Regular 0 Bold 1 Italic 2 Underline 4 Strikeout 8 Let's say the initial value of the fontStyle is 0 which means, the current font style uses regular (or no style).
int fontStyle = 0;

To add the Bold font style, we can use the bitwise OR operator. Note that Bold is represented by code 1.
fontStyle = fontStyle | 1;

To add the Italic font style to the current fontStyle, again, use the bitwise OR operator.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

fontStyle |= 2;

Since the fontStyle previously has the value 1 which means bold, adding the italic style 2 will perform bitwise OR operation on 1 and 2 resulting to 3. By looking at the table of styles above, there is no corresponding style for code 3. Therefore, we can assign the 3 to the new style BoldItalic which is a combination of Bold and Italic styles. If we are to add the Underline font style (8) to the current font style (3), the result will be 11, which can represent the font style which is Bold, Italicized, and Underlined at the same time. Say you want to assign a new style which is a combination of all the styles, then you can simply use the bitwise OR operator between each font style.
fontStyle = 1 | 2 | 4 | 8;

To test if a style is part of the overall font style, we can use the bitwise AND operator.
bool isBold = (fontStyle & 1) == 1;

The expression tests if ANDing the current fontStyle yields to the style being tested. If so, the result of the expression is true, otherwise false. If you want for example to remove the Underline style to the current font style, you can use the XOR operator.
fontStyle = fontStyle ^ 8; //or fontStyle ^= 8;

Once the Underline style is removed, using the bitwise XOR operator again will add the Underline style instead of removing it. The previous example represented the font styles using plain integers which is hard to read. The proper way is by using enumerations which we will be discussing in an upcoming lesson.

The Bitwise Shift Operators


Another pair of operators, called the bitwise shift operators allows you to shift the position of the bits to the left or to the right. Both operators accept two operands, the left being the value whose binary representation will be shifted, and the right operand specifies the number of positions to shift to left or right. Operator << >> Name Left Shift Operator Right Shift Operator Category Example Binary Binary x = y << 2; x = y >> 2;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Operator <<= >>=

Name

Category Example x <<= 2; x >>= 2;

Left Shift Assignment Binary Right Shift Assignment Binary

Figure 6 - Bitwise Shift Operators The Left Shift Operator (<<) shifts the bits of the left operand to the left by n positions specified by the right operand. Consider the following example.
int result = 10 << 2; Console.WriteLine(result); 40

The previous statement indicates that we shift the bits of the decimal value 10, by two positions. Let's demonstrate the effect by showing their binary representations.
10: 00000000000000000000000000001010 -----------------------------------40: 00000000000000000000000000101000

You can see that every digits was moved by 2 positions. Digits to the left will be discarded and the empty slots to the right where the original bits once reside will be replaced by 0's. For example, since we shifted 2 positions to the left, the last 2 digits to the left will be droped, and two 0's will be added to the right. Shifting bits to the left has an effect of multiplying the value by 2 multiple times depending on the value of the right operand. For example, the value 10 when shifted to the left by 2 positions multiplies 10 by 2 two times. 10 << 3 will multiply 10 by 2 three times and 10 << 4 will multiply 10 by 2 four times and so on. The number of times a value will be multiplied by 2 depends on the value of the right operand. The Right Shift Operator (>>) is similar to the left shift operator but it shifts the bits to the right instead of left. The following is an example of using this operator.
int result = 100 >> 4; Console.WriteLine(result); 6

Using the right shift operator, the bits of value 100 was shifted to the right by 4 positions. Let's look at their binary equivalents.
100: 00000000000000000000000001100100 -----------------------------------6: 00000000000000000000000000000110

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Every bit is moved by 4 positions to the right, so the first 4 bits in the right where droped and 0's where added to the right to fill the gap. Shifting bits to the right has an effect of dividing the value by 2 multiple times depending on the value of the right operand. For example, the value 100 when shifted to the right by 4 positions divides 10 by 2 four times. 100 >> 2 will divide 100 by 2 two times and 100 >> 3 will divide 100 by 2 three times and so on. The number of times a value will be divided by 2 depends on the value of the right operand. The shofthand assignment versions of bitwise operators are also available.
result1 <<= 2; result2 >>= 4;

They both act the same as the other assignment operators we have seen. Bitwise shift operators are rarely used but it is better to know that these operators exist.

Operator Precedence
Operator precedence determines which to calculate first in an expression involving more than two operands. Operators in C# has their own priority during calculation, and the compiler calculates those with the highest priority first. Consider this example:
number = 1 + 2 * 3 / 1;

If we don't follow the order of which to calculate first then we have to calculate the expression from left to right. So 1 + 2 results to 3 multiplied by 3 yields 9 divided by 1 would give a final answer of 9 which is not the right answer. The compiler follows operator precedence. For example, the multiplication and division has higher precedence than addition and subtraction so we need to multiply 2 and 3 first which will result to 6 then divide it by 1 which is 6 and finally, we add 1 to 6 which results to 7. The result is then assigned to the variable thanks to the = operator which has lower precedence. The following table shows the precedence of some of the operators in C#. Precedence Operators Highest ++, --, (used as prefixes); +, - (unary) *, /, % +, <<, >> <, >, <=, >= ==, != & ^ |

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Precedence

Operators && || =, *=, /=, %=, +=, -= ++, -- (used as suffixes)

Lowest

Figure 1 - Operator Precedence Operators with a high precedence than other operators with lower precedence is calculated first. Notice that the ++ and -- operators' precedence depends on where you put those operators in an operand. For example, consider the expression below.
int number = 3; number1 = 3 + ++number; //results to 7 number2 = 3 + number++; //results to 6

In the first expression, the value of number is incremented first by 1 which makes it 4 and then it is added to 3 which results to a value of 7. On the second expression, the value of number which is 3 is added first to 3 which yields 6 that is added to variable number2. Just then would the number be incremented to 4. To make operator precedence even more readable, we use parentheses.
number = ( 1 + 2 ) * ( 3 / 4 ) % ( 5 - ( 6 * 7 ));

The expressions inside each set of parentheses are evaluated first. Take note on expression inside the third set of perenthesis. The values inside of it uses the normal operator precedence so 6 and 7 are multiplied first before subtracting the it to 5. If two or more operators with the same level of precedence exists, then you can evaluate them based on their associativity. For example, in the expression:
number = 3 * 2 + 8 / 4;

has both * and / operators which has the same level of precedence. Their associativity is left-toright so you must start with the one in the left the proceed to the next ones to the right. So we first multiply 3 and 2 and then divide 8 by 4. The results of the two expressions is added and then assigned to the number. You can check the following link for a full list of operator precedence and their associativiy. Operator Precedence Chart

Getting Input From User


User input is essential for a program to execute it's functions and give you the data you want. The .NET Framework has some methods available to you for getting user input from the user.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

For now, we will discuss about the Console.ReadLine() method that gets a string value from the user. The Console.ReadLine() method takes no arguments and returns a string value which is the value given or typed by the user. As the name of the method implies, it reads the whole line you type in the console until you press the return or enter key. You can then convert that string data using either the Parse method or the conversion methods of the Convert class. If the variable that will store the string data is of type string, then no conversion is neccessary. Lets take a look at the example program.
1 using System; 2 3 namespace GettingInputDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 string name; 10 int age; 11 double height; 12 13 Console.Write("Enter your name: "); 14 name = Console.ReadLine(); 15 Console.Write("Enter your age: "); 16 age = Convert.ToInt32(Console.ReadLine()); 17 Console.Write("Enter your height: "); 18 height = Convert.ToDouble(Console.ReadLine()); 19 20 //Print a blank line 21 Console.WriteLine(); 22 23 //Show the details you typed 24 Console.WriteLine("Name is {0}.", name); 25 Console.WriteLine("Age is {0}.", age); 26 Console.WriteLine("Height is {0}.", height); 27 } 28 } 29}

Figure 1 - Getting Input from the User


Enter your name: John Enter your age: 18 Enter your height: 160.5 Name is John. Age is 18. Height is 160.5.

We first declared three variables that will hold the data that we will give to the program. The program prompts the user to enter his name (line 13). Note that we use Console.Write() instead of Console.WriteLine(). Line 14 iis where you will get the input from the user. The name
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

variable is assigned the value that is returned by the Console.ReadLine() method. Since name is string, and the value returned by Console.ReadLine() is also string, then no conversion is necessary. Then we prompt for the age of the user. The age is a variable of type int so we need to do a conversion from string to int. So we use Convert.ToInt32() method to do just that. The value returned by that method is what will be assigned to the age variable. Same goes with the height variable but instead, we use Convert.ToDouble() method since height is of type double. Alternatively, when converting string values to their numerical types, you can use the Parse() method which is available on every simple types except string.
age = int.Parse(Console.ReadLine()); height = double.Parse(Console.ReadLine());

Note on converting numbers such as int and double from string. The string must or is able to represent a number. If the string contains alphanumeric characters or characters which are not numbers and cannot be expressed as a valid number, then an error will occur. So for example, the program prompts you for the age and you type your name instead, converting your name to a number will produce an error during runtime.

Making Decisions
Almost every programming languages allows you to execute a code when a certain condition is met. This adds logic to your program. Imagine a program that cannot make decisions and execute every line of code. That would be okay if you just want to print a messages in a screen. But what if you want to print a certain message if the value of a variable is equal to a specified number. C# offers different ways to make add this kind of behavior to your program. In the following of lessons, you will learn the following:

The if Statement The if else Statement The Ternary Operator Multiple Selection if Statements Nesting if Statements Logical Operators The switch Statement

The if Statement
A program cannot think if it cannot make a decision. C# allows you to execute codes if certain conditions are true or false. By using an if statement and specifying the condition that will execute the code, you can add logic to your program. The if statement is a single-selection conditional statement which means that there will be no alternative codes to execute if a certain condition is not met. The syntax of an if statement is as follows:

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

if (condition) code to execute;

Before an if statement can be executed, the condition is tested first. If the condtion results to true, then the following code will be executed. The condition is in a form of a comparison expression. We use comparison operators to test if a condition is true or false. Lets take a look at how we can use an if statement inside a program. The following program will show the message "Hello World." if the value of number is less than 10 and "Goodbye World." if it is greater than 10.
1 using System; 2 3 namespace IfStatementDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 //Declare a variable and set it a value less than 10 10 int number = 5; 11 12 //If the value of number is less than 10 13 if (number < 10) 14 Console.WriteLine("Hello World."); 15 16 //Change the value of a number to a value which 17 // is greater than 10 18 number = 15; 19 20 //If the value of number is greater than 10 21 if (number > 10) 22 Console.WriteLine("Goodbye World."); 23 } 24 } 25}

Example 1 - Using the if Statement


Hello World. Goodbye World.

Line 10 declares a variable named number with a value of 5. When we reach the first if statement in line 13, the program determines if the number is less than 10, that is if 5 is less than 10. Logically, it results to true so the if statement's corresponding statement to execute (line 14) will be executed resulting to printing the message "Hello World.". After that, we change the value of number to 15 (line 18). When it reach the second if statement in line 21, it sees that 15 is indeed greater than 10 and executes the message "Goodbye World." in line 22. Note that it doesn't matter if you write the if statement in one line as in:
if ( number > 10 ) Console.WriteLine("Goodbye World.");

As long as you have a single statement to execute and you terminate the statement with a semicolon, the above code is valid.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can have multiple statements inside an if statement. You need to put curly braces to mark the start and end of the set of statements to execute. Everything inside the curly braces is considered the block or body of the if statement. Not placing curly braces will lead to your program not doing what you expected. The following is the syntax of an if statement with multiple statements in its block.
if (condition) { statement1; statement2; . . . statementN; }

Let's look an an example with this code snippet:


if (x > 10) { Console.WriteLine("x is greater than 10."); Console.WriteLine("This is still part of the if statement."); }

The code above will output the two messages if the value of x is greater than 10. If for instance, we remove the curly braces and the value of x is not greater than 10 such as the following code snipppet:
if (x > 10) Console.WriteLine("x is greater than 10."); Console.WriteLine("This is still part of the if statement. (Really?)");

The above code is better read if we put the proper indentions for the statements.
if (x > 10) Console.WriteLine("x is greater than 10."); Console.WriteLine("This is still part of the if statement. (Really?)");

You can see that the second statement is actually not part of the if statement. The code will only print the second line because the value of x is less than 10 and the condition for the if statement will result to false. That's why curly braces are important. As a good practice, always write curly braces even if you only have one statement in the body of the if statement so whenever you want to add another statment inside it, you won't forget adding curly braces which will result to errors which are hard to find. One common mistake of new programmers is putting a semicolon right after the right parenthesis of the if statement's condition. Consider the following example.
if (x > 10); Console.WriteLine("x is greater than 10");

This will lead to the if statement having no statements to execute. The second will be not part of the if statement. Although this would compile, your program will yield logic errors. So always
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

remember to not put a semicolon at the end of the condition of an if statement because doing so will signify that the if statement's code block has ended there.

Let's take a look at another example of using if statements.

1 using System; 2 3 namespace IfStatementDemo2 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 int firstNumber; 10 int secondNumber; 11 12 Console.Write("Enter a number: "); 13 firstNumber = Convert.ToInt32(Console.ReadLine()); 14 15 Console.Write("Enter another number: "); 16 secondNumber = Convert.ToInt32(Console.ReadLine()); 17 18 if (firstNumber == secondNumber) 19 { 20 Console.WriteLine("{0} == {1}", firstNumber, secondNumber); 21 } 22 if (firstNumber != secondNumber) 23 { 24 Console.WriteLine("{0} != {1}", firstNumber, secondNumber); 25 } 26 if (firstNumber < secondNumber) 27 { 28 Console.WriteLine("{0} < {1}", firstNumber, secondNumber); 29 } 30 if (firstNumber > secondNumber) 31 { 32 Console.WriteLine("{0} > {1}", firstNumber, secondNumber); 33 } 34 if (firstNumber <= secondNumber) 35 { 36 Console.WriteLine("{0} <= {1}", firstNumber, secondNumber); 37 } 38 if (firstNumber >= secondNumber) 39 { 40 Console.WriteLine("{0} >= {1}", firstNumber, secondNumber); 41 } 42 } 43 } 44}

Example 2
Enter a number: 2 Enter another number: 5

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

2 != 5 2 < 5 2 <= 5 Enter a number: 10 Enter another number: 3 10 != 3 10 > 3 10 >= 3 Enter a number: 5 Enter another number: 5 5 == 5 5 <= 5 5 >= 5

We used the comparison operators as condition for each if statements. We asked an input from the user for two numbers that will be involved on the comparisons. The numbers will be compared inside every if statements and print the corresponding message if the condition results to true. Note that conditions are boolean values which are results of a comparison expression. Therefore, you can store the result of an expression in a boolean variable and then use the variable as the condition in an if statement.
bool isNewMillenium = year == 2000; if (isNewMillenium) { Console.WriteLine("Happy New Millenium!"); }

If the value of year is indeed 2000, then the expression will yield true and be stored in variable isNewMillenium. We can use the variable to determine if the if statement's body will execute depending on whether the value of the variable is true or false.

The if else Statement

The if statement we presented last time is only good if you want to execute a code when one condition is met. But what would you do if you want execute another set of codes when that condition is not met? The if else statement serves this purpose because it is a double-selection conditional statement. It means, you can specify another behavior when the specified condition is false. Below is the syntax of an if else statement.
if (condition) { code to execute if condition is true; } else { code to execute if condition is false; }

The else keyword can't be use by itself. It must have a matching if statement. The curly braces are optional if you only have one statement to execute for each of the body of if

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

and else. The code inside the else block will only be executed if the condition inside the if statment results to false. I'll show you an example of using the if else statement.
using System; 1 2 namespace IfElseStatementDemo 3 { 4 public class Program 5 { 6 public static void Main() 7 { 8 int number = 5; 9 10 //Test the condition 11 if (number < 10) 12 { 13 Console.WriteLine("The 14 } 15 else 16 { 17 Console.WriteLine("The 18equal to 10."); 19 } 20 21 //Modify value of number 22 number = 15; 23 24 //Repeat the test to yield 25 if (number < 10) 26 { 27 Console.WriteLine("The 28 } 29 else 30 { 31 Console.WriteLine("The 32equal to 10."); 33 } 34 } 35 } }

number is less than 10.");

number is either greater than or

a different result number is less than 10.");

number is either greater than or

Example 1 - Using the if else Statement


The number is less than 10. The number is either greater than or equal to 10.

The output shows the functionality of the if else statement. When the value of number is less than 10, it met the condition and executes the code that is inside the if block. When the value of number was modified to have a value which is greater than 10, the condition resulted to false and the code block of else was executed. Do not use the else block if it has no corresponding if block. Like the if statement, do not add a semicolon immediately after the else keyword.

Conditional Operator
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

The conditional operator (?:) in C# does the same thing as the if else statement though it is more suited on simple statements such as assigning two different values depending on a specified condition. Below shows the syntax of using this operator.
<condition> ? <result if true> : <result if false>

The conditional operator is C#'s only ternary operator as it requires three operand, the condition, the value when the condition is true, and the value when the condition is false. Let's take a look at how to use this operator inside a program.

1 namespace ConditionalOperatorDemo 2 { 3 public class Program 4 { 5 public static void Main() 6 { 7 string pet1 = "puppy"; 8 string pet2 = "kitten"; 9 string type1; 10 string type2; 11 12 type1 = (pet1 == "puppy") ? "dog" : "cat"; 13 type2 = (pet2 == "kitten") ? "cat" : "dog"; 14 } 15 } 16}

Example 1 - Using the Conditional Operator

The above program demonstrates the use of the conditional operator. The first line translates like this; if the value of pet1 is "puppy" then assign "dog" to type1, otherwise, assign "cat" to type1. Same goes with the second line; if the value of pet2 is "kitten" then assign "cat" to type2, "dog" otherwise. Let's transform the following line of code to it's equivalent if else statement to make it even clearer. If we rewrite this using if else statement, it will look like this.
if (pet1 == "puppy") type1 = "dog"; else type1 = "cat";

Avoid using the conditional operator when you have multiple statements inside an if or else block. Sometimes, the conditional operator can make code less readable.

Multiple Selection if Statements


What if you have more conditions to test? You can write multiple if statements but woudn't it be better if you can combine those if statements into one whole list. You can have multiple selection in an if statement using the syntax below.
if (condition) { code to execute;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

} else { if (condition) { code to execute; } else { if (condition) { code to execute; } else { code to execute; } } }

The code above is hard to read. You are branching if statements inside the else blocks. There's a better way of doing this. We could rewrite the code above and make it simpler.
if (condition) { code to execute; } else if (condition) { code to execute; } else if (condition) { code to execute; } else { code to execute; }

We introduce using the else if statement. Like the else, the else if must have a corresponding if statement. The else if statement executes if the first if statement is not true. The condition of the else if is then tested and if false, the other else if statements will be executed. If no other else if is found, the else block will be executed instead. Lets make a program that will demonstrate the else if statements.
1 using System; 2 3 namespace MultipleSelectionIfStatementsDemo 4 { 5 public class Program

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48}

{ public static void Main() { int choice; Console.WriteLine("What's your favorite color?"); Console.WriteLine("[1] Black"); Console.WriteLine("[2] White"); Console.WriteLine("[3] Blue"); Console.WriteLine("[4] Red"); Console.WriteLine("[5] Yellow\n"); Console.Write("Enter your choice: "); choice = Convert.ToInt32(Console.ReadLine()); if (choice == 1) { Console.WriteLine("You might like my black t-shirt."); } else if (choice == 2) { Console.WriteLine("You might be a clean and tidy person."); } else if (choice == 3) { Console.WriteLine("You might be sad today."); } else if (choice == 4) { Console.WriteLine("You might be inlove right now."); } else if (choice == 5) { Console.WriteLine("Lemon might be your favorite fruit."); } else { Console.WriteLine("Sorry, your favorite color is " + "not in the choices above."); } } }

Example 1 - Using Multiple Selection if Statements


What's your favorite color? [1] Black [2] White [3] Blue [4] Red [5] Yellow Enter your choice: 1 You might like my black t-shirt.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

What's your favorite color? [1] Black [2] White [3] Blue [4] Red [5] Yellow Enter your choice: 999 Sorry, your favorite color is not in the choices above.

The output will vary depending on what choice you give to the program. Depending on what you choose, the program will print a different message. Take note about the else statement. If the number you typed is not in the choices, then the code inside the else block will be executed.

Nesting if Statements
You can nest if statements in C#. This is simply placing if statements inside if statements. You can make something as complex as the code that follows.
if (condition) { code to execute; if (condition) { code to execute; } else if (condition) { if (condition) { code to execute; } } } else { if (condition) { code to execute; } }

Let's try a program that uses nested if statements.


1 using System; 2 3 namespace NestingIfStatementsDemo 4 { 5 public class Program 6 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42}

public static void Main() { int age; string gender; Console.Write("Enter your age: "); age = Convert.ToInt32(Console.ReadLine()); Console.Write("Enter your gender (male/female): "); gender = Console.ReadLine(); if (age > 12) { if (age < 20) { if (gender == "male") { Console.WriteLine("You are a teenage boy."); } else { Console.WriteLine("You are a teenage girl."); } } else { Console.WriteLine("You are already an adult."); } } else { Console.WriteLine("You are still too young."); } } }

Example 1 - Nesting if Statements


Enter your age: 18 Enter your gender: male You are a teenage boy. Enter your age: 12 Enter your gender: female You are still too young.

Let's disect the program. First, the program will ask you for your age (line 13). Line 16 asks for your gender. Then the program will hit the first if statement in line 18. It will test if you will past the first condition and that's if your age is greater than 12. If you pass this condition, you will move inside the body of the if statement. If not, you jump to the corresponding else block (line 34) of that if statement. Let's say you pass the first condition, and you are now inside the block of the first if statement. Inside it, you will meet a second nested if statement (line 20). It will determine if your age is less than 20. If you pass this, you will be taken into its code block, but if not, you will jump again to the it's else pair in line 31. Let's assume the value of your age is

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

indeed less than 20, then you will be taken inside its body and there you will encounter yet another if statement (line 22). This will look at your gender and if it is "male", then you will execute the code inside the body of the 3rd if statement, if not, it will execute the body of the else statement (line 26). The nesting ends there. If possible, avoid so much nesting of if statements. This makes your code very confusing to read. You can avoid using too many nested if statements using logical operators.

Using Logical Operators


Logical operators allows you to combine multiple conditions. These operators involves at least two conditions and the final boolean result is determined by the operator being used. Let's take a look at some logical operators. Operator Pronounced as Effect z will be assigned a value of true if both z = (x > 2) && (y < 10) the conditions are true. If one of the conditions results to false, then z will automatically assigned a value of false. z will be assigned a value of true if at least one of the z = (x > 2) || (y < 10) conditions is true. If there's no condition that results to true, then z will be assigned a value of false. z will be assigned a value of true if the condition z = !(x > 2) results to false, and false, if the condition results to true. Example

&&

And

||

Or

Not

Figure 1 For example, you can read z = (x > 2) && (y < 10) as "Assign z with true if the value of x is greater than 2 AND the value of y is less 10, false otherwise". The sentence suggest that it requires to have all the conditions to be true in order for the statement to be true. You passed the subject if you passed the final exam AND you got a passing grade. This means you cannot pass the subject if you neither pass the final exam nor have a passing grade or both. The use of || (logical OR) is a different effect than the && (logical AND). The logical OR operator results to true if at least one of the conditions is true. If none of those conditions is true, then it will result to falsity. You can even combine both logical AND and logical OR in an expression like this:
if ( (x == 1) && ( (y > 3) || z < 10) ) ) { //do something here }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The use of parentheses is important here. We use it to group the conditions. First, it will calculate the result of (y > 3) || (z < 10) because it is considered as a group thanks to the parentheses. The result will then be the right operand of the logical AND and will be compared to (x == 1) condition. The result will determine if the program should execute the code in its body. We wrote a program on our previous lesson. Lets make some modifications in it to show how to use a logical operator inside a program.
1 using System; 2 3 namespace LogicalOperatorsDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 int age; 10 string gender; 11 12 Console.Write("Enter your age: "); 13 age = Convert.ToInt32(Console.ReadLine()); 14 15 Console.Write("Enter your gender (male/female): "); 16 gender = Console.ReadLine(); 17 18 if (age > 12 && age < 20) 19 { 20 if (gender == "male") 21 { 22 Console.WriteLine("You are a teenage boy."); 23 } 24 else 25 { 26 Console.WriteLine("You are a teenage girl."); 27 } 28 } 29 else 30 { 31 Console.WriteLine("You are not a teenager."); 32 } 33 } 34 } 35}

Example 1 - Logical Operators


Enter your age: 18 Enter your gender (male/female): female You are a teenage girl. Enter you age: 10 Enter your gender (male/female): male You are not a teenager.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The modified program shows you the logical operator AND in action (line 16). When you reach the if statement, the program determines if your age is between 12 and 20. First, it checks if your age is greater than 12 then it checks if your age didn't exceed 20. If both of these are true, then it will execute the code inside the if block. If one condition yields false such as meeting the condition that you are older than 12 but not younger than 20, then it will execute the code inside the else block. The && operator evaluates the left operand. If it is false, then it skips evaluating the right operand and automatically yield false as the result. In contrast, the || operator evaluates the left operand and if it is true, then it skips the evaluation of the right operand and immediately yields true. One important thing to note is that you can also use the operators & and | which are the bitwise AND and OR operators.
if (x == 2 & y == 3) { //Some code here } if (x == 2 | y == 3) { //Some code here }

One minor difference of this operators on the logical operators we have discussed is that they evaluate the two operands regardless of the value of the left operand. For example, even if the left operand is false, the right operand is still evaluated by the bitwise AND operator (&). If you are combining conditions, it would be better to use the logical AND (&&) and OR (||) operators instead of the bitwise AND (&) and OR (|) operators. There's another logical operator that I would like to show. The NOT Operator (!) is used to negate or inverse the effect of an expression.Consider the following example:
if (!(x == 2)) { Console.WriteLine("x is not equal to 2."); }

If the expression x == 2 evaluates to false, the ! operator reverses the result from false to true.

The switch Statement


C# offers switch statements which allows you to have multiple selections based on a constant value of a variable. A switch statement is equivallent to a multiple selection if statement but a switch statement is used if the variable to be compared has a constant value such as a number, a string, or a character. Constant values are values that doesn't change. Below shows the syntax of a switch statement.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

switch (testVar) { case compareVal1: code to execute break; case compareVa12: code to execute break; . . . case compareVa1N: code to execute break; default: code to execute break; }

if testVar == compareVa11; if testVar == compareVa12;

if testVer == compareVa1N; if none of the values above match the testVar;

You pass a variable to a switch statement. This variable is then compared to each case statement inside the block of the switch. If the variable matched a value in a case statement, the code of that particular case statement is executed. Note that even if the number of lines of code inside a case statement is more than one, we don't use curly braces. The end of the body of a case statement is determined by the keyword break which brings the program outside of the switch statment and executes any code following the structure. If this is omitted, then you will encounter an error. The switch statement also has a default statement which is executed if none of the values of all the case statements match the value of the test variable. The default statement is optional and nothing will happen if you remove it except that nothing will be executed if no values match the cases.The position of the default statement is not important but it is a habit to place it below. Let's look at an example of how to use a switch statement.
1 using System; 2 3 namespace SwitchStatementDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 int choice; 10 11 Console.WriteLine("What's your favorite pet?"); 12 Console.WriteLine("[1] Dog"); 13 Console.WriteLine("[2] Cat"); 14 Console.WriteLine("[3] Rabbit"); 15 Console.WriteLine("[4] Turtle"); 16 Console.WriteLine("[5] Fish"); 17 Console.WriteLine("[6] Not in the choices"); 18 Console.Write("\nEnter your choice: "); 19

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41choices."); 42 43 44 45 46 47 } 48 } }

choice = Convert.ToInt32(Console.ReadLine()); switch (choice) { case 1: Console.WriteLine("Your break; case 2: Console.WriteLine("Your break; case 3: Console.WriteLine("Your break; case 4: Console.WriteLine("Your break; case 5: Console.WriteLine("Your break; case 6: Console.WriteLine("Your

favorite pet is Dog."); favorite pet is Cat."); favorite pet is Rabbit."); favorite pet is Turtle."); favorite pet is Fish."); favorite pet is not in the

break; default: Console.WriteLine("You don't have a favorite pet."); break; }

Example 1 - Using a switch Statement


What's your favorite pet? [1] Dog [2] Cat [3] Rabbit [4] Turtle [5] Fish [6] Not in the choices Enter your choice: 2 Your favorite pet is Cat. What's your favorite pet? [1] Dog [2] Cat [3] Rabbit [4] Turtle [5] Fish [6] Not in the choices Enter your choice: 99 You don't have a favorite pet.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The program above lets you pick what your favorite pet is. Each pet has been assigned a corresponding number. You enter that number and then it was compared inside the switch structure. If a matching number in a case statement is found, the appropriate message is shown. If none of the case statements match, then the default statement is executed. Another feature of the switch statement is that you can make two or more case values to execute one set of codes. For example, what if you want values 1, 2, and 3 to execute one set of code? You simply write a case immediately after another.
switch(number) { case 1: case 2: case 3: Console.WriteLine("This code is shared by three values."); break; }

I said earlier that a switch statment is equivalent to a multiple selection if statement. So another way to write the program in Figure 1 is like this:
if (choice == 1) Console.WriteLine("Your favorite pet is Dog."); else if (choice == 2) Console.WriteLine("Your favorite pet is Cat."); else if (choice == 3) Console.WriteLine("Your favorite pet is Rabbit."); else if (choice == 4) Console.WriteLine("Your favorite pet is Turtle."); else if (choice == 5) Console.WriteLine("Your favorite pet is Fish."); else if (choice == 6) Console.WriteLine("Your favorite pet is not in the choices."); else Console.WriteLine("You don't have a favorite pet.");

The code above will have exactly the same result as the switch statment. Notice that the default statement is equivalent to the else statement. So what should you use between the two? We use switch statement if the value to be compared is constant or is not changing. So the below code is prohibited.
int myNumber = 5; int x = 5; switch (myNumber) { case x: Console.WriteLine("Error, you can't use variables as a value" + " to be compared in a case statment."); break; }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can see here that even though x has a value of 5 which obviously matches the value of the test variable myNumber, an error occured because x is not constant, or to say it in other words, it has a possibility of changing its value. If you want to use x and yield no error, you have to make it a constant variable.
int myNumber = 5; const int x = 5; switch (myNumber) { case x: Console.WriteLine("Error has been fixed!"); break; }

We used the const keyword to make the value constant. Note that after declaring a variable as constant, you won't be able to change its value anywhere in a program. Also note that you need to supply a value in the declaration of a constant variable. A switch statement must match a value of the test variable to the case value so you cannot test if a test variable is less than or greater than the other value. For example, there is no such thing as this:
switch (myNumber) { case x > myNumber: Console.WriteLine("switch staments can't test if a value is less than " + "or greater than the other value."); break; }

Therefore, it is harder to test if the test value is equal to a range of values. This time, you have to use the multiple selection if statement because you will have hard time if you stick with switch statements.

Looping
Looping allows you to repeat a set of code or statements while a given condition is true. Without it, you have to write multiple similar codes just to make your program repeat and that is tedious. Suppose you want to print "Hello World." 10 times. It will look like this without using a loop.
Console.WriteLine("Hello Console.WriteLine("Hello Console.WriteLine("Hello Console.WriteLine("Hello Console.WriteLine("Hello Console.WriteLine("Hello Console.WriteLine("Hello Console.WriteLine("Hello Console.WriteLine("Hello Console.WriteLine("Hello World."); World."); World."); World."); World."); World."); World."); World."); World."); World.");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Of course you can copy the first line and just hit Ctrl + V to paste the other nine, but what I'm trying to show you here is inefficiency. There is a way to better write all of these lines of code and that's by using a loop. There are different kinds of looping structure in C#.

while Loop do while Loop for Loop

The while Loop


The while loop is the most basic looping structure in C#. It takes one condition and a set of codes that it will execute for as long as the condition remains true. The basic syntax of a while loop is as follows.
while(condition) { code to loop; }

As you can see, the syntax is as simple as the structure of an if statement. We first write the condition which is a boolean statement and if that condition is true, then it will execute the code. If the condition is not true when the program reaches the while loop, then it will not execute the code at all. For a looping to stop, there must be some kind of modification to the values inside the while loop. You will be needing a counter variable that will be used inside the body of the while loop. This counter will be used in the condition to test if the loop should continue. Then inside the body, you must increment or decrement it. Lets look at an example program that will show you how to use a while loop.
1 using System; 2 3 namespace WhileLoopDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 int counter = 1; 10 11 while (counter <= 10) 12 { 13 Console.WriteLine("Hello World!"); 14 counter++; 15 } 16 17 } 18 } 19}

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Example 1 - Using the while Loop


Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello World! World! World! World! World! World! World! World! World! World!

The program above repeats the message 10 times. If you will not use a loop, you will need to repeat writing the same codes. Lets look at the code for that program. First we declared a variable in line 7 that will serve as a counter for the loop. This variable is initialized to 1 becuase it can't be involved in a condition if it has no value. Then we enter the while loop in line 9. It tests if the value of the counter is less than or equal to 10. Succeeding in that test, it enters the body of the while loop and print the message. After that, it increments the value of the counter by 1 (line 12). This makes sure that there is a certain end for our loop. Our loop will stay to repeat if the value of counter is less than 10. If the value of counter stays 1, by not incrementing it, or if it never made the condition false, then the it will result in an infinite loop. Notice also that we use <= rather than the < operator. If we are to use < instead, then we will only be repeating the code 9 times because we started at value 1, and at value 10, the codition becomes false10 < 10 is false. If you want to create an infinite loop, that is, a loop that never stops, then you can just write true as the condition statement of the while loop
while(true) { //code to loop }

This technique can be useful in some situations and you can only leave the loop by using break or return statements that we will discuss in an upcoming lesson.

The do while Loop


The do while loop is another way of making your code repeat its execution. It is almost similar the while loop with one minor diference, it checks the condition after the code body has been executed. Let's look at the syntax of the do while loop.
do { code to repeat;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

} while (condition);

As you can see, the condition is at the end of the structure. That means that the code inside the body will be executed at least once. Unlike the while loop where the body will not execute if the condition is already false the very first time. One example where you would prefer using a do while loop over the while loop is when getting information from the user. It requires the prompt to show for at least 1 time.
//while version Console.WriteLine("Enter a number greater than 10: "); number = Convert.ToInt32(Console.ReadLine()); while(number < 10) { Console.WriteLine("Enter a number greater than 10: "); number = Convert.ToInt32(Console.ReadLine()); }

Example 1 - Using a while Loop


//do while version do { Console.WriteLine("Enter a number greater than 10: "); number = Convert.ToInt32(Console.ReadLine()); } while (number < 10);

Example 2 - Using a do while Loop You can see that you have save a few lines of code by using do while instead of the while loop. Take note that everything you can do with the while loop, you can also do using do while and vice versa.

The for Loop


The for looping structure of C# is like an all-in-one looping utility. The for loop acts like the while loop only with some extra features. The syntax of a for loop is quite different compared to the other two looping structures.
for(initialization; condition; operation) { code to repeat; }

The initialization is where you will initialize your counter variable. That counter is only available or accessible inside the for loop. The condition is where the counter variable will be compared to a value to determine if the for loop should continue it's looping. The operation handles the modification of the counter variable like incrementing or decrementing it. All of those three are essential for a counter-controlled repetition.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Lets look an example program that uses the for loop.


1 using System; 2 3 namespace ForLoopDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 for (int i = 1; i <= 10; i++) 10 { 11 Console.WriteLine("Number " + i); 12 } 13 } 14 } 15}

Example 1 - Using the for Loop


Number Number Number Number Number Number Number Number Number Number 1 2 3 4 5 6 7 8 9 10

The program will count from 1 to 10 using the for loop. The for loop header has it all to make the loop. First, it declares a variable that will be used as a counter and then initializes its value to 1. Then it will test the condition provided whether it is less than or equal to 10. Note that the third one which is the operation will not be executed immediately. The code will execute first which prints the current value of i preceded by the string "Number ". Just then will the code i++ be executed which will increment the value of the counter i by 1 and then the comparison takes place again if the value of i still passes the condition. If for example you want to reverse the way the program counts, you could write this instead:
for (int i = 10; i > 0; i--) { //code omitted }

This code will make the program count from 10 to 1 instead of 1 to 10. We initialized the value of the counter to 10 and used the decrement operator (--) to make the program do a countdown. Some more complex modifications can be done with the condition and the operation part of the for loop. For example, you can use the logical operators to make more complex expressions and you can use different assignment operators for the operation. You can also declare multiple variables that will contribute on the for loop.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

for (int i = 1, y = 2; i < 10 && y > 20; i++, y -= 2) { //some code here }

Note that if you are using two or more counter variables or operations, you must seperate them with a coma. The for loop is best used when your loopings continuity is determined by counters. It would be odd to use, but acceptable, to consider for loop in a sentinel-controlled repetition or a repetition where the condition is based on a sentinel that is a value that will make the loop stop. For sentinel-controlled repetition, a while or do while loop is more prefered.
//for version for ( char choice = 'y'; choice != 'n'; ) { Console.WriteLine("Repeat?(y/n): "); choice = Convert.ToChar(Console.ReadLine()); } //while version char choice2 = 'y'; while(choice2 != 'n') { Console.WriteLine("Repeat?(y/n): "); choice2 = Convert.ToChar(Console.ReadLine()); }

Example 2 - Comparing for Loop with while Loop The operation part of the for loop above was omitted because the continuity of the loop is determined by a user input. It makes the head of the for loop a little odd looking compared to the while loop which looks more natural that's why I prefer using that when the loop is controlled by a sentinel.

break and continue Statements


Sometimes, you want to stop the loop even if the condition is still true. How do you do that? Well, we can use the break keyword to stop the loop and the continue keyword to skip one loop cycle and continue to the next. The program below will demonstrate the use of break and continue statements.
1 using System; 2 3 namespace BreakContinueDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 Console.WriteLine("Demonstrating the use of break.\n");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30}

for (int x = 1; x < 10; x++) { if (x == 5) break; Console.WriteLine("Number " + x); } Console.WriteLine("\nDemonstrating the use of continue.\n"); for (int x = 1; x < 10; x++) { if (x == 5) continue; Console.WriteLine("Number " + x); } } }

Example 1 - break and continue Statements


Demonstrating the use of break. Number Number Number Number 1 2 3 4

Demonstrating the use of continue. Number Number Number Number Number Number Number Number 1 2 3 4 6 7 8 9

The program uses a for loop although using break inside while or do while loops will have the same results. When the value of x reaches 5 as the if condition in line 11 said, then execute the break statement (line 14). The looping is immediately stopped even if the condition x < 10 is still true. On the other hand, the continue (line 24) only stops the execution for a particular loop cycle. If the value of x is 5 and then the continue statement executes, it will stop execution of codes and proceed the the next loop cycle.

Arrays
An array is a kind of variable that stores a list of addresses of variables and can store a set of data having the same data type. Declaring multiple variables with the same type and used for the
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

same purpose can be exhausting. What if you want to store a thousand values with integers and they will be used, for example, a list of grades of students. It would be tedious and boring to declare all of those one thousand variables. But with arrays, you can declare them in one line. Below shows you the simplest way to declare an array.
datatype[] arrayName = new datatype[length];

The datatype is the type of variable that the array will store. The square brackets next to the data type tells that it is an array. The arrayName is the identifier or the name of the variable. When naming an array, it is a good practice to make it plural to indicate that it is an array. For example, use numbers instead of number when naming an array. The length tells the compiler how many data or values you are going to store in an array. We used the new keyword to allocate enough spaces for the array in the memory depending on the value specified by the length. Each item in an array is called an array element. If we are to declare an array that can store 5 values of type integer, we would write:
int[] numbers = new int[5];

This declaration reserves 5 addresses inside your computer's memory awaiting for a value to be stored. So how can we store values to each of the array elements? Array's value can be accessed and modified by indicating their index or position.
numbers[0] numbers[1] numbers[2] numbers[3] numbers[4] = = = = = 1; 2; 3; 4; 5;

Index starts with 0 and ends with (length - 1) of the array. For example, we have 5 elements so the indices of our array starts from 0 and ends with 4 because length - 1 equates to 5 - 1 which is 4. That means that index 0 is the first element, index 1 is the second element and so on. Look at the image below to better understand this concept.

Figure 1 Consider each square is an array element and the values inside them are the values they contain. Newbie programmers often get confused by the index resulting to errors such as starting the count from 1 to 5. If you access an array element with an index that's not inside the range of valid indexes, then you will get an IndexOutOfRangeException which simply says that you are

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

accessing an address that does not exist. Just remember the formula and you won't have any problems. If you want to assign values immediately in the declaration of a variable, you can do a modified version of the declaration of an array.
datatype[] arrayName = new datatype[length] { val1, val2, ... valN };

You can enumerate the values inside curly braces immediately after the declaration of the size of the array. You should seperate the values with commas. The number of values inside the curly braces should exactly match the size of the array declared. Lets look at an example.
int[] numbers = new int[5] { 1, 2, 3, 4, 5 };

This will have the same results as the code in Figure 1 but it save us a lot of lines of code. You can still change the values of any element by accessing its index and assigning a new value. Our numbers array requirs 5 elements so we supplied it with 5 values. If we are to supply less or more than it requires, we will encounter an error. There is another way of declaring an array. You can supply an array with any number of values as long as you do not indicate the size. Here's an example:
int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

We are now giving 10 values to the array. Notice that there's no length indicated for the array. If this is the case, the compiler will count the number of values inside the curly braces and that will determine the length of the array. Note that if you do not give a length for the array, you need to supply values for it. If not, you will receive an error.
int[] numbers = new int[]; //not allowed

There is a shorter version for doing the this:


int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

We simply assign the values inside curly braces without using the new keyword and the data type. This will also assign all of the 10 values into the array and automatically counts the length that the array should have.

Accessing Array Values Using for Loop


The following is an example of using arrays. Our program will retrieve 5 values from the user and then calculate the average of those numbers.
1 using System; 2 3 namespace ArraysDemo 4 { 5 public class Program

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29}

{ public static void Main() { int[] numbers = new int[5]; int total = 0; double average; for (int i = 0; i < numbers.Length; i++) { Console.Write("Enter a number: "); numbers[i] = Convert.ToInt32(Console.ReadLine()); } for (int i = 0; i < numbers.Length; i++) { total += numbers[i]; } average = total / (double)numbers.Length; Console.WriteLine("Average = {0}", average); } }

Example 1 - Using Arrays


Enter a Enter a Enter a Enter a Enter a Average number: number: number: number: number: = 86 90 85 80 87 92

Line 9 declares an array that can hold 5 integer values. Lines 10 and 11 declares variables that will be used on calculating the average. Note that total is initialized to 0 to avoid errors when adding values to it. Lines 13-17 uses a for loop that will repeat on getting input form the user. We used the Length property of the array to determine the number of elements it contains. Although we can simply specify the value 5 in the condition, using the Length property is more versatile as we can change the length of the array and the condition in the for loop will adjust to the new change. Line 16 retrieves input from the user, converts it to int, and stores it on an array element. The index uses the current value of i. For example, at the beginning of the loop, i is initialized to 0, so when Line 16 is first encountered, it will add the value retrieve by the user to numbers[0]. After the loop, i is incremented by 1, and one Line 16 is reached again, it will now assign the retrieve value to numbers[1]. It will continue as long as the for loop meets the condition. Lines 19-22 uses another for loop to access each value of the numbers array. We used the same technique of using the counter variable as the index. Each element of the numbers is added to variable total. After the end of the loop, we can now calculate the average (line 24). We divide the value of total by the number of elements of the numbers array. To access the number of elements of numbers, we used again the Length property of the array. Note that we converted the
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

value of the Length property to double so the expression will yield a double result which includes the fractional part of the result. If we don't convert any of the operands of the division, then it will yield an integer result which does not include the fractional or decimal part of the result. Line 26 displays the calculated average. Array's length cannot be changed once it was initialized. For example, if you initialize an array to contain only 5 element, then you cannot resize the array to contain, for example, 10 elements. A special set of classes acts the same as the array but is capable of resizing the number of elements they can contain. Arrays are very useful in many situations and it is important that you master this concept and how they can be used.

The foreach Loop


The foreach loop is yet another looping structure in C# which is specially designed for arrays, lists, and collections.The foreach loop cycles through each of the elements, placing the element's value into a temporary variable. You can access the element's value through that temporary variable. Below shows the syntax of using a foreach loop.
foreach (datatype temporaryVar in array) { code to execute; }

The temporaryVar is the variable that will hold the values of the elements of the array. The temporaryVar should have a data type capable of storing the value of an element in the array. For example, if you have to cycle through an array of int numbers, the the data type of the temporary variable should be int as well or any data type that can store int such as double or long. In objects inheriting other objects, the type of a variable could be the type of any object it inherits. Then we write the in keyword and then the name of the array in which the foreach loop will get the values one by one. Below is an example of using the foreach loop.
1 using System; 2 3 namespace ForeachLoopDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 int[] numbers = { 1, 2, 3, 4, 5 }; 10 11 foreach (int n in numbers) 12 { 13 Console.WriteLine("Number {0}", n); 14 } 15 } 16 } 17}

Example 1 - Using the foreach Loop


COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Number Number Number Number Number

1 2 3 4 5

The program declares a 5-element array with values of 1 to 5 (line 9). Line 11 starts the foreach loop. We declare a temporary variable that will hold the values from the numbers array. For each loop cycle of the foreach loop, the temporary variable n extracts a value from the numbers array. The foreach loop gets the value from the first element up to the last element .Unlike a for loop, you cannot control the sequence of how the foreach loop gets the value unless you use custom iterators which is an advanced topic. The foreach loop is good if you want to get each of the values in an array. After getting the value of an element in the array, we print the value of the temporary variable. There's one downfall when considering using foreach loops. foreach loops are limited to accessing or reading the data. They cannot modify the elements of an array. To understand this, the code below tries to increment the value of each of the element of an array.
int[] numbers = { 1, 2, 3 }; foreach(int number in numbers) { number++; }

Run the program and it will give you an error. If you want to modify each element, then use a for loop instead.
int[] numbers = { 1, 2, 3 }; for (int i = 0; i < number.Length; i++) { numbers[i]++; }

Multidimensional Arrays
Multidimensional arrays are arrays that uses more than one index to access its content. Imagine a table with rows and columns, a multidimensional array can represent its data in a way a table can. Adding more indices increases the dimension of an array and makes it even more complex although it is very rare to use a multidimentional array that uses indexes more than two. The syntax of a multidimensional array that has two dimensions is as follows.
datatype[,] arrayName = new datatype[lengthX, lengthY];

And a multidimentional array with three dimensions has the following syntax.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

datatype[, ,] arrayName = new datatype[lengthX, lengthY, lengthZ];

You can create an array with as much dimension as you can where each dimension is specified by a length. Because using 3-dimensional arrays or arrays with dimensions more than 2 are rare, let's concentrate this lesson on using 2-dimensional arrays. The syntax requires the datatype which is the type that the elements of that array possess. Next to the type is a pair of square brackets and a comma inside it. Note the number of commas to place inside the brackets. If we have a 2 dimension array, we place 1 comma and if we have a 3 dimension array, we put 2 commas so to find out how many commas to put, just remember (numberOfDimensions - 1). Next, we write the name of the variable and then we assign the dimension lengths by writing the new keyword, the data type and the lengths. In a 2-dimensional array, we need to give two length values, one for the x value and one for the y value where x represents the row of a table and y represents the column of a table if we look at it as a table. A three dimensional array can be represented by a cube like the word "3-D" suggest so the x would be the height, y would be the width, and z would be the depth. Let's look at an example of 2-dimensional array.
int[,] numbers = new int[3, 6];

The code above tells the compiler to allocate enough space for (3 * 6) array elements. The picture below shows where each array elements will be mapped if we think of them as cells in a table.

Figure 1 We pass 3 for the lengthX thats why we have 3 rows and we gave 5 for lengthY thats why we have 5 columns. How do we initialize values in a multidensional array? There are multiple ways of initializing values in a multidimensional array.
datatype[,] arrayName = new datatype[x, y] { { r0c0, r0c1, ... r0cX }, { r1c0, r1c1, ... r1cX },

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

. . . { rYc0, rYc1, ... rYcX } };

To make it even simpler, you can ignore writing the new dataype[,] part.
datatype[,] arrayName = { { r0c0, r0c1, ... r0cX }, { r1c0, r1c1, ... r1cX }, . . . { rYc0, rYc1, ... rYcX } };

Here's an example:
int[,] numbers = { { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 10 }, { 11, 12, 13, 14, 15 } };

Or do everything manually and assign values to each element one by one like this:
array[0, array[0, array[0, array[1, array[1, array[1, array[2, array[2, array[2, 0] 1] 2] 0] 1] 2] 0] 1] 2] = = = = = = = = = value; value; value; value; value; value; value; value; value;

As you can see, accessing a 2-dimensional array's element is as simple as indicating the x index and y index of the element inside a pair of brackets seperated by a comma.

Iterating through a Multidimentional Array


Iterating through a multidimensional array can be a bit tricky. The easiest way perhaps is to use a foreach loop. You can also use a nested for loop. Let's take a look at using foreach loop first.
1 using System; 2 3 namespace MultidimensionalArraysDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 int[,] numbers = { { 1, 2, 3, 4, 5 }, 10 { 6, 7, 8, 9, 10 }, 11 { 11, 12, 13, 14, 15 } 12 };

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

13 14 15 16 17 18 19 20}

foreach (int number in numbers) { Console.Write(number + " "); } } }

Example 1 - Iterating through a Multidimensional Array


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

You can see how simple is it to cycle through the values of each element of a multidimensional array by just using a foreach loop. By using a for each loop, we won't be able to detect the end of a row in case we want to bring the next row to the next line. You can easily do that with the for each loop. The following program shows you how to use the for loop to read all the values in an array.
1 using System; 2 3 namespace MultidimensionalArraysDemo2 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 int[,] numbers = { { 1, 2, 3, 4, 5 }, 10 { 6, 7, 8, 9, 10 }, 11 { 11, 12, 13, 14, 15 } 12 }; 13 14 for (int row = 0; row < numbers.GetLength(0); row++) 15 { 16 for (int col = 0; col < numbers.GetLength(1); col++) 17 { 18 Console.Write(numbers[row, col] + " "); 19 } 20 21 //Go to the next line 22 Console.WriteLine(); 23 } 24 } 25 } 26}

Example 2 - Using a foreach Loop on a Multidimensional Array


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We can't just use a plain for loop when accessing a multidimensional array. We need to use a nested for loop. On the first for loop (line 14), we declared a variable which will loop through all the "rows" of our multidimensional array. It will loop until the value of row is less then the length of the first dimension. We used the method GetLength() of the Array class. This method gets the length of the array in a specified dimension. It has one parameter and that's the dimension of the array. For example, to get the length of the first dimension of the array, we pass 0 as the value because it counts the dimension of an array from 0 to numberOfDimensions - 1. Inside the first for loop is yet another for loop (line 16). We declared another counter that will loop through all the "columns" of the current row in the loop cycle of the first loop. The condition involves using the method GetLength() again but this time, we pass 1 instead to get the length of the second dimension of the array. So for example, the current value of row is 0, then the second for loop will loop from [0, 0] up to [0, 4]. We then show a value of the current element in the loop, if the value of row is 0 and the value of col is 0, then it will show the value of numbers[0, 0]. After the second loop has finished doing the loop, it will execute the command immediately after it, in this case, the next line informs the program to go to the new line. The first loop will then repeat all of this process with the value of row increment incremented by 1. We will then repeat the second for loop and display the values of the second row. The process will repeat until the row is less than the length of the first dimension. Let's apply what we have learn to make a program that get four grades of each of the three students. The program will determine the average grade for each student.
1 using System; 2 3 namespace MultidimensionalArrays3 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 double[,] studentGrades = new double[3, 4]; 10 double total; 11 12 for (int student = 0; student < studentGrades.GetLength(0); 13student++) 14 { 15 total = 0; 16 17 Console.WriteLine("Enter grades for Student {0}", student + 181); 19 20 for (int grade = 0; grade < studentGrades.GetLength(1); 21grade++) 22 { 23 Console.Write("Enter Grade #{0}: ", grade + 1); 24 studentGrades[student, grade] = 25Convert.ToDouble(Console.ReadLine()); 26 total += studentGrades[student, grade]; 27 } 28 29 Console.WriteLine("Average is {0:F2}",

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

30 31 32 } } }

(total / studentGrades.GetLength(1))); Console.WriteLine(); }

Example 3 - Multidimensional Array Application


Enter grades for Student 1 Enter Grade #1: 92 Enter Grade #2: 87 Enter Grade #3: 89 Enter Grade #4: 95 Average is 90.75 Enter grades for Student 2 Enter Grade #1: 85 Enter Grade #2: 85 Enter Grade #3: 86 Enter Grade #4: 87 Average is 85.75 Enter grades for Student 3 Enter Grade #1: 90 Enter Grade #2: 90 Enter Grade #3: 90 Enter Grade #4: 90 Average is 90.00

The program declares a multidimensional array of type double (line 9) because we are storing grades. We also declare a variable total (line 10) that will be used soon for calculating the average of each student. We now enter the nested for loop (line 12). On the first for loop, we declare a student variable that will determine which of the student the program will ask the grades for. We use GetLength() to determine the number of students. We enter the for loop body. Line 14 assigns a value of 0 to variable total. We will know later why we did this. The program displays a prompt telling you to enter the grade of student number (student + 1). We add 1 to the student so that instead of displaying Student 0, it starts with 1 which is more natural. We then arrive at the second for loop (line 18). We declare a counter variable grade and get the length of the second dimension of the array by calling GetLength(1). This length determines the number of grades the program will ask. The program will get each of the four grades for the current student. Each time the program gets grade from the user, the grade obtained will be added to the total variable. When all the grades have been entered, the total variable already contains the sum of those grades. Lines 25-26 will now display the average grade of the current student. Take note of the {0:F2}. This formats the grade into a fixed number with 2 decimal places. The average is then calculated by dividing the sum by the number of grades. We used GetLength(1) again to get the number of grades. The average grade is then displayed.

Jagged Arrays
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Jagged Arrays are multidimensional arrays containing rows of varying lengths. A simple multidimensional array is rectangular because it's rows has the same number of columns but jagged arrays can have different lengths for each of it's rows. Therefore, jagged arrays can also be called arrays of arrays. Below shows the syntax of declaring a jagged array.
datatype[][] arrayName;

We write the data type followed by two sets of square bracket to indicate that it is a jagged array. Initializing jagged arrays with values is quite confusing. The following is an example of one way of initializing a jagged array.
int[][] myArrays = new int[3][]; myArrays[0] = new int[3]; myArrays[1] = new int[5]; myArrays[2] = new int[2];

Figure 1 First, we declared the number of "rows" of the jagged array by using the new keyword, the data type and two pairs of square brackets with number of rows inside the first pair. Then we give the number of columns for each row by accessing those three rows by their indices and initializing them like normal arrays. You can give each row a set of values for their columns.
int[][] myArrays = new int[3][]; myArrays[0] = new int[3] { 1, 2, 3 }; myArrays[1] = new int[5] { 5, 4, 3, 2, 1 }; myArrays[2] = new int[2] { 11, 22 };

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Another clever way of initializing a jagged array is as follows.


int[][] myArrays = new int[3][] { new int[3] { 1, 2, 3 }, new int[5] { 5, 4, 3, 2, 1 }, new int[2] { 11, 22 } };

Also, you can ignore specifying the lengths of each row by simply not indicating them.
int[][] myArrays = new int[][] { new int[] { 1, 2, 3 }, new int[] { 5, 4, 3, 2, 1 }, new int[] { 11, 22 } };

You can simplify the above code even more.


int[][] myArrays = { new int[] { 1, 2, 3 }, new int[] { 5, 4, 3, 2, 1 }, new int[] { 11, 22 } };

We access a value of an element of a jagged array by indicating its row and column indices.
array[row][column] Console.WriteLine(myArrays[1][2]);

We can't use a single foreach loop to access the each elements of a jagged array.
foreach(int array in myArrays) { Console.WriteLine(array); }

This will produce an error because what we are extracting in the myArrays are arrays as well. So to fix this, we have to change the type of the temp variable into an int array and nest another foreach loop to access the values of that temp array variable.
foreach(int[] array in myArrays) { foreach(int number in array) { Console.WriteLine(number); } }

Alternatively, you can use a nested for loop.


for (int row = 0; row < myArray.Length; row++) { for (int col = 0; col < myArray[row].Length; col++) { Console.WriteLine(myArray[row][col]); } }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

On the first for loop, we access the Length property of myArray to get the number of rows of the jagged array. On the second for loop, we use the Length property of the current row element to get the number of columns. We then print the array element with indices indicated by the current value of row and col.

Methods
Methods let you define a behavior or task which composed of a set of codes that you can execute anywhere in the program. methods can accept arguments which supplements the method's duty. You define a method inside a class. You cannot define a method inside another method. We will see more about methods of classes in later lessons. When a program detects that you are calling a method, it jumps to its definition somewhere in the code and execute its contents. Method promotes software reusability which allows other programmers to effectively use your code just by knowing the parameters and return values of the method. There is one method a program should find in order to start a program, and that is the Main method. The Main method serves as the starting point of the program. Without it, the program doesn't know where to start its execution. Parameters are what a method is expecting to receive. Arguments are the values you pass in the parameters of the method. Sometimes, the terms parameters and arguments are used interchangeably. The basic syntax of the simplest method is as follows.
returnType MethodName() { code to execute; }

Lets look at an example program that uses a simple method that prints a message in the screen.
1 using System; 2 3 namespace MethodsDemo 4 { 5 public class Program 6 { 7 static void PrintMessage() 8 { 9 Console.WriteLine("Hello World!"); 10 } 11 12 public static void Main() 13 { 14 PrintMessage(); 15 } 16 } 17}

Example 1 - Your First Method


Hello World!

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

In lines 7-10, we declared our first method. The position inside the class is not important. For example, you can place it below the Main() method instead. You can call (or invoke) this method inside other methods. Write now, we only have Main() as the other method who can possible call PrintMessage(). You can see that the Main() method is declared as static. For the PrintMessage() method to be used by the Main() method, it needs to be static also. static simply means that the method can be used without creating an instance of the class. The Main() method always requires that it is declared static because the program will use it immediately without creating an instance of the Program class. We will look closely on the static keyword when we reach the topic of Object Oriented Programming. The Program class is being executed when the program runs so both the method we defined and the Main method should be static. We we'll learn more about this keyword in later lessons. Continuing with the method we are creating, after the word static is the keyword void which indicates that the method will not return or give back a value. Next lesson will demonstrate you how you can return values from a method and use that returned value for different purposes. We then name our method PrintMessage. Notice that we used Pascal Casing on naming our method. This is a convention in C# and can be ignored but I do recommend to stick to this convention so that you can easily distinguish a method. Also, when naming methods, use verbs because methods are like actions so naming them GoToBed, OpenDoor, Calculate is a good practice. In cases where it will return a bool data, you can name your method with a question such is IsLeapyear, IsTeenager, DoneEating but refrain from adding a question mark after the names. The pair of parentheses following the name is required to indicate that it is a method. Currently, it has nothing between the parentheses because it has no parameters which will be introduced in a later lesson. We placed a set of curly braces which wraps the body of the method and inside it, we write the code that we will execute. Inside our Main() method, we called the method we created in line 14. To call a method, simply write its name followed by parentheses. If the method has parameters, then you must placed the arguments between the parentheses in the proper order. This will be demonstrated later. Calling the method will execute the code that the method contains inside its body. The execution will jump from the Main() method to the starting point of the PrintMessage() method. For example, when we called the PrintMessage() method in line 14, the program jumps from line 14 to line 9 where the beginning of the method to be called is located. Since we now have a method defined in our Program class, all the methods of the Program class can call the method we created.

Returning Values from a Method


Methods can return values of any data type. These values can be used for calculations or obtaining data that the method has calculated. In a real life scenario, imagine that the method is your employee and you called him to finish some documents. You are then expecting to receive the finished documents from him. Those documents are considered the return value of a method. In fact, when looking at a method, one important thing to know is the value it will return so you will know how to process the returned values. Returning a value from a method is easy, just follow the syntax below when creating a method which returns a value.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

returnType MethodName() { return value; }

The returnType here is the data type of the value that the method will return to the caller. Inside a method, we use the return keyword followed by a value or an expression that will result in a value. The value's data type to be returned should have a similar data type with the one indicated in the method header. If we are not returning a value, we should use void as the return type. Figure 1 shows an example of a method that will return a value.
1 using System; 2 3 namespace ReturningValueFromMethodDemo 4 { 5 public class Program 6 { 7 static int CalculateSum() 8 { 9 int firstNumber = 10; 10 int secondNumber = 5; 11 12 int sum = firstNumber + secondNumber; 13 14 return sum; 15 } 16 17 public static void Main() 18 { 19 int result = CalculateSum(); 20 21 Console.WriteLine("Sum is {0}.", result); 22 } 23 } 24}

Example 1 - Returning a Value from the Method


Sum is 15.

As you can see in line 7 of Example 1, we used int as the return type in the method header instead of void because we are expecting an int value to be returned. Lines 9-10 declares two variables and initialize them with values. Note that these variables are local variables. It means that it cannot be accessed by other methods such as the Main method. They can only be used by the method who owns them. Line 12 determines the sum of 2 numbers and then assigned to the sum variable. Line 14 returns the value of sum to the caller using a return statement. Inside the Main() method, we declared a variable in line 19 and called the CalculateSum() method. The CalculateSum() method returns the value 15 which is the result of the expression inside its body. The value returned is assigned to result variable. Line 21 prints the result containing the returned value.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The method in Example 1 is not very useful. We hardcoded a value inside a method and it will always return one value which is 15. You can simply assign the value 15 in the result variable. This method will be more useful if we add parameters in a the method. This will be discussed in the next lesson. When doing decisions inside a method such as using an if or switch statement, all code paths must return a value. This is better demonstrated by the following code example.
1 using System; 2 3 namespace ReturningValueFromMethodDemo2 4 { 5 public class Program 6 { 7 static int GetNumber() 8 { 9 int number; 10 11 Console.Write("Enter a number greater than 10: "); 12 number = Convert.ToInt32(Console.ReadLine()); 13 14 if (number > 10) 15 { 16 return number; 17 } 18 else 19 { 20 return 0; 21 } 22 } 23 24 public static void Main() 25 { 26 int result = GetNumber(); 27 28 Console.WriteLine("Result = {0}.", result); 29 } 30 } 31}

Example 2 - All Code Paths Must Return a Value


Enter a number greater than 10: 11 Result = 11 Enter a number greater than 10: 9 Result = 0

Lines 7-22 defines a method named GetNumber() which asks a user of a number which is greater than 10. Failing to give the proper number, the method will return 0. If we are to omit the else part(lines 18-21) of the if statement or we didn't supply a return statement inside its body, an error will show up when compiling the code. That's because if the condition of the if statement results to false, the path that the program will follow doesn't have a return statement which is an error because the method is expected to return a value.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

One last thing I want to imply in this lesson. You can exit a method that has no return type. Even if you use the data type void for a method, you can still use the return keyword. Using the return keyword in a method that has no return type exits the method and continue to the next code of the statement that called the method.
1 using System; 2 3 namespace ReturningValueFromMethodDemo3 4 { 5 public class Program 6 { 7 static void TestReturnExit() 8 { 9 Console.WriteLine("Line 1 inside the method 10 Console.WriteLine("Line 2 inside the method 11 12 return; 13 14 //The following lines will not execute 15 Console.WriteLine("Line 3 inside the method 16 Console.WriteLine("Line 4 inside the method 17 } 18 19 public static void Main() 20 { 21 TestReturnExit(); 22 Console.WriteLine("Hello World!"); 23 } 24 } 25}

TestReturnExit()"); TestReturnExit()");

TestReturnExit()"); TestReturnExit()");

Example 3 - Returning from a void type Method


Line 1 inside the method TestReturnExit() Line 2 inside the method TestReturnExit() Hello World!

The program demonstrates that using the return keyword(line 12) immediately take you out from the method, ignoring all the codes that follow the return statement. The next line following the method call inside the Main method is then executed.

Parameters and Arguments


Parameters gives a method something to play with. They are like raw informations that the method will process to give you the data you are looking for. Imagine parameters as informations you give to an employer that he needs in order to finish his job. Consider a method that calculates the sum of two values for example. In order for that method to be flexible and useful, parameters are needed. A method can have any number of parameters. Each parameter can have different data types. Below shows the syntax of a method with N parameters.
returnType MethodName(datatype param1, datatype param2, ... datatype paramN)

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

{ code to execute; }

The parameters are placed between the parentheses following the MethodName. You can have as many parameters as you want as long as they are essential for the job of the method. When calling the method, you must provide the arguments. The arguments are the values that will be assigned to each of the parameters. The order is important when passing arguments in a method. Failure to follow the right order or sequence of providing the arguments can lead to logic and runtime errors. Lets demonstrate all of this by looking at an example.
1 using System; 2 3 namespace ParametersDemo 4 { 5 public class Program 6 { 7 static int CalculateSum(int number1, int number2) 8 { 9 return number1 + number2; 10 } 11 12 public static void Main() 13 { 14 int num1, num2; 15 16 Console.Write("Enter the first number: "); 17 num1 = Convert.ToInt32(Console.ReadLine()); 18 Console.Write("Enter the second number: "); 19 num2 = Convert.ToInt32(Console.ReadLine()); 20 21 Console.WriteLine("Sum = {0}", CalculateSum(num1, num2)); 22 } 23 } 24}

Example 1 - Methods with Parameters


Enter the first number: 10 Enter the second number: 5 Sum = 15

The program in Example 1 declared a method named CalculateSum (lines 7-10) which calculates the sum of two values provided by the user. The method returns the sum of two integer values therefore we indicate the return type as int. The method has two parameters which are the numbers to be added. Note at the data types of the parameters. The first parameter named number1 is expecting an int value and the second parameter named number2 is expecting also an int value. In the body, the return statement returns the result of the expression that adds the two values. Inside method Main, the program asks the user for two values and assign them inside variables. We then call the method providing the two arguments inside the parentheses. The value of num1
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

will be passed to the first parameter of the method and the value of num2 will be passed to the second parameter of the method. Right now, interchanging the position of the two values when calling the method has no effect since addition is commutative. Just keep in mind that the position of the arguments when calling a method must exactly match the order of the paramters in the method declaration. After passing the values 10 and 5 to the method parameters, the parameters now has those values. Note that parameter names, by convention, uses camelCasing. Inside the method body, line 9 adds the two values using an addition expression and the result is returned to the caller. Last lesson, we used a variable to hold the results, but as you can see now, we can simply provide the expression and return the results immediately. Inside the Main() method, we asks the user of two numbers that will be added together. Line 21 calls the CalculateSum() method and we passed the two integer values given by the user. The two integer is added inside the method and their sum is returned to the caller. The returned value is then displayed by the Console.WriteLine() method. Lets look at another program but this time, we will be using two parameters with different data types.
1 using System; 2 3 namespace ParametersDemo2 4 { 5 public class Program 6 { 7 static void ShowMessageAndNumber(string message, int number) 8 { 9 Console.WriteLine(message); 10 Console.WriteLine("Number = {0}", number); 11 } 12 13 public static void Main() 14 { 15 ShowMessageAndNumber("Hello World!", 100); 16 } 17 } 18}

Example 2 - Another Example of Using Parameters


Hello World! Number = 100

Example 2 shows a method (lines 7-11) accepting a string value for the first parameter and an int for the second. The method simply displays the two values passed to it. Line 15 calls the method we created. We specified a string message first and then the number. If for example, we called the method like this:
ShowMessageAndNumber(100, "Welcome to Gimme C#!");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The above statement will produce an error since 100 will be passed to the string parameter and the message "Hello World!" will be passed to the int parameter. This shows that the order of the arguments when calling the method is very important. Consider the program in Example 1. It required us to pass 2 numbers of int type. If that is the case, we can supply the values in any order. But if the method parameters have specific purposes, the order must be considered.
void ShowPersonStats(int age, int height) { Console.WriteLine("Age = {0}", age); Console.WriteLine("Height = {0}", height); } //Using the proper order of arguments ShowPersonStats(20, 160); //Acceptable, but produces odd results ShowPersonStats(160, 20);

The example above shows that even if the method accepts two parameters of the same data type, each parameter has a specific purpose. The first call is valid because the age of the person will be 20 and his/her height will be 160cm. If we are to switch the positions of the arguments, the person's age will be 160 and his/her height will be 20cm which is not so realistic. Knowing the principle of returning values and passing arguments, you do many complex things. The following code snippet shows you that you even pass a returned value of a method as an argument to another method.
int MyMethod() { return 5; } void AnotherMethod(int number) { Console.WriteLine(number); } // Codes skipped for demonstration AnotherMethod(MyMethod());

The above code will have an output of 5 since MyMethod() returned 5 and that value was passed as an argument to the AnotherMethod(). Again, mastering the concept of returning and passing values will allow you to make more complex codes.

Named Arguments
Another way of passing arguments is by using named arguments. Named arguments free you from remembering or following the order of the parameters when passing arguments. In exchange, you have to memorize the names of the parameters of a method (but since Visual

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Studio has Intellisense, you don't have to do so). Named arguments improve readability because you can see what values are assigned to what parameters. Named argument is introduced in C# 2010 so if you are using an older version such as C# 3.5 (2008), then this won't work. The following example shows the syntax of using named arguments when calling a method.
MethodToCall( paramName1: value, paramName2: value, ... paramNameN: value);

The program in Figure 1 demonstrates how to use named arguments.


1 using System; 2 3 namespace NamedArgumentsDemo 4 { 5 public class Program 6 { 7 static void SetSalaries(decimal jack, decimal andy, decimal mark) 8 { 9 Console.WriteLine("Jack's salary is {0:C}.", jack); 10 Console.WriteLine("Andy's salary is {0:C}.", andy); 11 Console.WriteLine("Mark's salary is {0:C}.", mark); 12 } 13 14 public static void Main() 15 { 16 SetSalaries(jack: 120, andy: 30, mark: 75); 17 18 //Print a newline 19 Console.WriteLine(); 20 21 SetSalaries(andy: 60, mark: 150, jack: 50); 22 23 Console.WriteLine(); 24 25 SetSalaries(mark: 35, jack: 80, andy: 150); 26 } 27 } 28}

Example 1 - Using Named Arguments


Jack's salary is $120. Andy's salary is $30. Mark's salary is $75. Jack's salary is $50. Andy's salary is $60. Mark's salary is $150. Jack's salary is $80. Andy's salary is $150. Mark's salary is $35.

The WriteLine() methods in lines 9-11 used the currency formatter indicated by {0:C} which formats a numerical data into a monetary format. The output shows that even if we change the
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

order of the arguments in the three method calls, the proper values are still assigned to their respective parameters. You can mix named arguments and fixed arguments that depend on the position of the parameter.
//Assign 30 for Jack's salary and use named arguments for // the assignment of the other two SetSalary(30, andy: 50, mark: 60); // or SetSalary(30, mark: 60, andy: 50); //The following codes are wrong and will lead to errors SetSalary(mark: 60, andy: 50, 30); // and SetSalary(mark: 60, 30, andy: 50);

As you can see, you need to placed the fix arguments first. On the first and second examples, we give 30 as the first argument so it was assigned to jack since he is the first parameter of the method. The third and fourth examples are wrong since you indicated the named parameters first before the fixed parameter. Always placed the named parameters after defining the fixed arguments to prevent an error.

Passing Arguments by Reference


Arguments can be passed by reference. That simply means that we are passing the address of the variable and not its value. Pass by reference are useful when you are passing large-sized arguments such as objects. When we modify or use the passed argument inside the method, the originating source or the variable that we are referring outside the method is modified as well. The following is the basic syntax of defining parameters that will accept address instead of values.
returnType MethodName(ref datatype param1) { code to execute; }

You noticed that we used the ref keyword. When calling the method and passing the argument, we use the ref keyword as well.
MethodName(ref argument);

Let's demonstrate the difference of passing an argument by value and passing it by reference.
1 using System; 2

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

3 namespace PassByReferenceDemo 4 { 5 public class Program 6 { 7 static void ModifyNumberVal(int number) 8 { 9 number += 10; 10 Console.WriteLine("Value of number inside method is {0}.", 11number); 12 } 13 14 static void ModifyNumberRef(ref int number) 15 { 16 number += 10; 17 Console.WriteLine("Value of number inside method is {0}.", 18number); 19 } 20 21 public static void Main() 22 { 23 int num = 5; 24 25 Console.WriteLine("num = {0}\n", num); 26 27 Console.WriteLine("Passing num by value to method 28ModifyNumberVal() ..."); 29 ModifyNumberVal(num); 30 Console.WriteLine("Value of num after exiting the method is 31{0}.\n", num); 32 33 Console.WriteLine("Passing num by ref to method 34ModifyNumberRef() ..."); ModifyNumberRef(refnum);; ConsoleConsole.WriteLine("Value of num after exiting the method is {0}.\n", num); } } }

Example 1 - Passing Arguments by Reference


num = 5 Passing num by value to method ModifyNumberVal() ... Value of number inside method is 15. Value of num after exiting the method is 5. Passing num by ref to method ModifyNumberRef() ... Value of number inside method is 15. Value of num after exiting the method is 15.

The program in Example 1 defined two methods that has the same purpose, to add 10 to the values passed to them. The first one (lines 7-11) requires a parameter that accepts an argument's value. When we call it and supply an argument (line 26), the argument's value is copied to the parameter of the method. Therefore, the value of the original variable outside the method has no
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

link or relation to the parameter of the method. We then added 10 to the parameter variable and print the result. To prove that the num variable was not affected by the modifiication and it is a different copy, we print again its value and we saw that it did not change. The second method (lines 13-17) requires the caller to pass the value by reference. Instead of copying the value of the argument being passed, the caller gives the address of that variable instead. The parameter now "refers" to the orignial variable that was passed to the method during the method call. When we modified the parameter variable containing the address of the original variable (line 15), we are actually modifying the value of that original variable outside the method. We displayed the value of the original variable after exiting the method and it is apparent that the value was indeed modified.

Out Parameters
Out parameters are parameters that can accept uninitialized variables or arguments. The out keyword is used when passing an uninitialized variable to a method. Uninitialized variables are variables that contains no value or it has not been assigned a value yet. The method should give that uninitialized variable a value. Passing uninitialized variables to a method is usefull when you just want to be supplied with data from a method. Using the out keyword for a argument also passes it by reference and not by value. Let's take a look at the following example program.
1 using System; 2 3 namespace OutParametersDemo 4 { 5 public class Program 6 { 7 static void GiveValue(out int number) 8 { 9 number = 10; 10 } 11 12 public static void Main() 13 { 14 //Uninitialized variable 15 int myNumber; 16 17 GiveValue(out myNumber); 18 19 Console.WriteLine("myNumber = {0}", myNumber); 20 } 21 } 22}

Example 1 - out Parameters Example


myNumber = 10

We used the out keyword for the parameter of the method so that it can hold an uninitialized variable. In the Main method, line 17 calls the method and we precede the argument with the out

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

keyword. The uninitialized variable is passed to the method and there, we assign it a value of 10 (line 9). We displayed the value of myNumber(line 19) and to show that it now contains the value that we assigned inside the method. Using out parameters doesn't mean that you always need to pass an uninitialized argument. In fact, you can still pass an argument that already contains a value. Doing that is equivalent to using the ref keyword.

Arrays as Arguments
You can pass arrays as arguments to a method. You have to specify in the parameters of the method that it will accept an array. Let's take a look at an example.
1 using System; 2 3 namespace ArraysAsArgumentsDemo1 4 { 5 public class Program 6 { 7 static void TestArray(int[] numbers) 8 { 9 foreach (int number in numbers) 10 { 11 Console.WriteLine(number); 12 } 13 } 14 15 public static void Main() 16 { 17 int[] array = { 1, 2, 3, 4, 5 }; 18 19 TestArray(array); 20 } 21 } 22}

Example 1 - Passing Arrays as Arguments


1 2 3 4 5

We simply put square brackets after the data type of the parameter of the method to indicate that the parameter is expecting an array. When we call the method in line 19, we just pass the array using its name without the index. This will pass the address of the array to the method. When we used the foreach loop(line 9-12), we access each of the elements of the original array that was passed as the argument to the method. The next program below demonstrates that we are passing the array by reference.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

1 using System; 2 3 namespace ArraysAsArgumentsDemo2 4 { 5 public class Program 6 { 7 static void IncrementElements(int[] numbers) 8 { 9 for (int i = 0; i < numbers.Length; i++) 10 { 11 numbers[i]++; 12 } 13 } 14 15 public static void Main() 16 { 17 int[] array = { 1, 2, 3, 4, 5 }; 18 19 IncrementElements(array); 20 21 foreach (int num in array) 22 { 23 Console.WriteLine(num); 24 } 25 } 26 } 27}

Example 2 - Array Arguments Are Passed by Reference


2 3 4 5 6

The program above presented a method that accepts an array and then increment each of its element. Note that we didn't use a foreach loop to increment the values of each of the element because foreach loops are only suitable for reading each element and not modifying them. Inside the method, we increment the value of each element of the array. After exiting the method, we displayed the results and as you can see, the original values of the method are also modified. Another way of passing an array to a method is by giving the values directly in the method call. For example:
IncrementElements( new int[] { 1, 2, 3, 4, 5 } );

We didn't declared an array. Instead, we pass a set of values to the parameter that is expecting an array. Since there was no array variable that was declared, we cannot use it in the Main method for displaying the results.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

If there are multiple parameters in a method, always place square brackets for each of the parameter the will expect n array. For example:
void MyMethod(int[] param1, int param2) { //code here }

Looking at the header, param1 is expecting an array argument, but param2 is accepting a normal int number. You must put square brackets if param2 should also accept an array.
void MyMethod(int[] param1, int[] param2) { //code here }

The params Keyword


The params keyword lets you pass any number of arguments that has the same data type and then store them into one single array parameter. The code below demonstrates how to use the params keyword.
using System; 1 2 namespace ParamsKeywordDemo 3 { 4 public class Program 5 { 6 static int CalculateSum(params int[] numbers) 7 { 8 int total = 0; 9 10 foreach (int number in numbers) 11 { 12 total += number; 13 } 14 15 return total; 16 } 17 18 public static void Main() 19 { 20 Console.WriteLine("1 + 2 + 3 = {0}", CalculateSum(1, 2, 3)); 21 22 Console.WriteLine("1 + 2 + 3 + 4 = {0}", CalculateSum(1, 2, 3, 234)); 24 25 Console.WriteLine("1 + 2 + 3 + 4 + 5 = {0}", CalculateSum(1, 2, 263, 4, 5)); 27 28 } 29 } }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Example 1 - Using the params Keyword


1 + 2 + 3 = 6 1 + 2 + 3 + 4 = 10 1 + 2 + 3 + 4 + 5 = 15

We used the params keyword before the data type of the array parameter. We then called the method three times supplying different number of arguments. These arguments are stored inside the array parameter. Using a foreach loop (line 11-14), the sum of all the elements is determined and returned to the caller. When you have multiple parameters in a method, you can only have one parameter that is labeled with params. This parameter labeled with params should be placed in the last position of the parameter list. If it is not in the last position or there are more than one params paramater, an error will occur. The three method headers below shows you which is right and which are wrong.
void SomeFunction(params int[] x, params int[] y) //ERROR void SomeFunction(params int[] x, int y, int z) //ERROR void SomeFunction(int x, int y, params int[] z) //Correct

Variable Scopes
Variables in C# have scope. Scope tells where the variable is available or where in the program it can be accessed. For example, variables declared inside a method can only be accessed inside that method's body. We can have two variables with similar names as long as they exist in diffent methods. The program below demonstrates this concept.
1 using System; 2 3 namespace VariableScopeDemo 4 { 5 public class Program 6 { 7 static void DemonstrateScope() 8 { 9 int number = 5; 10 11 Console.WriteLine("number inside method DemonstrateScope() = 12{0}", number); 13 } 14 15 public static void Main() 16 { 17 int number = 10; 18 19 DemonstrateScope(); 20 21 Console.WriteLine("number inside the Main method = {0}",

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

22number); 23 } } }

Example 1
number inside method DemonstrateScope() = 5 number inside the Main method = 10

You can see that even if we declared two variables with the same name, they are in different scopes. Each of them was assigned different values. The variable inside the Main() method is not related to the variable inside the method DemonstrateScope(). We will learn more about this when we reach the topic of classes.

Optional Parameters
Optional parameters, as the name suggests, are optional and you have a choice whether to provide the argument or not. Optional parameters are assigned with default values. If you do not provide or give an argument corresponding to that optional parameter, then the default value will be used instead. Lets look at the program in Figure 1 for an example.
using System; 1 2 namespace OptionalParametersDemo 3 { 4 public class Program 5 { 6 static void PrintMessage(string message = "Welcome to Visual C# 7 Tutorials!") 8 { 9 Console.WriteLine(message); 10 } 11 12 public static void Main() 13 { 14 PrintMessage(); 15 16 PrintMessage("Learn C# Today!"); 17 } 18 } 19 }

Example 1 - Optional Parameters Demo


Welcome to Visual C# Tutorials! Learn C# Today!

The PrintMessage() method has one optional parameter. To declare an optional parameter, simply provide it with a default value by using the assignment operator(=). We called the method twice. In the first call (line 14), we didn't provide an argument so the method used the default
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

message. On the second call(line 16), we passed a message and this message overrides the default message of the optional parameter. If you have multiple arguments, all the optional arguments must come last. The three method headers below shows which are wrong and which is right.
void SomeMethod(int opt1 = 10, int opt2 = 20, int req1, int req2) //ERROR void SomeMethod(int req1, int opt1 = 10, int req2, int opt2 = 20) //ERROR void SomeMethod(int req1, int req2, int opt1 = 10, int opt2 = 20) //Correct

When calling methods with multiple optional parameters, you must still provide values for the optional parameters which are not in the last position. You cannot leave a gap like this:
void SomeMethod(int required1, int optional1 = 10, int optional2 = 20) { //Some Code } // ... Code omitted for demonstration SomeMethod(10, , 100); //Error

If you want to skip an optional argument that is not in the last position, then you must take advantage of using named parameters.
SomeMethod(10, optional2: 100);

To use named arguments, you simple specify the name of the parameter followed by a colon, and the value that will be assigned to the parameter. The above method didn't supply an argument for parameter optional1 therefore, it will use its default value indicated in the method declaration.

Method Overloading
Method overloading allows you to declare two methods with the same name but has different signitures or parameter set. The program will automatcally detect which method you are calling by looking at the arguments you are passing to the method. The signiture of a method shows the data types, the order of the parameters, and the return type. But method overloading only cares about the name and the types and order of the parameters of a method. For example a method below:
void MyMethod(int x, double y, string z)

would have a signature of


MyMethod(int, double, string)

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Note that the return type and the names of the parameter is not included in the signiture of the method. Therefore, you cannot overload a method with another method that has the same name but with a different return type. The example below demonstrate method overloading.
1 using System; 2 3 namespace MethodOverloadingDemo 4 { 5 public class Program 6 { 7 static void ShowMessage(double number) 8 { 9 Console.WriteLine("Double version of the method was called."); 10 } 11 12 static void ShowMessage(int number) 13 { 14 Console.WriteLine("Integer version of the method was called."); 15 } 16 17 static void Main() 18 { 19 ShowMessage(9.99); 20 ShowMessage(9); 21 } 22 } 23}

Example 1 - Method Overloading Demo


Double version of the method was called. Integer version of the method was called.

The program defined two methods with similar names. If method overloading is not supported by C#, then the program will have a hard time choosing which method to use when the name of the method is called. The secret is in the types of the parameters of a method. The compiler can differ two or more methods if they have different set of parameters. When we called the method, it reads the type of the argument. On the first call (line 19), we passed a double value so the ShowMessage() (line 7-10) with double as the parameter was executed. On the second method call (line 20), we passed an int argument so the other ShowMessage() (line 12-15) with int as the argument was executed. It's essential to know method overloading. The big purpose of method overloading is when multiple methods do the same task but only matters on the data that they require. A lot of methods in .NET Classes are overloaded. For example, the Console.WriteLine() method has multiple overloads. You saw that it can accept one string argument which is the string to display, and another version of it accepts 2 or more arguments, the first being the format string.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Recursion
Recursion is a process where a method calls itself repeatedly until it arrives on a desired value. Recursion is a complex topic in programming and mastering it is not that easy. Recursion must stop at some point or else, it will call itself for an infinite number of times. For this lesson, I will show a very simple example of recursion. The factorial of a positive integer n (denoted as n!) is the product of all positive integers less than or equal to n. Consider the factorial of 5.
5! = 5 * 4 * 3 * 2 * 1 = 120

So to make a recursive method, we need to analyze how our method will stop its recursion. Based on the description of recursion, the factorial only accepts a positive integer. The lowest positive integer we can give is 1. We will use this value to stop the recursion.
1 using System; 2 3 namespace FactorialDemo 4 { 5 public class Program 6 { 7 static long Factorial(int number) 8 { 9 if (number == 1) 10 return 1; 11 12 return number * Factorial(number - 1); 13 } 14 15 public static void Main() 16 { 17 Console.WriteLine(Factorial(5)); 18 } 19 } 20}

Example 1 - Factorial Using Recursion


120

The method returns a long value because factorial calculations can be very big. The method accepts one argument which is the number that will be involved in the calculation. Inside the method, we first wrote an if statement in line 9 telling that if the argument provided is equal to 1, then we will return 1 as the value. If it is not 1, then we will proceed in the next line. This condition is also the one that will determine if the repetition of calls should stop. Line 12 multiplies the current value of number and then the method calls itself providing an argument which 1 less than the current value of number. Inside the method called inside the original method, processes will again occur, and if the argument passed is not equal to 1, then it will do another recursive step. The diagram below shows the how we arrived at the final value.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 The above code can be rewritten using a for loop.


factorial = 1; for ( int counter = number; counter >= 1; counter-- ) factorial *= counter;

The above code is easier than its equivalent code that uses recursion. Recursion has its specific use in the field of computer science. Recursion is used when it seems more natural to use it than using a non-recursion version (called Iteration). Recursion consumes more memory so do not use recursion if speed is important.

Delegates
Delegates are types that hold references to methods instead of variables. A delegate can copy the bahavior of any method. To declare a delegate, you use the delegate keyword. Declaring a delegate is similar to declaring a method except that it has no body. It has a return type and a set of parameters just like a method. These tells the type of method it can hold. Below shows the syntax of declaring a delegate.
delegate returnType DelegateName(dt param1, dt param2, ... dt paramN);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The following example program shows how to use and the benefits of using a delegate.
1 using System; 2 3 namespace DelegatesDemo 4 { 5 public class Program 6 { 7 delegate void ArithmeticDelegate(int num1, int num2); 8 9 static void Add(int x, int y) 10 { 11 Console.WriteLine("Sum is {0}.", x + y); 12 } 13 14 static void Subtract(int x, int y) 15 { 16 Console.WriteLine("Difference is {0}.", x - y); 17 } 18 19 static void Main() 20 { 21 ArithmeticDelegate Operation; 22 23 int num1, num2; 24 25 Console.Write("Enter first number: "); 26 num1 = Convert.ToInt32(Console.ReadLine()); 27 28 Console.Write("Enter second number: "); 29 num2 = Convert.ToInt32(Console.ReadLine()); 30 31 if (num1 < num2) 32 { 33 Operation = new ArithmeticDelegate(Add); 34 } 35 else 36 { 37 Operation = new ArithmeticDelegate(Subtract); 38 } 39 40 Operation(num1, num2); 41 } 42 } 43}

Figure 1
Enter first number: 3 Enter second number: 5 Sum is 8 Enter first number: 5 Enter second number: 3 Difference is 2

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Line 7 is the declaration of our delegate. We used the delegate keyword to indicate that it is a delegate. The following is the return type of the method it will accept. The naming practice for a delegate is the same with the method, we used Pascal Casing. We also append the word "Delegate" for better recognition. We defined the parameters of the delegate which will also be the same with the parameters of the method it will hold. The delegate that was declared in line 7 can only accept references to methods that has a void return type (no return type) and has two int parameters. After defining the delegate, we defined two methods with exactly the same signitures as the delegate because they are the methods the delegate will use later. Both methods doesn't return a data and both accepts 2 int arguments. Inside the Main method, we declared a variable with the type of the delegate we defined (line 21). This variable will hold a reference to a method that matches the delegate's signiture.The program asked for two values from the user. We entered an if statement in line 31 wherein, if the value of the first number is less than the second number, then we add them. If the value of the first number is greater than or equal to the number, we subtract them. To assign a method to the delegate, we follow this syntax:
variable = new DelegateName(MethodName);

When assigning a delegate with a reference of the method, we use the new keyword followed by the name of the delegate. Inside the parentheses, we indicate the name of the method the delegate will refer to. A much simpler way is you can just assign the name of the method to the delegate variable.
Operation = Add; Operation = Subtract;

Back to our if statement, when the condition was true, we assigned the delegate the method Add() and when the value was false, we assigned it with the Subtract() method. Line 40 executes our delegate containing the reference of the assigned method. Executing the delegate also executes the method it refers.

Command Line Arguments


To successfully run a C# application, you must provide a Main method. The Main() method is the starting point of the program. It is declared public or internal, and it must also be static. You can actually pass command line arguments to the Main() method. This is demonstrated by the code below.
1 using System; 2 3 namespace CommandLineArgumentsDemo 4 { 5 public class Program 6 { 7 static void Main(string[] args) 8 { 9 string name = args[0];

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

10 11 12 13 14 15 16 17 18}

int counter = Convert.ToInt32(args[1]); for (int i = 1; i <= counter; i++) { Console.WriteLine(name); } } }

Example 1 - Command Line Arguments Notice the parameter args. It is a string array that can accept any number of string arguments. If you build your program and access the .exe file for your program, you can pass string parameters to the Main. For example, open the command prompt, and access your .exe file by moving to the directory where it exists. Below only shows an example but the directory might be different for you. Suppose our .exe is located in C:\Sample Project\bin\Release\.
C:\Sample Project\bin\Release\Sample Bob 5 Bob Bob Bob Bob Bob

We execute the file by writing its file name. After it, we wrote Bob and 5. The first one will be stored in the first element of array args and the second one will be stored in the second element. The the code inside the Main() method does the rest of the job. We stored the first element of args to a variable and we converted the second element of args into int and stored it in an int variable. We then print the name x times by using a for loop. In fact, many program uses this technique. You can pass comman line arguments to modify how a program runs. For example, you can activate a cheat code when you run a game through the command line.

Enumeration
Enumeration is a way of defining your own type that can accept a predefined set of values identified by names. For example, you want a variable that can only store directions such as east, west, north, and south. You can define an enumeration named Direction and declare all the possible values it can have inside the enumeration body. Let's look at the syntax for an enumeration.
enum enumName { value1, value2, value3, . .

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

. valueN }

We used the enum keyword then the name of the enumeration. As a practice in the C# world, enumeration names uses Pascal Casing. Following is the body of the enum. Inside it are the values identified by names. Here is how our Direction enumeration would look like.
enum Direction { North, East, South, West }

By default, the values that an enumeration can store are of type int. For example, North is mapped to the value of 0 and each subsequent values is 1 greater than the last value. So East has a value of 1, South has 2, and West has 3. You can modify this flow by specifying an specific value like this:
enum Direction { North = 3, East = 5, South = 7, West = 9 }

This time, the North has a value of 3, East has a value of 5, South has a value of 7 and West contains a value of 9. If for example you don't assign a value for a value, then an underlying value is given to it automatically.
enum Direction { North = 3, East = 5, South, West }

After East, we didn't assign a value to South, therefore, it's value will be 1 greater than the value of 5 which is 6 and West will have a value of 1 greater than South, which is 7. You can also assign identical values for the enumeration items.
enum Direction { North = 3, East, South = North, West }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Can you guess their values now? The values for North, East, South, and West are 3, 4, 3, 4 respectively. We assign 3 to North so East will have a value of 4. Then we assign the value of South with the value of North which is 3. If South has now a value of 3, then the next one which is West will have a value of 4. Be cautious though when using this technique. If you assign the value of North to South, then these two directions would be equal and you can't walk to North and South at the same time. But in some occasions, you might find using this technique if it is appropriate. If you don't want the values of your enumeration items to be int (which is the default). For example, you can use byte as the type of the enumeration items.
enum Direction : byte { North, East, South, West }

The byte data type can only hold a value of up to 255 so the number of values you can add to the enumeration is quite limited. Lets see how to use an enumeration inside a C# program.
1 using System; 2 3 namespace EnumerationDemo 4 { 5 enum Direction 6 { 7 North = 1, 8 East, 9 South, 10 West 11 } 12 13 public class Program 14 { 15 public static void Main() 16 { 17 Direction myDirection; 18 19 myDirection = Direction.North; 20 21 Console.WriteLine("Direction: {0}", myDirection.ToString()); 22 } 23 } 24}

Example 1 - Enumeration Demo


Direction: North

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

First, we created our enumeration (lines 5-11). Note that we placed our enumeration outside class Program. Doing so will make our enumeration available throughout the program. You can also place the declaration of the enumeration inside a class to make it only available inside that class.
class Program { enum Direction { //Code omitted } static void Main(string[] args) { //Code omitted } }

Continuing with our program in Example 1. Inside the enumeration are the four possible values and each of them are assigned with value 1 to 4. Line 17 declared our variable that will store a Direction value. We follow this syntax:
enumType variableName;

where the enum type is the Enumeration Type such as Direction and the name of a particular enumeration value. After that, we assign a value to myDirection variable (line 19). We used this syntax:
variable = enumType.value;

We wrote the Enumeration type then a period and then the value from that particular enumeration type such as North. You can initialize a variable right away in its declaration like this:
Direction myDirection = Direction.North;

We then print the value of myDirection using Console.WriteLine() (line 21). Notice that we use the method ToString() to convert the value into its string equivalent. Enumeration is such a handy tool that it appears ubiquitously in the .NET Framework. Imagine if there is no enumeration, you have to memorize numbers instead of words since enumeration values are actually numbers being alliased with names defined by you or by other people. You can also perform bitwise operations on numerous .NET enumerations to produce some exciting results as you will see in some of the tutorials in this site. Enumeration variables can also be converted to other types such as int or string or convert a string value to an enumeration equivalent.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Converting Enumerations
You can convert enumerations to other values and vice versa. Enumeration values are actually numeric values that are just masked by their names so that they can easily be understood. Let's take a look at an example.
1 using System; 2 3 namespace ConvertingEnumerationsDemo 4 { 5 enum Direction 6 { 7 North, 8 East, 9 South, 10 West 11 } 12 public class Program 13 { 14 public static void Main() 15 { 16 Direction myDirection = Direction.East; 17 int myDirectionCode = (int)myDirection; 18 19 Console.WriteLine("Value of East is {0}", myDirectionCode); 20 21 myDirection = (Direction)3; 22 Console.WriteLine("\nDirection: {0}", myDirection.ToString()); 23 } 24 } 25}

Example 1
Value of East is 1 Direction: West

In line 16, we assigned the variable myDirection with the value East from the Direction enumeration. With the default values for the items in the enumeration, East should have a value of 1. Line 17 shows you how to convert an enumeration item into its equivalent integer value using casting. The syntax is as follows.
variable = (DestinationDataType)enumerationVariable;

Since myDirectionCode variable is of type int, it is expecting an int to be its value. We simply put the destination type inside a set of parentheses and put that group beside the enumeration variable. The result returned is the converted value. In line 21, we do the reverse. We convert an integer number into an enumeration value. The value 3 equates to the enumeration item West. To convert that, we used the same syntax of

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

converting a Direction to integer. Take note that if the number you will be converting is not in the bounds of the enumeration, it will still be converted but no equivalent enumeration item will be assigned for it. For example:
myDirection = (Direction)10; Console.WriteLine("Direction: {0}", myDirection.ToString()); Direction: 10

Since 10 is not a value of any of the enumeration items, the resulting output in the console would be the number itself.

Converting a String into an Enumeration Value


You can convert a string into an enumeration value. Say for example you have a string "West" and you want to convert it to Direction.West, then you have to do a more complex technique. You need to use the Enum class of the System namespace of .NET Framework.
Direction myDirection = (Direction)Enum.Parse(typeof(Direction), "West"); Console.WriteLine("Direction: {0}", myDirection.ToString()); Direction: West

The Enum.Parse() method has two parameters. The first is the type of the enumeration. We used the typeof operator to return the type of the enumeration.The second parameter is the string to be converted to the enumeration type provided in the first argument. The value returned is of type object so a conversion to the proper enumeration type is neccessary. With those details, we can now make a syntax for converting a string into an enumeration item.
enumType name = (enumType)Enum.Parse(typeof(enumType), string);

If the string you passed to the method cannot be mapped or is not member of the enumeration, then an error will occur.

Structures
Structures or structs are user-defined data types that can contain other variables as its fields, and methods as its bahavior. You can create your very own customized data type using structures. Let say you want a data that don't just store a name as a string, but you also want to include his age and his monthly salary. To define a structure in a program, we use the following syntax.
struct StructName { member1; member2; member3; ... member4; }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We declare a structure using the struct keword. Names of structures should used Pascal Casing to indicate that it is a structure but that is just a convention followed in C# programming. The members can either be variables or methods. The program below shows an example of a structure.
1 using System; 2 3 namespace StructuresDemo 4 { 5 public struct Employee 6 { 7 public string name; 8 public int age; 9 public decimal salary; 10 } 11 12 public class Program 13 { 14 public static void Main() 15 { 16 Employee employee1; 17 Employee employee2; 18 19 employee1.name = "Jack"; 20 employee1.age = 21; 21 employee1.salary = 1000; 22 23 employee2.name = "Mark"; 24 employee2.age = 23; 25 employee2.salary = 800; 26 27 Console.WriteLine("Employee 1 Details"); 28 Console.WriteLine("Name: {0}", employee1.name); 29 Console.WriteLine("Age: {0}", employee1.age); 30 Console.WriteLine("Salary: {0:C}", employee1.salary); 31 32 Console.WriteLine(); //Seperator 33 34 Console.WriteLine("Employee 2 Details"); 35 Console.WriteLine("Name: {0}", employee2.name); 36 Console.WriteLine("Age: {0}", employee2.age); 37 Console.WriteLine("Salary: {0:C}", employee2.salary); 38 } 39 } 40}

Example 1 - Using Structures


Employee 1 Details Name: Jack Age: 21 Salary: $1000.00 Employee 2 Datails Name: Mike

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Age: 23 Salary: $800.00

Lets disect the code to better understand the program. Lines 5-10 is the declaration of a structure. Note that we used the public keyword. That keyword simply indicates that our Employee can be accessed or used anywhere in the program (or outside the program). public is one of the access specifiers and will be discussed in greater detail in later lessons. We used the struct keyword followed by name of the structure. Structure names also follow the Pascal Casing convention. Inside the body of the structure, we defined three fields. Fields are like the properties of our Employee. For example, an employee has a name, an age and for he to continue his job, he is given a monthly salary. These members was also declared as public so they can be called outside the structure as demonstrated later. Lines 16 and 17 declares two instances of Employee. The declaration of structure instances is similar to normal variables. You first indicate the structure type, and then the identifier. Lines 19 to 25 assigned values to the respective fields of each employee. To access the fields outside the structure, they must be public first (or internal as seen in a later lesson). We first write the name of the variable, followed by a dot (.) and then the name of the field. When the dot operators is used in this context, it is called the member access operator as it allows you to call the members of a particular structure (and class as we will see in the following lessons). Lines 27 to 37 demonstrates how you can access the values stored on each field of a structure variable. When accessing or reading a field, we do the same thing. We indicate the variable name followed by a dot and then the name of the field to be read. Structures are value types. That means that if we assign employee2 with a value of employee1, employee2 will copy all the values of the attributes of employee1 instead of getting its reference. A class is similar to a structure but it is a reference type. It will be discussed in a later lesson. You can also add methods inside a structure. The example below modifies the program in Example 1.
1 using System; 2 3 namespace StructuresDemo2 4 { 5 public struct Employee 6 { 7 public string name; 8 public int age; 9 public decimal salary; 10 11 public void SayThanks() 12 { 13 Console.WriteLine("{0} thanked you!", name); 14 } 15 } 16 17 public class Program

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49}

{ public static void Main() { Employee employee1; Employee employee2; employee1.name = "Jack"; employee1.age = 21; employee1.salary = 1000; employee2.name = "Mark"; employee2.age = 23; employee2.salary = 800; Console.WriteLine("Employee 1 Details"); Console.WriteLine("Name: {0}", employee1.name); Console.WriteLine("Age: {0}", employee1.age); Console.WriteLine("Salary: {0:C}", employee1.salary); employee1.SayThanks(); Console.WriteLine(); //Seperator Console.WriteLine("Employee 2 Details"); Console.WriteLine("Name: {0}", employee2.name); Console.WriteLine("Age: {0}", employee2.age); Console.WriteLine("Salary: {0:C}", employee2.salary); employee2.SayThanks(); } }

Example 2 - Using Structures


Employee 1 Details Name: Jack Age: 21 Salary: $1000.00 Jack thanked you! Employee 2 Details Name: Mike Age: 23 Salary: $800.00 Mike thanked you!

Lines 11 to 14 define a new method inside a structure. This method prints a message and gets the value of the name field to show a unique message for each instance. To call the method, we used similar syntax except that instead of the field following the dot, we indicate the name of method to call followed by parenthesesand a set of arguments if they are required by a function.

Object Oriented Programming


COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Object Oriented Programming (OOP) involves defining classes and creating objects that resemble real life objects. For example, consider a car. The car has properties such as color, speed, model, manufacturer and many more. It also has bahaviors or actions such as accelerate, steer left, steer right, and brake. Objects in C# mimics a real life object so a Car object in C# can have the same properties and behaviors of the real one. OOP deals with classes and objects to modularize codes and make them more manageable. It also promotes software reusability. We first need to define a class which serves as a blueprint for the object we are creating. The object in OOP is the one that is created using the class you defined. For example, consider the class as the blueprint of your house. The blueprint defines properties of the house such as the area, the height, and materials to be used to build the house. The object is the actual house itself which was based on the blueprint. Object Oriented Programming is the modern approach used by programmers and it makes the program more reusable, readable, and easy to debug. C# is an object-oriented language and everything in C# is an object. The following lessons will show you how you can define classes and use objects. We'll also take a look at inheritance and polymorphism which are two main concepts studied in object-oriented programming.

Defining a Class
A class let's you define a user-defined data type that contains fields, properties and methods. A class serves as a blueprint for an object. The object is the actual thing that follows the structure or possesses the properties and bahaviors of the class. When you create an object, you call them an instance of a class. I may use the terms object and instance interchangeably. At first, you may think that classes are similar to structures. The main difference between a class and a structure is that classes are reference types and structures are value types. This will be demonstrated further in a later lesson. We have been using defining class since the beginning and that was the Program class. It contains the Main() method which is the starting point of the execution of the program. Defining a class is the same as defining a structure. But instead of using the struct keyword, we can tell the compiler that we are indicating a class by using the class keyword.
class ClassName { field1; field2; ... fieldN; method1; method2; ... methodN; }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We write the keyword class followed by the class name. Class names also adhere to the Pascal Casing naming convention. Inside the body of the class, we provide the fields and methods it contain. Fields are the private data members that the class use for its behaviors and for storing the values of its properties. The methods are the bahavior of the class or what it can do. Example 1 shows an example of defining and using a simple class named Person.
1 using System; 2 3 namespace ClassesDemo 4 { 5 public class Person 6 { 7 public string name; 8 public int age; 9 public double height; 10 11 public void TellInformation() 12 { 13 Console.WriteLine("Name: {0}", name); 14 Console.WriteLine("Age: {0} years old", age); 15 Console.WriteLine("Height: {0}cm", height); 16 } 17 } 18 19 public class Program 20 { 21 public static void Main() 22 { 23 Person firstPerson = new Person(); 24 Person secondPerson = new Person(); 25 26 firstPerson.name = "Jack"; 27 firstPerson.age = 21; 28 firstPerson.height = 160; 29 firstPerson.TellInformation(); 30 31 Console.WriteLine(); //Separator 32 33 secondPerson.name = "Mike"; 34 secondPerson.age = 23; 35 secondPerson.height = 158; 36 secondPerson.TellInformation(); 37 } 38 } 39}

Example 1 - Your First Class


Name: Jack Age: 21 years old Height: 160cm Name: Mike Age: 23 years old Height: 158cm

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The program above contains two classes, the Person class and the Program class. We know that the Program class contains the Main() method which is required in a program so let's focus our attention on the Person class. Lines 5-17 is the declaration of our Person class. Line 5 specifies the name of the class and its accessibility. We used the public access specifier so other classes can recognize the Person class. We'll take a look at access specifiers in a seperate lesson. Inside the body of the class are fields for that class (lines 7-9). We defined three fields that resembles the real properties of a realworld person. A person has a name, age, and height. Lines 11-16 defined one method inside the class named TellInformation(). It is the bahavior of our class as if we are asking the Person object to tell something about himself. Inside the method are codes that will display the currently stored values of the fields. You can see that it simply shows the values of the class' fields. One thing to note about fields. Since they are declared inside the class and considered as class members, they have a class scope. It means that these fields can only be used inside the class where it belongs or by an instance of a class. Inside the Main() method, lines 23-24 created two instances or objects of Person class. When declaring an instance of a class, we use the new keyword followed by the name of the class and a set of parentheses. When creating an instance of a class, you need to call the constructor. A constructor is a special method used to initialize values of the fields of an object. The class calls the default parameterless constructor when you don't specify arguments inside the parentheses. We'll take a look at constructors in the next lesson. Lines 26-28 assigns values to the fields of the first Person object. We used the dot syntax when accessing fields or methods of an object. For example, calling firstPerson.name refers to the name field of the firstPerson. We called the TellInformation() method of the firstPerson to print the values of its fields. Lines 33-36 does the same to the secondPerson oobject. We also assigned values to it and call the TellInformation() method. Note that firstPerson and secondPerson has different coppies of each fields so specifying a name for the secondPerson does not affect the name of the firstPerson. You will learn about class members that is shared by all the instances of the class in a later lesson.

Constructors
Constructors are special methods that are required to create or "construct" objects. They allow you to assign the initial values for each data member of an array and add codes that you want to execute when you create an object. If you don't include any constructors in a class, then the compiler will use a default constructor which is a contructor that has no parameters. You can have as many constructors as you want provided that they have different set of parameters. Let's take a look at a class that contains a constructor.
1 using System; 2 3 namespace ConstructorsDemo 4 { 5 public class Person 6 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49}

public string name; public int age; public double height; //Explicitly declare a default constructor public Person() { } //Constructor that has 3 parameters public Person(string n, int a, double h) { name = n; age = a; height = h; } public void ShowInformation() { Console.WriteLine("Name: {0}", name); Console.WriteLine("Age: {0} years old", age); Console.WriteLine("Height: {0}cm", height); } } public class Program { public static void Main() { Person firstPerson = new Person(); Person secondPerson = new Person("Mike", 23, 158); firstPerson.name = "Jack"; firstPerson.age = 21; firstPerson.height = 160; firstPerson.ShowInformation(); Console.WriteLine(); //Seperator secondPerson.ShowInformation(); } }

Example 1 - A Class with a Constructor


Name: Jack Age: 21 years old Height: 160cm Name: Mike Age: 23 years old Height: 158cm

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The program in Example 1 is the same program that we saw in the last lesson. We added two constructors for class Person. One is the default constructor (lines 12-14) and the other is a constructor that accepts three arguments (lines 17-22).You notice that a constructor is just like a method but it must not have a return type, not even void. The name of a constructor must exactly match with the name of the class. The default constructor has nothing inside its body. This is the same as the default constructor being called if we did not provide any constructors for a class. We will see later how we can assign default values to data members when using a default constructor. Take a look at the second constructor. It has the same name as the first one. Constructors can be overloaded like methods. Let's look at how we can call a specific constructor based on the declaration of the instances of the class.
Person firstPerson = new Person(); Person secondPerson = new Person("Mike", 23, 158);

On the first instance of person, we used the default constructor because there are no arguments inside the parentheses. On the second declaration, we are now using the second constructor because the three arguments that the parameter of the constructor is expecting are provided. The code below shows the effect of using two different constructors.
firstPerson.name = "Jack"; firstPerson.age = 21; firstPerson.height = 160; firstPerson.ShowInformation(); Console.WriteLine(); //Seperator secondPerson.ShowInformation();

As you can see, the object that used the default constructor requires you to assign the values for it data members so it can show something if you call the ShowInformation() method. Contrast to the second object that used the parametarized constructor, you just call the method and everything will run as expected. This is because, you already gave the values for the data members when you declared the instance so theres no need to reassign values unless you want to modify the value of an data member.

Providing Default Values for the Default Constructor


The program in Example 1 showed a default constructor that has an empty body. You can add codes inside the default constructor. You can assign default values to the data members if nothing is provided by the user.
public Person() { name = "No Name"; age = 0; height = 0; }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Now our default constructor has something to do. If we declared an instance that uses this constructor, then it will be assigned the default values.
Person person1 = new Person(); person1.ShowInformation(); Name: No Name Age: 0 years old Height: 0cm

Using the this Keyword


Another way of providing default values is by using the this keyword. The example below shows a modified program in Figure1 and uses 4 constructors with different number of paremeters.
1 using System; 2 3 namespace ConstructorDemo2 4 { 5 public class Person 6 { 7 public string name; 8 public int age; 9 public double height; 10 11 public Person() 12 : this("No Name", 0, 0) 13 { 14 } 15 16 public Person(string n) 17 : this(n, 0, 0) 18 { 19 } 20 21 public Person(string n, int a) 22 : this(n, a, 0) 23 { 24 } 25 26 public Person(string n, int a, double h) 27 { 28 name = n; 29 age = a; 30 height = h; 31 } 32 33 public void ShowInformation() 34 { 35 Console.WriteLine("Name: {0}", name); 36 Console.WriteLine("Age: {0} years old", age); 37 Console.WriteLine("Height: {0}cm\n", height); 38 } 39 } 40

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56}

public class Program { public static void Main() { Person firstPerson = new Person(); Person secondPerson = new Person("Jack"); Person thirdPerson = new Person("Mike", 23); Person fourthPerson = new Person("Chris", 18, 152); firstPerson.ShowInformation(); secondPerson.ShowInformation(); thirdPerson.ShowInformation(); fourthPerson.ShowInformation(); } }

Example 2 - Using the this Keyword


Name: No Name Age: 0 years old Height: 0cm Name: Jack Age: 0 years old Height: 0cm Name: Mike Age: 23 years old Height: 0cm Name: Chris Age: 18 years old Height: 152cm

We declared four constructors for our modified class. You can have as many constructors in a class when deemed necessary. The first constructor is the default parameterless constructor. The second constructor is the one that has one parameter. The third constructor has two paremters, and the fourth constructor has three parameters. Take note of the fourth constructor in lines 2631. The other three constructors will relly with the constructor. Lines 11-14 is the default parameterless constructor. Notice the use of the this keyword after placing a colon (:) . The this keyword lets you call another existing constructor inside the class. We give the default values for the data members. Since we provided three arguments inside the parentheses folowing the this keyword, the constructor with three parameters was called and three arguments was passed to its parameters. The code inside the body of the fourth constructor is executed which assigns the values of the parameters to their respective data members. We didn't write any code inside the body of the first constructor since that will be handled by the fourth constructor. If we write codes inside the body of the default constructor, then the fourth constructor will be executed before the code inside the default constructor.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The second constructor (lines 16-19) requires one argument which is the name of the person. When this parameter is filled up with a string value, that value is then passed to the paremeters of the fourth constructor along with the other two default values (0 for age and 0 for height). Again, we didn't write any code inside the body of the second constructor because it will be handled by the fourth parameter. Lines 21-24 is the third constructor which is similar to the second constructor but has two parameters. The value of the two parameters of the third constructor along with a default value of 0 for the third argument, is passed to the fourth constructor using the this keyword..
Person Person Person Person firstPerson = new Person(); secondPerson = new Person("Jack"); thirdPerson = new Person("Mike", 23); fourthPerson = new Person("Chris", 18, 152);

With multiple constructors for our class, we have multiple ways of creating our class depending on which data are needed. We declared four instances of the Person class and we used the four different variations of its constructor. We then displayed the values of the data members of each instance. There's another use for the this keyword. What if the parameter name for your class method or constructor is similar the name of the one of the data members.
public Person(string name, int age, double height) { name = name; age = age; height = height; }

This will give ambiguity to the code and the compiler cannot determine which variable you are assigning to and which variable is being assigned a value. This is where the this keyword is used.
public Person(string name, int age, double height) { this.name = name; this.age = age; this.height = height; }

We precede each of the data members with the this keyword to indicate that what's being assigned with a value are the attibutes of "this" class. The this keyword represents the reference of the object itself.

Destructors
Destructors are the oposite of constructors. Destructors are also special methods that is called when the object is being destroyed. Objects uses memory of your computer and if they are not

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

removed from the memory, you will suffer a memory leak. You can use the destructor as a clean up tool or to remove any resources that aren't needed by the program. The .NET Framework offers automatic garbage collection so you don't need to manually remove the objects (or dispose them) from the memory. There are times where the garbage collector can't do its job well. For example, when creating a connection to a database, or when opening a stream for reading a text file. With the use of destructors, you define the code that will be executed when an object is destroyed. Usually, an object is destroyed when it leaves a scope. The syntax of a destructor is a little different than the constructor.
~ClassName() { code to execute; }

Like a constructor, the destructor should also match the name of the class. Notice that we precede the name with a tilde (~) which is found below the escape key on your keyboard. The destructor cannot have access specifiers such as public. The program below shows the order by which the destructor and constructor are called.
1 using System; 2 3 namespace DestructorsDemo 4 { 5 public class Test 6 { 7 public Test() 8 { 9 Console.WriteLine("Constructor was called."); 10 } 11 ~Test() 12 { 13 Console.WriteLine("Destructor was called."); 14 } 15 } 16 17 public class Program 18 { 19 public static void Main() 20 { 21 Test x1 = new Test(); 22 } 23 } 24}

Example 1 - Creating a Desctructor


Constructor was called. Destructor was called.

We defined both a constructor and a destructor for class Test. We then created an instance of it inside the Main() method. When we created the instance, the constructor was called and the
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

proper message was displayed. When we left the Main() method, the object was destroyed and the destructor was called. The .NET Framework actually interprets a destructor as a method that overrides the Finalize() method of the System.Object.

readonly Fields
The readonly keyword is used for fields that will not allow modification of values. readonly fields have similar characteristics as constants except that you can allow a readonly field to have no value from the declaration. Even though, you must assign values for readonly fields inside the class constructor. Once assigned with a value, a readonly field's value cannot be changed. Doing so will result into a compiler error.
1 namespace ReadOnlyFieldsDemo 2 { 3 public class Sample 4 { 5 readonly int y = 10; 6 readonly int x; 7 8 public Sample(int number) 9 { 10 x = number; 11 } 12 } 13}

Example 1 - readonly Fields Demo The class above defined two readonly fields. The first one is initialized a value at the declaration. The other one was assigned a value in the class constructor.

Access Specifiers
Access specifiers determine the accessability of a class method or data members. We'll take a look at the public and private access specifiers. The public access specifier is used when you want to access a method or data members outside the class or even outside the project. For example, consider the following code:
1 using System; 2 3 namespace AccessSpecifiersDemo 4 { 5 public class Test 6 { 7 public int number; 8 } 9 10 public class Program 11 { 12 public static void Main()

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

13 14 15 16 17 18 19}

{ Test x = new Test(); x.number = 10; } }

Example 1 - public Access Specifier We declared our test class as public. This will allow the Program class to create Test instances. We also declared one public data member inside the Test class. We tested if we can access that data member from outside the Test class by assigning a value to it inside the Main() method of the Program class. If we are to omit the use of the public keyword, then we won't be able to create a Test class and access its data member. That is similar to the private access specifier.
1 using System; 2 3 namespace AccessSpecifiersDemo2 4 { 5 private class Test 6 { 7 public int number; 8 } 9 10 public class Program 11 { 12 public static void Main() 13 { 14 Test x = new Test(); 15 16 x.number = 10; 17 } 18 } 19}

Example 2 - private Access Specifier We used the private keyword for class Test. Compiling this will produce an error because Test now can't be accessed anywhere inside the Program class or any other classes. Note that even though the data member of the Test class is public, it cannot be accessed because the class itself is private which makes everything inside it inaccessible. Note that if you don't specify any access specifier for a class, it will use internal access specifier which means that only the classes within the current project can access the class. Using internal is equivalent to public but it can't be accessed outside the project. The following code have the same in effect.
class Test { } internal class Test

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

{ }

If we made our class public but its data member is private, then we can create an instance of that class outside of it but the private data member cannot be accessed. The private data member can only be accessed by methods within the Test class.
1 using System; 2 3 namespace AccessSpecifierDemo3 4 { 5 public class Test 6 { 7 private int number; 8 } 9 10 public class Program 11 { 12 public static void Main() 13 { 14 Test x = new Test(); 15 16 x.number = 10; //Error, number is private 17 } 18 } 19}

Example 3 - Accessing a private Field Produces Error There are more access specifiers available in C# and they will be discussed in later chapters when you are finish learning about inheritance.

Encapsulation
Encapsulation or information hiding is the process of hiding the sensitive data of an object from a user and only providing him/her with what is neccessary. When we define a class, we often have states, which are the data members that store the values about the object. Some of these data members are used by the class itself to support the functionality of methods and sometimes, act as temporary variables. This kind of data members are called utility members because they are only used to support the methods and not as a visible data of the class. Not all of the data members or methods is needed by the user or the one who will use the class. Allowing these type of data members to be accessed outside of the class is dangerous as the user can modify the bahavior and the results of the methods. Consider a simple program below:
1 using System; 2 3 namespace EncapsulationDemo 4 { 5 public class Test 6 { 7 public int five = 5;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26}

public int AddFive(int number) { number += five; return number; } } public class Program { public static void Main() { Test x = new Test(); x.five = 10; Console.WriteLine(x.AddFive(100)); } }

Example 1 - Not Using Encapsulation


110

The method inside the Test class is named AddFive which has a simple purpose of adding the value 5 to any number. Inside the Main() method, we created an instance of the Test class and modified the value of the data member five and assigned it a new value of 10. Now, the functionality of method AddFive() has been modified as well and the you will now get different results. This is why encapsulation is important. The things we've done in the last chapters which are making the data members public and allowing the user to access them outside of the class is a wrong practice. We only did that for demonstration purposes. Data members should always be private. Starting now, we will do the right way of creating class by introducing properties in the next lesson.

Properties
Properties is the C# standard for accessing private data members inside a class. Properties have getters which gets the value of the private data and setters which sets a value to a private data. Properties should be public so they can be accessed by other class. The example below shows how to define and use properties.
1 using System; 2 3 namespace PropertiesDemo 4 { 5 public class Person 6 { 7 private string name; 8 private int age; 9 private double height;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

public string Name { get { return name; } set { name = value; } } public int Age { get { return age; } set { age = value; } } public double Height { get { return height; } set { height = value; } } public Person(string name, int age, double height) { this.name = name; this.age = age; this.height = height; } } public class Program { public static void Main() { Person person1 = new Person("Jack", 21, 160); Person person2 = new Person("Mike", 23, 158); Console.WriteLine("Name: {0}", person1.Name); Console.WriteLine("Age: {0} years old", person1.Age); Console.WriteLine("Height: {0}cm", person1.Height);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94}

Console.WriteLine(); //Seperator Console.WriteLine("Name: {0}", person2.Name); Console.WriteLine("Age: {0} years old", person2.Age); Console.WriteLine("Height: {0}cm", person2.Height); person1.Name = "Frank"; person1.Age = 19; person1.Height = 162; person2.Name = "Ronald"; person2.Age = 25; person2.Height = 174; Console.WriteLine(); //Seperator Console.WriteLine("Name: {0}", person1.Name); Console.WriteLine("Age: {0} years old", person1.Age); Console.WriteLine("Height: {0}cm", person1.Height); Console.WriteLine(); Console.WriteLine("Name: {0}", person2.Name); Console.WriteLine("Age: {0} years old", person2.Age); Console.WriteLine("Height: {0}cm", person2.Height); } }

Example 1 - Properties Demo


Name: Jack Age: 21 years old Height: 160cm Name: Mike Age: 23 years old Height: 158cm Name: Frank Age: 19 years old Height: 162cm Name: Ronald Age: 25 years old Height: 174cm

The program inroduces the use of properties and we defined three properties which corresponds to each of the data members.
private string name; private int age; private double height;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Notice that we made our data members private to promote encapsulation. Their values can only be accessed throught the provided properties.
public string Name { get { return name; } set { name = value; } } public int Age { get { return age; } set { age = value; } } public double Height { get { return height; } set { height = value; } }

These are the properties. When writing a property, we indicate its accessibility which is public and we provide the data type which is the data type of the value it will return or accept. Notice that the name of the properties the same as their corresponding data members except that the first letter is capitalized. It doesn't have to, but that is another convention in C#. Inside the body, you see getters and setters. The getters, indicated by the get keyword, allows you to extract the data from a private data member. The setters, indicated by the set keyword allows you to set value to a data member. Notice the value keyword inside the setter. The value contains what is being assigned to the property. To access a property, you simply use the dot syntax.
Console.WriteLine("Name: {0}", person1.Name); Console.WriteLine("Age: {0} years old", person1.Age); Console.WriteLine("Height: {0}cm", person1.Height));

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Calling a property this way will execute the code inside the body of the getter of the specified property. The getter then returns the value to the caller just like a method. Setting value to a property is also very simple.
person1.Name = "Frank"; person1.Age = 19; person1.Height = 162;

The statements above calls the setter of each of those properties which assigns the value to the corresponding data members. Using properties is very flexible specially you want to add validation when getting or setting data to the members of the object. For example, you can add a restriction that only positive number can be assigned to age of the person. You can modify the setter of the Age property like this:
public int Age { get { return age; } set { if (value > 0) age = value; else age = 0; } }

This time, if a user tries to assign a negative number to the age of the person, it will assign 0 instead because of the if statement inside the setter of the property. You can also make a property read-only (cannot be set with values) by not including a setter. For example, you can make the Name property read-only by doing the following:
public string Name { get { return name; } }

When you try to assign a new value to name, then an error will occur. Another thing is that you can also place access specifiers for getters and setters. Consider the following code:
public string Name { get { return name;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

} private set { name = value; } }

The Name property can only be read outside the class but only methods inside the Person class can set new values. A property doesn't need to be associated to one private data member. It can be a combination of two data. Consider the code below.
private string firstName; private string lastName; public FullName { get { return firstName + " " + lastName; } }

We defined a read-only property called FullName which returns the combination of firstName and lastName sperated by a space. C# also offers a shortcut when creating properties. You can define a property without any private data member associated with it.
public int MyProperty { get; set; }

These feature are also called automatic properties which was introduced in C# 3.0. Notice that we didn't supply any code for the getter and setter. The above statement is equivalent to defining a private int data member and it's corresponding property except that the shorthand version is done in one line. This is automatically recognized by the compiler as a property and a corresponding field is created during runtime. Note that when defining automatic properties, you must have both the getter and the setter. You also cannot put codes inside the getter or setter of an automatic property.

Namespaces
Namespaces is a way of packaging your application codes such as classes into a uniquely named structure. Everything in .NET Framework is wrap inside at least one namespace. When naming your class, there is a big chance that other programmers might have named their classes the same as yours. When you use their class into your program that also uses the class with the same name, there will be a conflict. Namespaces prevent, or at least decrease the likelihood of this event. As of now, we have encountered only one namespace and that is the System namespace which contains the most common methods and classes such as the Console class and the WriteLine()

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

method. We haven't use any namespace on our previous lessons, but if you will create a new project, the default code it wil provide you will have a namespace that has a name similar to your project's name. In this lesson, I will show you how you can write your classes inside a seperate file and then use it on another file. Fire up Visual Studio 2010 or Visual C# 2010 and create a new project. After your project has been created, let's create a new code file. There are multiple ways to create a new file. One way is by right-clicking your project inside Solution Explorer, select Add and then New Item...

Another way is by simply clicking the Add New Item button found on the Toolbar.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Or you can simply hit Ctrl + Shift + A. Whichever way you choose, a dialogue will be presented to you asking you to choose which file you are trying to create.

Choose class and name it Sample.cs. C# code files has file extentions of cs. For the purpose of this lesson, delete all the contents that is provided to you after creating the class and write the following code.
namespace MyNamespace { class Sample { public void ShowMessage() { System.Console.WriteLine("Hello World!"); } } }

Here, we defined our namespace and named it MyNamespace. Inside it is our class Sample with one method that shows a message. Take note that we accessed the Console.WriteLine() method by calling the System namespace and by using the dot syntax. You can use the using keyword to allow you to omit the System namespace when calling the Console.WriteLine() Method. Now switch to Program.cs which is the default file when you created the project earlier. Delete the contents and write the following code.
using MyNamespace;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

class Program { static void Main() { Sample test = new Sample(); test.ShowMessage(); } } Hello World!

We use the using keyword to import all the contents of the MyNamespace which is the namespace that we created. If we are to remove that statement, then we should precede the Sample with MyNamespace everytime we want to use it.
MyNamespace.Sample test = new MyNamespace.Sample();

You can add multiple classes or interface inside a namespace. They will all be contained inside that namespace.
namespace MyNamespace { class Sample1 { } class Sample2 { } }

You are not limited to packaging your class into just one namespace. You can nest your namespace to further categorize your codes.
namespace MyNamespace1 { namespace MyNamespace2 { class Sample { public void ShowMessage() { System.Console.WriteLine("Hello World!"); } } } }

To access the Sample class, you have to indicate first all the namespaces that wraps it.
MyNamespace1.MyNamespace2.Sample

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Or you can use again the using statement.


using MyNamespace1.MyNamespace2;

The .NET Framework itself consist of deep nested namespaces. For example, the System.Data.SqlClient are three namespaces nested together. The .NET Framework uses namespaces to categorize each of the technologies it supports. You can create an alias namespace if you want to make nested namespaces to smaller or easier to type.
using AliasNamespace = MyNamespace1.MyNamespace2;

Structures Versus Classes


So what's the difference between a class and a structure? Structures are value types like int, double, and string. When you copy a value of structures to other variables, it copies its values to the other variable and not its address or reference. Classes are reference types like all the classes in the .NET Framework. Let's demonstrate the difference of the two by looking at an example.
1 using System; 2 3 namespace StructureVsClass 4 { 5 struct MyStructure 6 { 7 public string Message { get; set; } 8 } 9 10 class MyClass 11 { 12 public string Message { get; set; } 13 } 14 15 class Program 16 { 17 static void Main() 18 { 19 MyStructure structure1 = new MyStructure(); 20 MyStructure structure2 = new MyStructure(); 21 22 structure1.Message = "ABC"; 23 structure2 = structure1; 24 25 Console.WriteLine("Showing that structure1 " + 26 "was copied to structure2."); 27 Console.WriteLine("structure2.Message = {0}", 28structure2.Message); 29 30 Console.WriteLine("\nModifying the value of 31structure2.Message..."); 32 structure2.Message = "123";

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

33 34 Console.WriteLine("\nShowing that structure1 was not affected " 35+ 36 "by the modification of structure2"); 37 Console.WriteLine("structure1.Message = {0}", 38structure1.Message); 39 40 41 MyClass class1 = new MyClass(); 42 MyClass class2 = new MyClass(); 43 44 class1.Message = "ABC"; 45 class2 = class1; 46 47 Console.WriteLine("\n\nShowing that class1 " + 48 "was copied to class2."); 49 Console.WriteLine("class2.Message = {0}", class2.Message); 50 51 Console.WriteLine("\nModifying the value of 52class2.Message..."); 53 class2.Message = "123"; 54 55 Console.WriteLine("\nShowing that class1 was also affected " + "by the modification of class2"); Console.WriteLine("class1.Message = {0}", class1.Message); } } }

Example 1 - Structures Vs Classes


Showing that structure1 was copied to structure2. structure2.Message = ABC Modifying the value of structure2.Message... Showing that structure1 was not affected by the modification of structure2 structure1.Message = ABC Showing that class1 was copied to class2. class2.Message = ABC Modifying the value of class2.Message... Showing that class1 was also affected by the modification of class2 class1.Message = 123

We made a structure and a class that we will use to demonstrate their differences. We provided a Message property for each of the two. We then create two instances for each of them. We assigned a value for the Message property of structure1. We then assign the value of structure1 to structure2 so everything inside structure1 will be copied to structure2. To prove that everything was copied from structure1, we showed the value of structure2's Message property and you can see that it is the same as the structure1's Message property value. To show that

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

structures are value types, we assigned another message to the Message property of structure2. The Message property of structure1 is not affected because the structure2 is a seperate copy of structure1. Now to demonstrate the bahavior of reference types and classes. Classes pass their address and not thier value when they're being assigned to other variables. Therefore, when you edit a property of the object that receive the address of the original object, the property of that original object is also modified. When you're passing an object as an argument to a method, only the address of that object is passed. Any modifications to that object inside that method will also reflect to the original object that passed its address.

Class Libraries
You can create class libraries which is a collection of classes and other codes that can be compiled and redistributed for software reusability. Class libraries are compiled into dynamic link libraries (DLL). DLLs cannot be read when you open it inside any text editor programs. Only computers can understand them. Class libraries is a project that you can create in an individual solution or along with other solutions. Let's create a new class library for a class named sample. Go to File > New > Project.

You should then choose Class Library from the list of templates and name it Sample for this demonstration.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

After creating the class library, you will be provided a new class file. You can now add your codes inside this class file. You can also create your class library project along with your other projects inside one solution. Go to the solution explorer and right click your solution then choose New > Project. After writing your code for the classes inside the class library, you can build it by going to the Menu and choosing Build > Build Solution. It will compile into a .dll file. This file contains all your code. Now, other programs can use this .dll file. Create another Console Application Project. After creating it, you must add reference to the .dll we have created. Go to the Solution Explorer and right click the project and choosing Add Reference...

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Now, you need to browse for the .dll file. The first tab allows you to add reference for all the available .NET Assemblies. Note that not all assemblies are imported to your project by default. If you open the References folder inside the solution explorer, you will find all the assemblies that are available for you. If you want to use more assemblies from the .NET, then you have to add a reference to it using the first tab. The projects tab scans your current solution for class library projects and automatically list them here. The third one is the for Browsing DLL files that are outside the current solution. For example, if you created the Sample Class Library on a seperate solution and build it, you can browse the DLL file to include it on the solution that will use it. The location of the .DLL file is inside the Debug or Release folder of the class library project. These two folders will be found inside the bin folder inside the Solution Folder of the Class Library.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Inheritance
Inheritance allows a class to absorb or inherit all the properties and methods of another class. It is like a parent-child relationship where the child inherits some properties from his/her parents such as facial features and attitudes. The base class or the parent class, is the class which is inherited by other classes. The derived class or the child class, is the one inheriting from the base class. All the methods and properties of the base class can be used by the derived class except for the private members and methods. We will soon discover that all the classes in the .NET Framework inherits the Object class. We will demonstrate the basic concept of inheritance in the following example program. Create a seperate class file and write the following code.
1 using System; 2 3 namespace InheritanceDemo 4 { 5 class Parent 6 { 7 private string message; 8 9 public string Message 10 { 11 get { return message; } 12 set { message = value; } 13 } 14 15 public void ShowMessage() 16 { 17 Console.WriteLine(message); 18 }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34}

public Parent(string message) { this.message = message; } } class Child : Parent { public Child(string message) : base(message) { } }

Example 1 - Inheritance Demo We defined two classes named Parent and Child. We include a private data member (line 7) and its corresponding public property(lines 9-13). We also defined a method that will show the message. A constructor was defined for the Parent class that accepts a string argument that will serve as the message. Now take a look at the Child class (line 26). It inherits the Parent class and absorbs all its methods and properties. The syntax for inheriting a class is as follows.
class DerivedClass : BaseClass

You simply place a colon (:) after the name of the class and then indicate the class that it will inherit. Inside the Child class is a single constructor that also accepts a string argument. When creating inherited classes, both the derived class constructor and the base class default constructor are executed. A default constructor is a no-parameter constructor. If no constructor was defined in a class, the compiler automatically creates a default constructor. If we want to call the base class constructor when we call the derived class contructor, we need to use the base keyword. The base keyword calls a constructor of the base class. We need to write a colon before using the base keyword. By supplying the value of the message parameter of the derived class constructor and passing it inside the parentheses of the base keyword, it will call the matching contructor of the base class and pass the value of the message. The Parent's class constructor will then assign the value of the message into its private data member. You can add some code inside the body of the Child contructor and it will be executed after the Parent's constructor. If we omit the base keyword, the default constructor of the base class will be called instead. Let's now create the actual Parent and Child objects to demonstrate that Child really inherits the methods and properties of the Parent class.
1 namespace InheritanceDemo 2 { 3 class Program 4 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21class 22 23 } }

static void Main() { Parent myParent = new Parent("Message from parent."); Child myChild = new Child("Message from child."); myParent.ShowMessage(); myChild.ShowMessage(); myParent.Message = "Modified message of the parent."; myParent.ShowMessage(); myChild.Message = "Modified message of the child."; myChild.ShowMessage(); //myChild.message; ERROR: can't access private members of base }

Example 2 - Inheritance in Action


Message from parent. Message from child. Modified message of the parent. Modified message of the child.

We intialized both objects using their respective constructors (line 7-8). We then show the use of inheritance by accessing the methods and members of the Parent class through a Child object. Even if the Child class inherits from the Parent class, the private members of the Parent class is still inaccessible to the Child class (line 20). You will be introduced to the protected access specifier in the next lesson which allows you to access the members and methods of the base class. Another thing to note. If another class inherits the Child class, that class will inherit all the methods and properties that the Child class inherits from the parent class.
class GrandChild : Child { //Empty Body }

The class has nothing inside its body. When you create a GrandChild class and call a property from the Parent class, you will receive no error and the operation you are trying to do will be successful. Note that no constructor that accepts a string argument was defined inside the GrandChild therefore, you can only use the paremeterless or default constructor.
GrandChild myGrandChild = new GrandChild(); myGrandChild.Message = "Hello my grandchild!"; myGrandChild.ShowMessage();

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

When we create the class and call the GrandChild's constructor, the Parent's class constructor is called first. Next, the Child's contructor is called afterwards. Finally, the GrandChild's contructor is executed. The program below shows the proper order of constructor execution. Again, I place the classes into a seperate code file for readability.
1 using System; 2 3 namespace InheritanceDemo 4 { 5 class Parent 6 { 7 public Parent() 8 { 9 Console.WriteLine("Parent constructor was called!"); 10 } 11 } 12 13 class Child : Parent 14 { 15 public Child() 16 { 17 Console.WriteLine("Child constructor was called!"); 18 } 19 } 20 21 class GrandChild : Child 22 { 23 public GrandChild() 24 { 25 Console.WriteLine("GrandChild constructor was called!"); 26 } 27 } 28 29 class Program 30 { 31 static void Main() 32 { 33 GrandChild myGrandChild = new GrandChild(); 34 } 35 } 36}

Example 3 - Proper Order of Execution of Constructors


Parent constructor was called! Child constructor was called! GrandChild constructor was called!

protected Access Specifier


The protected access specifier allows class members to be accessed only by those who inherits from them. We learned about the public and private access specifiers. The protected access
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

specifier is used when only the derived classes and the class itself should be able to access the members. Other classes that does not inherit from the class with a protected member will be denied access. The table below shows the accessibility of the three access specifiers. Accessible from public private protected Inside the class true true true Outside the class true false false Derived class true false true Figure 1 - Accessibility of Access Specifiers You can see that public is the most accessible. Regardless of location, public members and methods can be called or accessed. The private is only accessible inside the class where it belongs. The protected access specifier is accessible inside the class where it is defined and also the derived classes of its class. protected members are prohibited from classes that has no relation. The example code below further shows you their behavior.
1 using System; 2 3 namespace ProtectedAccessSpecifierDemo 4 { 5 class Parent 6 { 7 protected int protectedMember = 10; 8 private int privateMember = 10; 9 public int publicMember = 10; 10 } 11 12 class Child : Parent 13 { 14 public Child() 15 { 16 protectedMember = 100; 17 privateMember = 100; 18 publicMember = 100; 19 } 20 } 21 22 class Program 23 { 24 public static void Main() 25 { 26 Parent myParent = new Parent(); 27 28 myParent.protectedMember = 100; 29 myParent.privateMember = 100; 30 myParent.publicMember = 100; 31 } 32 } 33}

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Example 1 - Access Specifiers Demo Codes in red will produce an error because they are not allowed to access the protected fields of the Parent class. As you can see in line 17, the Child class is trying to access the private member of Parent. Since private members are inaccessible from the outside, event from derived classes, line 17 will produce an error. If you will notice line 16, the Child class accesses the protected member of the Parent class and it was successful because the Child class is a derived class of the Parent. But if you will look at line 28 where the Program class access the protected member of the Parent class, it produces an error since the Program class does not inherit from the Parent class. Likewise, the Program class cannot also access the private member of the Parent class.

Static Members
The static keyword is used on members and properties that want to be shared by all instance of the class. When a method or property is defined as static, you can call them without creating an instance of that object. Let's define some static methods and properties.
1 using System; 2 3 namespace StaticMembersDemo 4 { 5 class SampleClass 6 { 7 public static string StaticMessage { get; set; } 8 public string NormalMessage { get; set; } 9 10 public static void ShowStaticMessage() 11 { 12 Console.WriteLine(StaticMessage); 13 } 14 15 public void ShowNormalMessage() 16 { 17 Console.WriteLine(NormalMessage); 18 } 19 20 public void ShowStaticFromInstance() 21 { 22 Console.WriteLine(StaticMessage); 23 } 24 } 25 26 class Program 27 { 28 public static void Main() 29 { 30 SampleClass sample1 = new SampleClass(); 31 SampleClass sample2 = new SampleClass(); 32 33 SampleClass.StaticMessage = "This is the static message!"; 34 SampleClass.ShowStaticMessage(); 35

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

36 37 38 39 40 41 42 43 44 45}

sample1.NormalMessage = "\nMessage from sample1!"; sample1.ShowNormalMessage(); sample1.ShowStaticFromInstance(); sample2.NormalMessage = "\nMessage from sample2!"; sample2.ShowNormalMessage(); sample2.ShowStaticFromInstance(); } }

Example 1 - Demonstrating Static Members


This is the static message! Message from sample1! This is the static message! Message from sample2! This is the static message!

We declared a static property named StaticMessage(line 7) and a static method named ShowStaticMessage(lines 10-13). The value of the StaticMessage property will be shared by all instance of the SampleClass. The static method cannot be called by intances of the SampleClass. To call the static method or property, simply write the name of the class and the property or method name seperated by a dot. You can see this in lines 33-34. No instance creation is needed. We assigned a message for the static message and call the static method to display its value. Next we call the NormalMessage property from the two instances and call the method that shows its value. We see that both of the two instance has their own NormalMessage value since that property is not static. We then call the ShowStaticFromInstance which is a method that will show the value of the StaticMessage to show that it still has the value assigned when we called it directly through the name of the class. Non-static methods can use static fields and properties. But the reverse is not allowed. For example, you have a static method, you cannot use any properties, fields or methods that are not labeled as static.
private int number = 10; public static void ShowNumber() { Console.WriteLine(number); //Error: cannot use non-static member }

Insisting on doing this will result in an error. An example of a static method is the WriteLine method of the Console class. If that particular method is not static, then we have to do the following:
Console display = new Console(); display.WriteLine("My message!");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We will need to create an instance of the Console class first before we can display messages. Another thing to note is the Main() method declared as static. The compiler requires it to be static so it can be executed in a program without creating an instance of it.

Virtual Methods
Virtual methods are methods of a base class that can be overriden by a method in a derived class to provide a different implementation of that method. For example, you have mathod A from Class A and Class B inherits from Class A, then method A will be available from Class B. But method A is the exact method you inherited from Class A. What if you want to have a different bahavior for the inherited method? Virtual methods solve this problem. Consider the following example.
1 using System; 2 3 namespace VirtualMethodsDemo 4 { 5 class Parent 6 { 7 public virtual void ShowMessage() 8 { 9 Console.WriteLine("Message from Parent."); 10 } 11 } 12 13 class Child : Parent 14 { 15 public override void ShowMessage() 16 { 17 Console.WriteLine("Message from Child."); 18 } 19 } 20 21 class Program 22 { 23 public static void Main() 24 { 25 Parent myParent = new Parent(); 26 Child myChild = new Child(); 27 28 myParent.ShowMessage(); 29 myChild.ShowMessage(); 30 } 31 } 32}

Example 1 - Virtual Methods Example


Message from Parent. Message from Child.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

A virtual method can be defined by placing the virtual keyword in the declaration of the method. The virtual keyword indicates that the method can be overriden or in other words, can have a different implementation. The class that inherits the Parent class contains the method that overrides the virtual method. You use the override keyword to indicate that a method should override a virtual method from the base class. You can use the base keyword to call the original virtual method inside the overriding method.
1 using System; 2 3 namespace VirtualMethodsDemo2 4 { 5 class Parent 6 { 7 private string name = "Parent"; 8 9 public virtual void ShowMessage() 10 { 11 Console.WriteLine("Message from Parent."); 12 } 13 } 14 15 class Child : Parent 16 { 17 public override void ShowMessage() 18 { 19 base.ShowMessage(); 20 Console.WriteLine("Message from Child."); 21 } 22 } 23 24 class Program 25 { 26 public static void Main() 27 { 28 Parent myParent = new Parent(); 29 Child myChild = new Child(); 30 31 myParent.ShowMessage(); 32 myChild.ShowMessage(); 33 } 34 } 35}

Example 2 - Using the base Keyword


Message from Parent. Message from Parent. Message from Child.

If you only use the base method and no other codes inside the overriding method, then it has similar effect to not defining the overriding method at all. You cannot override a non-virtual method or a static method. The overriding method must also have similar access specifier as the

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

virtual method. You can create another class that inherits the Child class and override its ShowMessage again and define a different implementation. If you want the overriding method to be final, that is, it cannot be overriden by the other classes that will derive on the class it belongs, you can use the sealed keyword.
public sealed override void ShowMessage()

Now if another class inherits from the Child class, it cannot override the ShowMessage() anymore. Let's have another example, we will override the ToString() method of the System.Object. Every class in C# including the ones you created inherits System.Object as you will see in the next lesson.
1 using System; 2 3 namespace VirtualMethodsDemo3 4 { 5 class Person 6 { 7 public string FirstName { get; set; } 8 public string LastName { get; set; } 9 10 public override string ToString() 11 { 12 return FirstName + " " + LastName; 13 } 14 } 15 16 class Program 17 { 18 public static void Main() 19 { 20 Person person1 = new Person(); 21 22 person1.FirstName = "John"; 23 person1.LastName = "Smith"; 24 25 Console.WriteLine(person1.ToString()); 26 } 27 } 28}

Example 3 - Overriding the ToString() Method


John Smith

Since we overrided the ToString() method of the System.Object class, we have customized the output to print the fullname rather than printing the type of the object which is the default.

System.Object Class
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

All classes in the .NET Framework inherits from the System.Object class. The System.Object class is mapped to the object keyword in C#. For simplicity, I will just use object to refer to System.Object. The following is a list of some common methods of the object class. Method Object() ~Object() Return Type Virtual Static None None No No No No Description This is the constructor of the System.Object class. This is the destructor of the System.Object class. Accepts another object as the argument and returns true if the object refers to the same object that called this method. A static method that accepts two objects and determines if they are reffering to desame object. A static method that determines if the two objects are the same instance. Returns a string representation of the object. You can override this method to provide your own string representation for your class. This method creates a new instance of the object and copies the values of it's data members. Returns the type of the object as System.Type Returns a hash value which identifies the object state.

Equals(object)

bool

Yess

No

Equals(object, object) bool

No

Yes

ReferenceEquals (object,object)

bool

No

Yes

ToString()

string

Yes

No

MemberwiseClone() object GetType() GetHashCode()

Noo

No No No

System.Type No int Yes

Figure 1 - System.Object Members Not all of this methods are used frequently. Since all clases in C# inherits from this class, they also possess these methods except for the static methods. When you are creating a class, the class implicitly inherits from the object class. So when you are declaring a class, this is the actual code read by the compiler.
class MyClass : System.Object { }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The purpose of why every classes in .NET inherits from object is to take advantage of polymorphism which will be discussed later. For example, one of the overloads of the Console.WriteLine() method accepts an object argument. That's why you can pass almost anything as an argument to the Console.WriteLine() method. To demonstrate that anything is an object in C#, let's take a look at a sample program that follows.
1 using System; 2 3 namespace ObjectDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 int myInt = 1; 10 double myDouble = 4.0; 11 string myString = "Hello"; 12 13 Console.WriteLine(myInt.ToString()); 14 Console.WriteLine(myDouble.ToString()); 15 Console.WriteLine(myString.ToString()); 16 } 17 } 18}

Example 1 - Everything Inherits from System.Object Class You can see that int, double, and string objects all called the ToString() method which is a method inherited from the object class.

Boxing and Unboxing


Boxing is tha process of converting a value type such as a structure into an object or a reference type. Unboxing is the opposite the opposite process and converts reference types to value types. Example 1 demonstrates boxing.
1 namespace BoxingAndUnboxingDemo 2 { 3 struct MyStruct 4 { 5 public int Number { get; set; } 6 } 7 8 class Program 9 { 10 public static void Main() 11 { 12 MyStruct valueType = new MyStruct(); 13 valueType.Number = 10; 14 object refType = valueType; 15 } 16 }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

17}

Example 1 - Boxing Demo We created a structure named MyStruct and provide a property for testing purposes. To box a value type, simple assign it into an object variable. The refType contains an address to a MyStruct type and not the address of the original variable valueType. This can be shown by unboxing the refType back into a value type MyStruct.
MyStruct valueType2 = (MyStruct)refType;

We use casting to convert the reference type refType variable back into a MyStruct value type variable.

Containment
Containment or composition is the process of adding another class as a member of a class. For example a Person class can have a field of type Name. The program below shows an example of a class using containtment.
1 using System; 2 3 namespace ContainmentDemo 4 { 5 class Name 6 { 7 public string FirstName { get; set; } 8 public string LastName { get; set; } 9 10 public Name(string f, string l) 11 { 12 FirstName = f; 13 LastName = l; 14 } 15 } 16 17 class Person 18 { 19 private Name myName; 20 21 public Name MyName 22 { 23 get { return myName; } 24 set { myName = value; } 25 } 26 27 public Person(Name name) 28 { 29 myName = new Name(name.FirstName, name.LastName); 30 } 31 32 public override string ToString()

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

33 34 35 36 37 38 39 40 41 42 43 44 45 46 47}

{ return myName.FirstName + " " + myName.LastName; } } class Program { public static void Main() { Person person1 = new Person(new Name("John", "Smith")); Console.WriteLine(person1.ToString()); } }

Example 1 - Containment Demo


John Smith

We declared a class named Name that will serve as a field in another class (Lines 5-15). This class has a constructor that accepts the first name and the last name of a person. Those values will be added to their corresponding properties.
class Person { private Name myName; public Name MyName { get { return myName; } set { myName = value; } } public Person(Name name) { myName = new Name(name.FirstName, name.LastName); } public override string ToString() { return myName.FirstName + " " + myName.LastName; } }

The Person class contains a field having a type of Name and a its corresponding property. It will store the name of this Person object. Notice that the constructor accepts a Name object, and then used that name object to initialize the myName field. This is known as aggregation. We also override the ToString() method of the System.Object class to show the full name when this method is called.
class Program {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

public static void Main() { Person person1 = new Person(new Name("John", "Smith")); Console.WriteLine(person1.ToString()); } }

We now create a Person object. We used the contructor that accepts a Name object as an argument. We declared the Name object directly inside the parentheses and we also provided the first name and last name as arguments to the Name constructor. Finally, we printed the results using the customized ToString() method. Also note that classes can have objects having its own type. For example, a Person object can have a Person member. Consider the code below.
class Person { public Person Sibling { get; set; } public string Name { get; set; } }

You can see that a Person object was declared inside the Person class. So everytime you create a Person object or instance, that object has another Person object inside it.
Person person1 = new Person(); person1.Sibling = new Person(); person1.Name = "John Smith"; person1.Sibling.Name = "Mike Smith";

The above code demonstrated how to access and initialize that Person member. Since the Sibling property is also a Person object, it too has a Sibling object inside it. So you can provide as many siblings as you want for person1 like this:
person1.Sibling.Sibling = new Person(); person1.Sibling.Sibling.Name = "Franc Smith"; person1.Sibling.Sibling.Sibling = new Person(); person1.Sibling.Sibling.Sibling.Name = "Bob Smith"; //And so on...

Operator Overloading
Operator overloading allows you to customize the behaviors of C# operators depending on the type of its operands. Operator overloading allows a C# operator to interpret objects in a different way. Consider the example below.
1 namespace OperatorOverloadingDemo 2 { 3 class MyNumber

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21}

{ public int Number { get; set; } } class Program { public static void Main() { MyNumber firstNumber = new MyNumber(); MyNumber secondNumber = new MyNumber(); firstNumber.Number = 10; secondNumber.Number = 5; MyNumber sum = firstNumber + secondNumber; } }

Example 1 - Not Taking Advantage of Operator Overloading The highlighted code is not acceptable because the compiler doen't know what to add for those two objects. The behavior we want is to add the values of each of the Number property of the two operands and then create a new object containing the sum. This new object is then assigned to the sum variable.

Overloading Binary Operators


The program was modified to add operator overloading to a binary operator (+) which accepts two operands.
1 using System; 2 3 namespace OperatorOverloadingDemo2 4 { 5 class MyNumber 6 { 7 public int Number { get; set; } 8 9 public static MyNumber operator +(MyNumber n1, MyNumber n2) 10 { 11 MyNumber result = new MyNumber(); 12 result.Number = n1.Number + n2.Number; 13 return result; 14 } 15 } 16 17 class Program 18 { 19 public static void Main() 20 { 21 MyNumber firstNumber = new MyNumber(); 22 MyNumber secondNumber = new MyNumber(); 23

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

24 25 26 27 28 29 30 31 32}

firstNumber.Number = 10; secondNumber.Number = 5; MyNumber sum = firstNumber + secondNumber; Console.WriteLine("Sum = {0}", sum.Number); } }

Example 2 - Using Operator Overloading


Sum = 15

We add the code for operator overloading inside the class that will use it. The syntax for operator overloading is as follows:
public static returnType operator operatorSymbol(type operand1, type operand2) { //Codes here return result; }

As you can see, operator overloading uses a public static method. It must be static because all the class instance will use this method. It must be public so it can be used outside of the class. We then use the operator keyword followed by the symbol of that operator such as + or -. Overloading a binary operator requires two operands so the method has two parameters that will accept these operands. Inside the code, another object is declared which will hold the result variable. We add the Number properties of the two parameters and then store the result to the Number property of the result object. Finally, we returned the result object back to the caller. That result object is then assigned to the sum variable. The code below is possible to have the same effect.
MyNumber sum = new MyNumber(); sum.Number = firstNumber.Number + secondNumber.Number;

But using operator overloading, we reduced to just this:


MyNumber sum = firstNumber + secondNumber;

Not all operators can be overloaded. You cannot overload for example, the += operator. As an alternative, you can overload the + operator and that will automatically apply when you use the += operator. Another thing is > or < must be overloaded in pairs. You cannot for example, just overload the <.
public static bool operator >(MyNumber n1, MyNumber n2) { return (n1.Number > n2.Number); }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

public static bool operator <(MyNumber n1, MyNumber n2) { return (n1.Number < n2.Number); }

Overloading Unary Operators


Overloading a unary operator is just as easy. All you have to do is provide one parameter because unary operators accept 1 operand. For example, let's take a look at how we can overload the ++ unary operator.
public static MyNumber operator ++(MyNumber n1) { MyNumber result = new MyNumber(); result.Number = n1.Number + 1; return result; }

We can see that the code is similar to overloading a binary operator. We created a result object and assigned the new value of Number into it. We returned that result to the caller.

The is Operator
The is operator in C# allows you to test if an object can be converted into another object mainly by using casting. The is operator requires two operands, the one that will be tested and the type to which that object will be compared. The is operator returns a boolean value. For example, supposed we have a class named Animal, then we created an instance of it:
1 using System; 2 3 namespace IsOperatorDemo 4 { 5 class Animal 6 { 7 8 } 9 10 class Program 11 { 12 public static void Main() 13 { 14 Animal myAnimal = new Animal(); 15 16 if (myAnimal is Animal) 17 { 18 Console.WriteLine("myAnimal is an Animal!"); 19 } 20 } 21 } 22}

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Example 1 - Using the is Operator


myAnimal is an Animal

You see the is operator in action. We use it as the condition for our if statement. It checked if the myAnimal object is an instance of an Animal. Since that was true, the code inside the if statement executed. The is operator can also check if a particular object is in the inheritance heirarchy of a particular type. Consider the next example:
1 using System; 2 3 namespace IsOperatorDemo2 4 { 5 class Animal 6 { 7 8 } 9 10 class Dog : Animal 11 { 12 13 } 14 15 class Program 16 { 17 public static void Main() 18 { 19 Dog myDog = new Dog(); 20 21 if (myDog is Animal) 22 { 23 Console.WriteLine("myDog is an Animal!"); 24 } 25 } 26 } 27}

Example 2 - Is Operator Also Checks for Inheritance


myDog is an Animal!

So we created another class named Dog which is a derived class of Animal. We created a new Dog instance and then test if it is an Animal or a derived class of Animal using the is operator. Since the Dog inherits Animal, expression results to true. If you will transform this in a sentence: "My Dog is an Animal". What will happen if we reverse it?
Animal myAnimal = new Animal(); if (myAnimal is Dog) {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Console.WriteLine("myAnimal is a Dog!"); }

This will not produce an error. The expression will only result to false. This makes sense since not all animals are dogs but all dogs are animals. An alternative way to check for the type of an object is by using the typeof operator and the GetType() method of the System.Object class.
if (myAnimal.GetType() == typeof(Animal)) { }

The GetType() method returns a System.Type object which indicates the type of the object that called it. The typeof operator accepts the name of a type and returns the its corresponding System.Type object as well.

Interfaces
Interfaces are similar to classes but it only contains declarations for methods and properties. Interfaces can be considered as plugins to classes. The class that implements a particular interface is required to make an implementation for the members and methods of that interface. Let's take a look at how we can define and use an interface on a class.
1 using System; 2 3 namespace InterfaceDemo 4 { 5 interface ISample 6 { 7 void ShowMessage(string message); 8 } 9 10 public class Sample : ISample 11 { 12 public void ShowMessage(string message) 13 { 14 Console.WriteLine(message); 15 } 16 } 17 18 class Program 19 { 20 public static void Main() 21 { 22 Sample sample = new Sample(); 23 24 sample.ShowMessage("Implemented the ISample Interface!"); 25 } 26 } 27}

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Example 1 - Using an Interface


Implemented the ISample Interface!

We defined an interface named ISample. As a naming convention, interfaces use Pascal Casing and all interfaces should start with letter I. We defined a method inside the interface (line 7). You may notice that the method has no body. When defining methods inside an interface, you only need to write the header of the method. Also note that methods and properties defined inside an interface cannot have access specifieres since they should always be accessed by implementing classes. When a class needs to implement an interface, we use the same syntax as the one we used for inheritance. The class that implemented the interface provide the actual code for the members of that interface. As you can see in our Sample class, it provided implementation for the ShowMessage() method of the ISample interface. You are not limited to implementing just one interface for a class.
class Sample : ISample1, ISample2, ISample3 { //Implement all interfaces }

You can supply as many interface as you want but make sure that the class that implements multiple interface will provide implementations for all the members of those interfaces. If a class is inheriting a base class and implementing interfaces at the same time, the base class should go first in the list before the interfaces.
class Sample : BaseClass, ISample1, ISample2 { }

You can also use the is operator to check if a particular object implements an indicated interface.
Sample sample = new Sample(); if(sample is ISample) { Console.WriteLine("sample implements the ISample Interface!"); }

Another thing to note is you cannot create instances of an interface because it has no constructor. The following code is illegal.
ISample sample = new ISample();

The following is an example of an interface that has a property.


interface ISample

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

{ int Number { get; set; } }

You do not provide any code for the getter and the setter. The class that will implement the interface will handle that.
class Sample : ISample { private int number; public int Number { get { return number; } set { number = value; } } }

Interfaces can even implement other interfaces. Consider the following example.
1 using System; 2 3 namespace InterfaceDemo2 4 { 5 interface IBase 6 { 7 void BaseMethod(); 8 } 9 10 interface ISample : IBase 11 { 12 void ShowMessage(string message); 13 } 14 15 public class Sample : ISample 16 { 17 public void ShowMessage(string message) 18 { 19 Console.WriteLine(message); 20 } 21 22 public void BaseMethod() 23 { 24 Console.WriteLine("Method from base interface!"); 25 } 26 } 27 28 class Program 29 { 30 public static void Main() 31 { 32 Sample sample = new Sample(); 33 34 sample.ShowMessage("Implemented the ISample Interface!"); 35 sample.BaseMethod();

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

36 37 38}

} }

Example 2 - Interface Which Implement Another Interface You can see that even if the Sample class only implemented the ISample interface, it needs to implement all the members of IBase since ISample inherited from it.

Abstract Classes
Abstract classes are classes that always serves as base class for other classes. Abstract classes are somewhat similar to the interface but abstract classes can also have methods and properties that already have implementation. Abstract classes can also have constructors just like a normal class. You cannot instantiate abstract classes because abstract classes main purpose is to serve as the base class for derived classes so the instantiation will be handled by the derived classes. The following is an example of using an abstract class.
1 using System; 2 3 namespace AbstractClassDemo 4 { 5 public abstract class Base 6 { 7 protected int number; 8 protected string name; 9 10 public abstract int Number 11 { 12 get; 13 set; 14 } 15 16 public string Name 17 { 18 get { return name; } 19 set { name = value; } 20 } 21 22 public abstract void ShowMessage(); 23 24 public Base(int number, string name) 25 { 26 this.number = number; 27 this.name = name; 28 } 29 } 30 31 public class Derived : Base 32 { 33 public override void ShowMessage() 34 { 35 Console.WriteLine("Hello World!");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55}

} public override int Number { get { return number; } set { number = value; } } public Derived(int number, string name) : base(number, name) { } }

Example 1 - Using an Abstract Class To declare a class as abstract, just use the abstract keyword. Inside our abstract class, we defined two protected fields that will be used by our properties. One of our properties is also abstract. Notice that it also uses the abstract keyword. This property needs to be overriden by the classes that will inherit from this class. Since that property is abstract, the getters and setters should not have a body. You can see that abstract classes can also contain normal properties as demonstrated by the Name property. We defined an abstract method. Again, the abstract keyword was used and the deriving class should override this method. The abstract class has its own contructor. Abstract classes should have at least one member that is abstract. We defined another class that inherits from the Base class. We overriden the abstract property and method by using the overrides keyword. We also defined a constructor and use the base keyword to pass the value of the parameters to the base constructor. Again, you cannot create abstract classes, but since we made a class that inherits from it, you can use that derived class instead.

Sealed Classes
Sealed classes are classes that cannot be inherited by other class. Since sealed classes cannot be inherited, they cannot be abstract. The following program shows an example of a sealed class.
1 namespace SealedClassesDemo 2 { 3 public sealed class Base 4 { 5 private int someField; 6 7 public int SomeProperty 8 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29}

get { return someField; } set { field = value; } } public void SomeMethod { //Do something here } //Constructor public Base() { //Do something here } } public class Derived : Base { //This class cannot inherit the Base class }

We use the sealed keyword to indicate that a class is a sealed class. You can see that sealed classes are just like normal classes so it can also have fields, properties and methods. The deriving class was colored red becuase it will produce an error. Sealed classes are usefull if you are making a class that prohibits itself from being inherited by others.

Partial Classes
Partial classes allows you to define a class in multiple seperate files. For example, you can place all the fields, properties, and constructors inside a file, and place all the methods in another file. To define a class as partial, simply use the partial keyword. The following shows you a partial class difined inside two seperate files.
1 namespace PartialClassesDemo 2 { 3 public partial class Sample 4 { 5 private int sampleField; 6 7 public int SampleProperty 8 { 9 get { return sampleField; } 10 set { sample = value; } 11 } 12 } 13}

Example 1 - First Partial Class


1 namespace PartialClassesDemo 2 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

3 4 5 6 7 8 9 10}

public partial class Sample { public void DoSomething() { //Do something here } }

Example 2 - Second Partial Class Partial classes are defined using the partial keyword. These seperate files will defined one class named Sample. A field and a property was defined on the first one, and a method was defined on the other one. Note that the compiler requires the partial classes that will be combined to be inside the same namespace. As you can see in Example 1 and 2, both partial classes are inside the PartialClassesDemo namespace. When inheriting classes or implementing interfaces, only one part of the partial class needs to do the inheritance. If the first part implements IInterface1 and the second part implements IInterface2, then the final combined class implements both IInterface1 and IInterface2.
public partial class Sample : IInterface1 { } public partial class Sample : IInterface2 { }

The combined class will look like this:


public class Sample : IInterface1, IInterface2 { }

Partial classes are used in windows forms and in web forms to seperate the code files from the files that handle the overall design of those forms.

Polymorphism
Polymorphism allows classes within the same inheritance hierarchy to to change form or to adapt properly. Polymorphism allows a programmer to program in the general, rather than program in the specific. For example, in real world, all animals eat food, but they eat food in different ways. In a program for example, you can create an Animal class. You can polymorph (convert) that class into a Bird class and call the Fly() method. Let's look at an example behavior of polymorphism.
1 using System; 2 3 namespace PolymorphismDemo 4 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56}

class Animal { public virtual void Eat() { Console.WriteLine("The animal ate!"); } } class Dog : Animal { public override void Eat() { Console.WriteLine("The dog ate!"); } } class Bird : Animal { public override void Eat() { Console.WriteLine("The bird ate!"); } } class Fish : Animal { public override void Eat() { Console.WriteLine("The fish ate!"); } } class Program { public static void Main() { Dog myDog = new Dog(); Bird myBird = new Bird(); Fish myFish = new Fish(); Animal myAnimal = new Animal(); myAnimal.Eat(); myAnimal = myDog; myAnimal.Eat(); myAnimal = myBird; myAnimal.Eat(); myAnimal = myFish; myAnimal.Eat(); } }

Example 1 - Polymorphism Demo


The animal ate!

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The dog ate! The bird ate! The fish ate!

We defined 4 different classes. The Animal is the base class and will be derived by the other three classes. Each of the class has their own version of the Eat() method. We created instances for each class. We then called the Eat() method of the Animal instance as shown below.
Animal myAnimal = new Animal(); myAnimal.Eat();

The polymorphism takes place next. We assigned the Dog object to the Animal instance and called the Eat() method again. Now even though we are using an Animal instance, the Eat() method of the Dog class was called. This is the effect of polymorphism. We then assigned the other two objects (Bird and Fish) to the Animal instance and called their respective Eat methods. Notice that when we assigned the objects to the Animal instance, we didn't use casting. This is because no casting is required if you are storing an object of a derived class to an object that has a type which is higher than that of the derived class in the inheritance hierarchy. You can also initialized an Animal class with the contructor of any of its derived classes.
Animal myDog = new Dog(); Animal myBird = new Bird(); Animal myFish = new Fish(); myDog.Eat(); myBird.Eat(); myFish.Eat();

The code above will yield the same output as Example 1. Let's modify our program to show another concept of polymorphism.
1 using System; 2 3 namespace PolymorphismDemo2 4 { 5 class Animal 6 { 7 public virtual void Eat() 8 { 9 Console.WriteLine("The animal ate!"); 10 } 11 } 12 13 class Dog : Animal 14 { 15 public override void Eat() 16 { 17 Console.WriteLine("The dog ate!"); 18 } 19

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69}

public override void Run() { Console.WriteLine("The dog ran!"); } } class Bird : Animal { public override void Eat() { Console.WriteLine("The bird ate!"); } public override void Fly() { Console.WriteLine("The bird flew!"); } } class Fish : Animal { public override void Eat() { Console.WriteLine("The fish ate!"); } public override void Swim() { Console.WriteLine("The fish swam!"); } } class Program { public static void { Animal animal1 Animal animal2 Animal animal3

Main() = new Dog(); = new Bird(); = new Fish();

Dog myDog = (Dog)animal1; Bird myBird = (Bird)animal2; Fish myFish = (Fish)animal3; myDog.Run(); myBird.Fly(); myFish.Swim(); } }

Example 2 - Polymorphism Demo 2


The dog ran! The bird flew! The fish swam!

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We created three Animal objects and initialized them using the three derived class constructors. We used casting to store those animal objets to their respective instances. We do this so we can call the unique methods for each of the derived classes. There is a shorthand way of doing this but you will not be able to store the object. It is demonstrated by the following code:
((Dog)animal1).Run(); ((Bird)animal2).Fly(); ((Fish)animal3).Swim();

We simply put the expression inside parentheses since the expression will result into an anonymous object. You can also use polymorphism on interfaces. The code below shows you just that.
1 using System; 2 3 namespace PolymorphismDemo3 4 { 5 interface IAnimal 6 { 7 void Eat(); 8 } 9 10 class Dog : IAnimal 11 { 12 public void Eat() 13 { 14 Console.WriteLine("The dog ate!"); 15 } 16 } 17 18 class Bird : IAnimal 19 { 20 public void Eat() 21 { 22 Console.WriteLine("The bird ate!"); 23 } 24 } 25 26 class Fish : IAnimal 27 { 28 public void Eat() 29 { 30 Console.WriteLine("The fish ate!"); 31 } 32 } 33 34 class Program 35 { 36 public static void Main() 37 { 38 IAnimal myDog = new Dog(); 39 IAnimal myBird = new Bird(); 40 IAnimal myFish = new Fish();

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

41 42 43 44 45 46 47}

myDog.Eat(); myBird.Eat(); myFish.Eat(); } }

Example 3 - Polymorphism With Interfaces


The dog ate! The bird ate! The fish ate!

Mastering polymorphism and inheritance is required to be able to fully understand the world of .NET programming.

The as Operator
You can use the as operator in C# to convert a class into another class within the same inheritance heirarchy. The as operator is equivalent to using casting with some minor differences as will be explained later. The following shows the syntax of using the as operator.
myObject as DestinationType;

The left operand is the object that will be converted and the right operand is the destination type for which that object will be converted to. The following codes are equivalent.
Destination someObject = (Destination)myObject; Destination someObject = myObject as Destination;

The first code where you used casting will cause an exception if the conversion failsthat is, if the conversion is not possible for the two classes. The second code where you used as operator will return null if the conversion has failed. You could also use the as operator when calling a method of a derived class through its base class. Refer to the classes from the last lesson.
(myAnimal as Dog).Run();

Overloading Conversion Operators


You can overload the conversion behaviors in C#. For example, what if you want to convert one class into an unrelated class. We can overload the effect of casting or the implicit conversion. The example below shows a program that demonstrates how we can overload the conversion operators.
1 using System; 2

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

3 namespace OverloadingConversionsOperatorsDemo 4 { 5 class Animal 6 { 7 public int Height { get; set; } 8 9 public static implicit operator Plant(Animal animal) 10 { 11 Plant result = new Plant(); 12 result.Height = animal.Height; 13 return result; 14 } 15 } 16 17 class Plant 18 { 19 public int Height { get; set; } 20 21 public static explicit operator Animal(Plant plant) 22 { 23 Animal result = new Animal(); 24 result.Height = plant.Height; 25 return result; 26 } 27 } 28 29 class Program 30 { 31 public static void Main() 32 { 33 Animal myAnimal = new Animal(); 34 myAnimal.Height = 100; 35 36 //Implicit conversion 37 Plant myPlant = myAnimal; 38 39 Console.WriteLine("myAnimal.Height = {0}cm", myAnimal.Height); 40 Console.WriteLine("myPlant.Height = {0}cm", myPlant.Height); 41 42 myPlant.Height = 200; 43 44 //Explicit conversion 45 myAnimal = (Animal)myPlant; 46 47 Console.WriteLine("\nmyAnimal.Height = {0}cm", 48myAnimal.Height); 49 Console.WriteLine("myPlant.Height = {0}cm", myPlant.Height); 50 } 51 } }

Example 1 - Overloading Conversion Operators


myAnimal.Height = 100cm myPlant.Height = 100cm

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

myAnimal.Height = 200cm myPlant.Height = 200cm

You can see that the two classes, Animal and Plant, doesn't inherit each other therefore, they are not related(at least they are through System.Object). We defined the overloading of the conversion for each classes. The Animal class overloads its implicit conversion to the Plant class. Notice that we used the implicit keyword to indicate the we are overloading the implicit conversion, and the operator keyword to indicate that the method will be used for overloading. We write the name of the destination class. When we assign the Animal object to a Plant object, the code inside the overloading method will be executed. The method requires one parameter which is the a reference to the object being converted. There is no return type or method name, and the method should be static and public. Inside the method, we created a new instance of the Animal class and assigned the value of the Height property of the passed Plant object to the Height property of the created Animal class. Basically, you should put all the code for transferring the neccessary values from source object to destination object. On the second method, we used the explicit keyword instead of the implicit to signify that we are overloading the explicit conversion for that class. The syntax is pretty much the same except for the explicit keyword. We used the same behavior inside the overloading method. When we watch those overloaded conversions in actions, you can see that the values of Height was indeed copied to the other class. Notice the implicit conversion of the Animal class to a Plant object.
Plant myPlant = myAnimal;

We cannot invert the position of them like this:


Animal myAnimal = myPlant;

This is because no overloading method was defined for the explicit conversion in the Animal class. But we know that the Plant class has one, so the following code uses that overloaded explicit conversion.
Animal myAnimal = (Animal)myPlant;

We used casting to do an explicit conversion.

Arrays for Classes


You can use arrays of objects. Creating arrays of objects is pretty much the same as when creating arrays for primitive datatypes such as int. For example, we can create an array of the Person class.
1 using System; 2 3 namespace ArrayOfObjectsDemo

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

4 { 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31}

public class Person { public string Name { get; set; } public Person(string name) { Name = name; } } public class Program { public static void Main() { Person[] people = new Person[3]; people[0] = new Person("Johnny"); people[1] = new Person("Mike"); people[2] = new Person("Sonny"); foreach (Person person in people) { Console.WriteLine(person.Name); } } }

Example 1 - Creating an Array of Objects


Johnny Mike Sonny

We created a class that has one property. We then declared an array of that class and initialized them with new instances. We displayed the value for the property of each instance using a foreach loop. You can use the other techniques you have learned when creating arrays. For example, you can recreate the program in Example 1 to use the other version of initializing and declaring arrays.
Person[] people = new Person[] { new Person("Johnny"), new Person("Mike"), new Person("Sonny") };

Here, the people array was declared with 3 elements because the compiler automatically counts the number of instances you provided. You can use these techniques for creating multidimensional and jagged arrays involving classes.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Indexers
Indexers allow you to access an element of a private array or collection field. When you indicate an index for an instance of a class, indexers will get the right data indicated by the index. The following program shows an example of an indexer:
using System; 1 2 namespace IndexersDemo 3 { 4 public class Person 5 { 6 private string[] friends; 7 8 //Constructor to add friends 9 public Person(params string[] friends) 10 { 11 this.friends = friends; 12 } 13 14 //This is the indexer 15 public string this[int index] 16 { 17 get { return friends[index]; } 18 set { friends[index] = value; } 19 } 20 } 21 22 public class Program 23 { 24 public static void Main() 25 { 26 //Create a new person and add some friends 27 Person person = new Person("Jenny", "Robert", "Susan", 28 "Charles", "Mandy"); 29 30 for (int i = 0; i < 5; i++) 31 { 32 //You can now access each element of the 33 // private field by specifying the index 34 Console.WriteLine(person[i]); 35 } 36 37 //Changing the second element to John 38 person[1] = "John"; 39 } 40 } 41 }

Example 1 - Indexers Demo


Jenny Robert Susan

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Charles Mandy

We created a class containing a private array that will store the friends of the Person instance (line 7). We also defined a constructor that will accept string values and assign them to the friends field (lines 10-13). We defined an indexer (lines 16-20) for the specified class. The indexer is just like a property, but instead of indicating a name, we used the this keyword and a parameter that will determine the index. We then provide the setters and getters. Inside the getter, we return the array element specified by the value of index. Inside the setter, we assigned the value to the element indicated by the index. We then created an instance of that class and gave some values as friends of the Person object (line 28). We queried all the elements of the private friends field of the instance using a for loop (lines 30-35). Notice that we didn't indicate any properties to get the values. We simply call the value of the element by specifying the index inside square brackets next to the name of the instance just like how we access array elements. You can also use the same referencing technique when assigning values to private array or collection fields. Without indexers, then we have to create a public property for the friends field.
public string[] Friends { get { return friends; } set { friends = value; } }

And you access the private array field by using the above property.
Console.WriteLine(person1.Friends[0]); person1.Friends[1] = "John";

One disadvantage of indexers is that you can only create one indexer per class. For example, if you have private fields named friends and classmates, you need to choose which to put indexer among those private fields. It is better to provide an indexer to an array field that is most useful for the class and then provide public properties for all the private arrays and collections including the one that has given an indexer. Note that you can also use string type as the index. This can be used if you are accessing a Dictionary inside your class. Dictionaries will be discussed in later lessons.

Exception Handling and Debugging


No matter how good a programmer is, he will always encounter errors or bugs. Testing for errors eats up a large percentage of program development. It would be better if there are ways to prevent this errors or at least "degrade gracefully", that is, inform the user about certain errors instead of the program suddenly crashing and showing up cryptic error messages the user can't understand.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Thankfully, C# has ways to do just that. .NET Framework offers a large collection of Exception classes for specific errors. Exceptions are .NET's way of saying an error was found while the program is running. The .NET Framework contains a large collection of exception classes that you can use to handle different errors on different situations. You can even create your own exception class! Exceptions are "thrown" by the program, and you need to "catch" these exceptions and act accordingly. For example, in the computer world, an integer can never be divided by 0. Try that on a calculator and you will receive an error. If a C# program encounters such an error, it will throw a DivideByZeroException which is an exception that is thrown when you divide a number by zero. Bugs are another term for errors or code that produce unwanted behavior to a program. Debugging is the process of removing those bugs, which means, removing the errors and misbehaviors. Visual Studio and Visual C# Express has tools for debugging, which finds errors and allows you to fix them. You will learn how to effectively use these tools to remove bugs(errors) from your program. Excessive testing and debugging of programs are necessary before you deploy the final version of your program.

Unhandled Exceptions
Unhandled exceptions are exceptions that were not properly handled by the program causing the program to terminate. We will demonstrate here what will happen if a program detects an exception during runtime and there is no exception handling used. You will see how exception can potentially destroy the flow or execution of your application. We are running our examples from the beginning up until now using Non-Debug mode. Running a program that contains no errors using Non-Debug or Debug modes has minimal difference. Here, we will clearly see the difference of each modes. Let's create our test program. Create a new Console Application and name it ExceptionTest. Use the following code.
1 using System; 2 3 namespace UnhandledExceptionDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 int five = 5; 10 int zero = 0; 11 12 //Generate an exception by dividing 5 by 0 13 int result = five / zero; 14 } 15 } 16}

Example 1 - A Program without Exception Handling


COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Dividing an integer by 0 is illegal and will cause a System.DivideByZeroException.

No Exception Handling (Non-Debug Mode)


Run the program in Non-Debug mode by hitting Ctrl+F5 shortcut. The program will successfully compile but you will get the following error message.
Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero. at ExceptionTest.Program.Main() in C:\Users\TheUser\AppData\Local\Temporary Proje cts\ExceptionTest\Program.cs:line 9

Then a window will prompt showing that the program was terminated.

Figure 1 - Unhandled Exception Window As you can see the label "Unhandled Exception". This is because the error was not handled properly because we did not use any exception handling techniques. These details are usually not needed by the one who will use your program.

No Exception Handling (Debug Mode)


There is a better way to see information about an unhandled exception. And that is by running the program in debug mode. You can go to Debug > Start Debugging to start Debug Mode. You can also hit the F5 key, or click the green play button located at the toolbar. It will now start debugging the program. During Debug Mode, Visual C# Express will stop executing and bring you to you code. The statement that produced the error will be highlighted in yellow and the Exception Assitant will show up.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 2 - The Exception Assistant The Exception Assistant is a helpful window that describes the exception that was unhandled and tries to give some tips on how you can troubleshoot or fix them. If the Exception Assistant is hidden, simply clicked again on the statement that threw the exception.

try and catch Statements


You can handle errors by using a try...catch statement. You wrap the code that you suspect to trigger an error inside a try block. The catch block contains the codes to be excecuted when an error is encountered. The following program demonstrates using try...catch statements.
1 using System; 2 3 namespace TryCatchDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 int result; 10 int x = 5;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

11 int y = 0; 12 13 try 14 { 15 result = x / y; // Exception will be thrown 16 } 17 catch 18 { 19 Console.WriteLine("An attempt to divide by 0 was 20detected."); 21 } 22 23 } 24 } }

Example 1 - The try...catch Statements


An attempt to divide by 0 was detected.

Inside the try block, we divided x which has a value of 5 by y which contains 0. The calculation will cause a DivideByZeroException. Note in C#, saying an exception was thrown simply means that a particular error was encountered by the program. That's why the catch block was named like that, becuase it "catches" the exceptions that were thrown. Since an exception was thrown, the codes inside the catch block will be executed. If the line of code causes an error, it will jump immediately to the catch block skipping the following lines. Therefore:
try { result = x / y; //Error: Jump to catch block Console.WriteLine("This line will not be executed."); } catch { Console.WriteLine("An attempt to divide by 0 was detected."); }

You can indicate a specific type of exception that you want to handle by indicating it on the catch block like this:
try { result = x / y; //ERROR } catch (DivideByZeroException) { Console.WriteLine("An attempt to divide by 0 was detected."); }

Additionaly, you can provide a variable that will hold the values for exception.
try {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

result = x / y; //ERROR } catch (DivideByZeroException error) { Console.WriteLine(error.Message); } Attempted to divide by zero.

The variable will hold useful informations about the exception that was thrown. We used the Message property to show the description of the message. Every exception class has descriptions about the errors. You will learn more properties of Exception in later lessons. If you are expecting more than one error to occur within the try block, you can provide multiple catch blocks but you should specify the type of exception for each of them.
int result; int x = 5; int y; try { y = Int32.Parse(Console.ReadLine()); result = x / y; } catch (DivideByZeroException error) { Console.WriteLine(error.Message); } catch (FormatException error) { Console.WriteLine(error.Message); }

Since the value of y is determined from the input of the user, the value can be a non-zero integer. But there is a problem. What if the user types a non-numerical value such as a letter. They cannot be properly converted to an int datatype so a FormatException will be thrown. When this exception is thrown, the catch block for the FormatException will be excecuted. The calculation for the quotient of the x and y will be skipped. What if you want to catch all the possible errors inside the try block? Simply use the generic Exception class. Every exceptions in .NET inherits from this class therefore, you can store any type of exception inside an object of the Exception class.
try { //Put your codes to test here } catch (Exception error) { Console.WriteLine(error.Message); }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Now, you don't need to worry that an error may get away. The catch block will handle every error that is detected within the try block and then show the appropriate message for that particular exception. Note that if you will use the Exception base class in a catch block together with other derive Exception classes, then the base Exception class must be placed at the final catch block.
try { //Put your codes to test here } catch (DivideByZeroException) { Console.WriteLine("Division by zero is not allowed."); } catch (FormatException) { Console.WriteLine("Error on converting the data to proper type."); } catch (Exception) { Console.WriteLine("An error occured."); }

This makes sense because if you place it in the first catch block, then it will always be match first and the other catch blocks after it will never be executed even if they have the specific exception that matches the one thrown by the program. You can also use the is operator or check the type of the exception to assign specific behaviors depending on the errors catched.
try { } catch(Exception error) { if (error is DivideByZeroException) { Console.WriteLine("Cannot divide by zero!"); } if (error is FormatException) { Console.WriteLine("Format cannot be accepted!"); } }

The catch block uses the Exception class to catch all the exceptions thrown by the program. Inside the catch block, you can then test what kind of Exception was thrown using an if statement and the is keyword.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Using finally Blocks


Using finally blocks, you can provide a code that will always execute even if exceptions are thrown. We learned that if an exception was thrown inside a try block, all the following codes in the try block will be skipped because the execution will immediately jump to the catch block. Those skipped codes could have a vital role in the program. That's the purpose of the finally block. You place the codes that you think is essential or needs to be executed inside the finally block. The following program shows an example of using a finally block.
1 using System; 2 3 namespace FinallyBlockDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 int result; 10 int x = 5; 11 int y = 0; 12 13 try 14 { 15 result = x / y; 16 } 17 catch (DivideByZeroException error) 18 { 19 Console.WriteLine(error.Message); 20 } 21 finally 22 { 23 Console.WriteLine("finally blocked was reached."); 24 } 25 } 26 } 27}

Example 1 - Using the finally Block


Attempted to divide by zero. finally blocked was reached.

The finally block comes write after catch block. If there are multiple catch blocks, the finally block must be placed after them. Note that if you will use a finally block, you are allowed to not define a catch block such as the following:
try { //some code } finally {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

//some code }

finally blocks are often used when you want to dispose of an object or close a database connection or file stream.

Throwing Exceptions
You can throw exceptions anywhere in the program to artificially create an occurance of an error. Additionally, you can create custom messages if you don't like the default message of an exception. The following program shows you an example.
1 using System; 2 3 namespace ThrowingExceptions 4 { 5 class Program 6 { 7 public static void Main() 8 { 9 int firstNumber, secondNumber, result; 10 11 Console.Write("Enter the first number: "); 12 firstNumber = Int32.Parse(Console.ReadLine()); 13 14 Console.Write("Enter the second number: "); 15 secondNumber = Int32.Parse(Console.ReadLine()); 16 17 try 18 { 19 if (secondNumber == 0) 20 { 21 throw new DivideByZeroException(); 22 } 23 else 24 { 25 result = firstNumber / secondNumber; 26 } 27 } 28 catch (DivideByZeroException error) 29 { 30 Console.WriteLine(error.Message); 31 } 32 } 33 } 34}

Example 1 - Manually Throwing Exceptions


Enter the first number: 10 Enter the second number: 0 Attempted to divide by zero.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

In line 19, we used the throw keyword followed by an instance of an exception class. We just gone straight to creating the instance and throwing it in just one line. For example, you can create an object first and then throw it.
DivideByZeroException error = new DivideByZeroException(); throw error;

You can also give your own error message by using an overloaded constructor of the Exception class which accepts a string as the error message.
throw new DivideByZeroException("Cannot divide by zero!");

This will modify the default error message stored in the Message property. Throwing exceptions are mostly use when a certain code will not naturally yield an error but you want to consider it an error anyways. The next lesson will show you something like that.

Exception Properties
The System.Exception base class is the class that is inherited by all exception classes in the .NET Framework. Therefore, the properties of the Exception class is available to other exception classes. The following table shows some notable properties of the System.Exception class which is shared by all of the other exception classes. Property Description InnerException Specifies the Exception instance that caused the current exception. Message Specifies the message that describes the exception. StackTrace Returns a string representation of the method-call stack. Figure 1 - System.Exception Properties

The Message Property


We have seen the Message property several times. It allows you to specify an error message which describes the Exception that was thrown. For example, consider the following code:
int x = 1; int y = 0; int z; try { z = x / y; } catch (Exception ex) { Console.WriteLine(ex.Message); }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Attempted to divide by zero.

We intentionally try to divide by zero so the catch block will be excecuted. Note that we provide an instance of the Exception class so we can use the Message property. We then print the content of the Message property. When you run the program, an error message will show up. Every predefined Exception class in the .NET framework has their corresponding error message stored in the Message property. If you are throwing exceptions, then you can use the overloaded constructor of the Exception class which accepts a string argument that is the error message.
try { if (y == 0) { throw new DivideByZeroException("You cannot divide by zero. Sorry my friend."); } else { z = x / y; } } catch (Exception e) { Console.WriteLine(e.Message); } You cannot divide by zero. Sorry my friend.

The InnerException Property


The InnerException property of the System.Exception class is used to determine the Exception that caused the current exception. For example, suppose a programmer wants to detect if the format of an account number is correct. The first thing to do is to convert it from string to int. If the account number cannot be converted properly to a numerical representation, then a FormatException will be thrown. Inside the catch block for the FormatException, you can then do some more processing and then throw another customized exception that describes the error more clearly. The following program shows you this example.
1 using System; 2 3 namespace InnerExceptionDemo 4 { 5 class Program 6 { 7 static int ProcessAccountNumber(string accountNumber) 8 { 9 try 10 { 11 return Convert.ToInt32(accountNumber); 12 } 13 catch (FormatException formatException)

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

14 { 15 throw new Exception("Invalid Account Number.", 16formatException); 17 } 18 } 19 static void Main(string[] args) 20 { 21 Console.Write("Enter an account number: "); 22 string input = Console.ReadLine(); 23 24 try 25 { 26 int accountNumber = ProcessAccountNumber(input); 27 } 28 catch (Exception ex) 29 { 30 Console.WriteLine("Current exception's message: {0}", 31ex.Message); 32 Console.WriteLine("Inner exception's message: {0}", 33 ex.InnerException.Message); 34 } 35 } } }

Example 1 - InnerException Demo


Enter an account number: abcde Current exception's message: Invalid Account Number. Inner exception's message: Input string was not in a correct format.

In lines 7-17, we defined a method named ProcessAccountNumber. This method accepts a string argument which is the string input given by the user. As you can see in line 25, this method is called and the input given by the user is passed as an argument. It is also enclosed in a try block because it might cause an exception. After the method is called the excecution will transfer to the first line of the ProcessAccountNumber() method. Inside that method is yet another try...catch statement. Inside the try block, we try to convert the string argument into a integer and return the value if successful. If the string argument cannot be converted, then a FormatException will be thrown and the succeeding catch block will handle it. Inside the catch block, we throw a new instance of the Exception class and provide a more descriptive message as the first argument, and the FormatException instance as the second argument which indicates the inner exception. The catch block inside the calling method (Main()) will then be executed (line 27) and there, we print the message of the new Exception and the message of the original inner exception that caused it by using the InnerException property and it's Message property.

The StackTrace Property


The StackTrace property of the System.Exception class allows you to inspect which method in the method-call stack produced the exception. This is a useful method when debugging since a

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

method might also call other methods which may result into errors. You might mistaken that method being called as the culprit but it might actually be the other methods it calls. The StackTrace shows the method-call stack as a string representation. To demonstrate this, the following code creates a deep method-call stack where the final method throws an exception.
1 using System; 2 3 namespace StackTraceDemo 4 { 5 class Program 6 { 7 static void Method1() 8 { 9 Method2(); 10 } 11 12 static void Method2() 13 { 14 Method3(); 15 } 16 17 static void Method3() 18 { 19 throw new Exception("Exception at Method3()"); 20 } 21 22 static void Main(string[] args) 23 { 24 try 25 { 26 Method1(); 27 } 28 catch (Exception ex) 29 { 30 Console.WriteLine(ex.StackTrace); 31 Console.ReadKey(); 32 } 33 } 34 } 35}

Example 2 - StackTrace Demo


at StackTraceDemo.Program.Method3() in C:\StackTraceDemo\Program.cs:line 19 at StackTraceDemo.Program.Method2() in C:\StackTraceDemo\Program.cs:line 14 at StackTraceDemo.Program.Method1() in C:\StackTraceDemo\Program.cs:line 9 at StackTraceDemo.Program.Main(String[] args) in C:\StackTraceDemo\Program.cs:line 26

Each line shows the method, file, and the line number where the exception was thrown. The first entry which is Method3() is the main source of the exception. The stack continues up to the Main() method which is the top of the method-call stack. Please note that you must run the program in debug mode to see the complete method-call stack.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

User-Defined Exceptions
You can create your own exceptions. User-defined exceptions must inherit from the Exception base class. We will create another separate class that inherits from the Exception base class. Create a new Console Application and name it UserDefinedExceptions. After the project is created, click the Add New Item button in the toolbar and browse for the Class template. Name the file NegativeNumberException.
1 using System; 2 3 namespace UserDefinedExceptions 4 { 5 class NegativeNumberException : Exception 6 { 7 public NegativeNumberException() 8 : base("The operation will result to a negative number.") 9 { 10 } 11 12 public NegativeNumberException(string message) 13 : base(message) 14 { 15 } 16 17 public NegativeNumberException(string message, Exception inner) 18 : base(message, inner) 19 { 20 } 21 } 22}

Example 1 - NegativeNumberException Class You can see in line 5 that our custom class inherits from the Exception class. As a convention, user-defined exception class names must be appended with the word "Exception" and it should define 3 constructors. The first one is the parameterless constructor, the second constructor accepts a string argument which defines the error message, and the third constructor accepts the error message, and the inner exception the caused the current exception. Let's try to use our very own exception class. In the Program.cs file, use the following codes.
1 using System; 2 3 namespace UserDefinedExceptions 4 { 5 class Program 6 { 7 public static void Main() 8 { 9 int firstNumber, secondNumber, difference; 10 11 Console.Write("Enter the first number: ");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32}

firstNumber = Int32.Parse(Console.ReadLine()); Console.Write("Enter the second number: "); secondNumber = Int32.Parse(Console.ReadLine()); difference = firstNumber - secondNumber; try { if (difference < 0) { throw new NegativeNumberException(); } } catch (NegativeNumberException error) { Console.WriteLine(error.Message); } } }

Example 2 - Using NegativeNumberException


Enter the first number: 10Enter the second number: 11 The operation will result to a negative number.

Since yielding a negative number as a result will not issue any kind of exception, we need to manually throw it ourselves . We ask two values from the user (line 11-15). We then calculated the difference of the two (line 17). Inside the try block, we tested if the result of the operation is a negative number (line 21). If it is, then we throw a new instance of the NegativeNumberException class (line 23). This will then be catched by the catch block and show the error message (line 24-26).

Debugging Using Visual Studio


Debugging is the process of detecting errors or bugs while your program is running. If you have successfully fix all the compilation and syntax errors with the help of the Error List window, the next step is finding logic errors and exceptions while the program is running. Visual Studio and Visual C# Express offers useful tools for debugging. With these tools, you can pause the execution of the program at certain points and monitor the values of the variables used by your program. You can do a step by step, line by line execution of code and you can go inside method calls. You can check details about the exception and you will be given tips on how to fix them.

Breakpoints

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Breakpoints allow your program to stop at certain points of the execution. You put breakpoints at a location of the code that you want to investigate. Breakpoints can only be set on executable lines of code. Once the program is suspended using breakpoints, you then use other tools of the Visual Studio to find errors in the code. We will use the program below to demonstrate the use of break points. Create a new Console Application and name it Breakpoints. Then replace the generated code with the code below.
1 using System; 2 3 namespace Breakpoints 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 Console.WriteLine("Line 10 Console.WriteLine("Line 11 Console.WriteLine("Line 12 Console.WriteLine("Line 13 Console.WriteLine("Line 14 Console.WriteLine("Line 15 Console.WriteLine("Line 16 Console.WriteLine("Line 17 Console.WriteLine("Line 18 Console.WriteLine("Line 19 } 20 } 21}

1"); 2"); 3"); 4"); 5"); 6"); 7"); 8"); 9"); 10");

Example 1 - Code for Breakpoint Demonstration

Adding Break Points


To add break points, find a line of executable code and click at the gray margin right beside that line of code. As an example, let's add a break at the second WriteLine statement.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Alternatively, you can right click the statement and then choose Breakpoints > Insert Breakpoint. The line of code or statement that has a break point will be covered in red. To remove a breakpoint, simply click the breakpoint or right click the line of code with the breakpoint and choose Breakponts > Delete Breakpoint. You can use the F9 shortcut key while in the desired line of code to toggle a breakpoint on or off. You can add as many breakpoints as you want at different locations of your code. Add another at the seventh WriteLine statement.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

To see the breakpoints in action, run the program in Debug mode by pressing F5 in the keyboard. Please note that you can stop debugging by pressing the blue square icon next to the Debug button in the Debug toolbar. The program will execute and suspend execution when it encounters the first break point.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The execution suspends the at the second WriteLine statement, executing the code that precedes it. If you will look at the console window, the first WriteLine statement has already executed. The yellow arrow indicates the current line that is being executed by the program. The corresponding line also has a yellow highlight to indicate that it is the one currently being executed. To continue to the next break point, you can use the same green play button located at the toolbar (there might be two green play buttons currently in the toolbar, choose any of the two). You can also press F5. Another way is by going to Debug > Continue.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Continuing to the next break point executes all the code between the source breakpoint and the destination breakpoint. If you will look again at the console, all the lines preceding the current breakpoint has been executed. You can see that the yellow arrow which indicates the currently executing line is now transferred to the next breakpoint. If there are no more breakpoints following the current break point, then the program will exit. You can also disable breakpoints so they will not activate temporarily. To do that, right click the break point and choose Disable Break Point, or you can right click the statement and choose Breakpoints > Disable Breakpoint. A disabled breakpoint will look like a hollow circle. To enable it, right click the disabled breakpoint, and choose Enable Breakpoint. You can use the shortcut Ctrl+F9 while your cursor is on the statement with the breakpoint to enable or disable a breakpoint.

Stepping Through Your Code


Once you set up a break points, you can use certain commands to step through you code line by line. This allows you to carefully examine what each line of code does and how it affects the program. Create a new Console Application and write the following code that we will use in this lesson.
1 using System; 2 3 namespace SteppingThroughCode 4 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30}

public class MyClass { public static void ShowMessage() { Console.WriteLine("Hello World!"); Console.WriteLine("Have a nice day!"); } } public class Program { public static void Main() { Console.WriteLine("Line 1"); Console.WriteLine("Line 2"); Console.WriteLine("Line 3"); MyClass.ShowMessage(); for (int i = 0; i < 5; i++) { Console.WriteLine("Hi there!"); } } }

Example 1 - Code to Demonstrate Stepping Through the Code Add a break point to the first WriteLine statement of the Main method.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We will now demonstrate how you can step through parts of your code by using the Step Over, Step Into, and Step Out commands. Run the program in Debug mode by pressing F5 on your keyboard. The execution will stop at the first breakpoint. We will now start stepping through code at this break point.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The commands for stepping through your code are located at the Debug toolbar in the toolbars section of the IDE.

Click the Step Over icon to make the program execute the current line and proceed to the next line of code. Examine the yellow highlight and arrow move 1 step down. Also examine the console for the output, you will see that the first WriteLine statement was executed.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Stepping through your code line by line executes the code one line at a time. Continue clicking the Step Over button until you reach the MyClass.ShowMessage() method.

We will now try to use the Step Into command. The command is located at the left of the Step Over button in the toolbar.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

This command will enter the currently selected method and will bring you to the definition of that method. You will then be able to execute the lines inside the method one by one.

You can use the Step Over command to go to the next line of the method. To go outside the method, you can use the Step Out command.

The Step Out command will execute the remaining part of the method and then you will be brought back to the caller of the method.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Clicking the Step Over button once more will bring us to a for loop statment. Stepping through code will execute the conditions and statements of the loop and after reaching the end of the loop, the cursor will go back to the beginning of the loop to increment the counter and test the condition. If the condition is true, then you will enter the loop again, if not, then you be taken outside the loop and to the next statement. Stepping through code is useless without knowing how to examine each line of code. The next lesson will teach you how to view values of variables and members of objects.

Viewing Values of Variables


When in Debug Mode, you can go to Code View to inspect values and states of objects and variables. You can use breakpoints to temporary suspend your program from running so you can examine your code. Visual Studio and Visual C# Express offers tools that allows you to see how the program runs. Create a new Console Application and and name it DebuggingTechniques. Use the following code.
1 using System; 2 3 namespace DebuggingTechniques 4 { 5 6 public class Person 7 { 8 public string FirstName { get; set; } 9 public string LastName { get; set; } 10 public int Age { get; set; } 11 12 public Person() : this("", "", 0) { } 13

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51}

public Person(string fn, string ln, int a) { FirstName = fn; LastName = ln; Age = a; } } public class Program { static void Main() { Person firstPerson = new Person ("John", "Smith", 20); Person secondPerson = new Person(); string firstName; string lastName; int age; firstName = "Mike"; lastName = "Welsh"; age = 30; secondPerson.FirstName = firstName; secondPerson.LastName = lastName; secondPerson.Age = age; Console.WriteLine("First Person Details: "); Console.WriteLine("First Name: {0}", firstPerson.FirstName); Console.WriteLine("Last Name: {0}", firstPerson.LastName); Console.WriteLine("Age: {0}\n", firstPerson.Age); Console.WriteLine("Second Person Details: "); Console.WriteLine("First Name: {0}", secondPerson.FirstName); Console.WriteLine("Last Name: {0}", secondPerson.LastName); Console.WriteLine("Age: {0}", secondPerson.Age); } }

Example 1 - Code for Viewing Variables Demonstration Add a break point to the first line of code of the Main method. We will now demonstrate how we can monitor the values of variables and objects. Run the program in Debug Mode. The execution will stop at the first breakpoint. The Quick Info window will show up contaning the name of the variable and its current value.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The current value of firstPerson object is null, since no values has been assigned to it yet. The current line is not yet executed. You can see a familiar pin icon. Clicking this icon will pin the Quick Info window so it will not auto-hide when you release your mouse. To unpin it, put the mouse over the pinned Quick Info window and press the pin icon again or the close button. If you hover your mouse over a type or class, you can see some details about it such as it's inheritance hierarchy.

Use the Step Over command to execute the current code and move to the next line of code. Since the previous line of code has been executed, firstPerson now has been initialized with values thanks to its constructor. If you hover again to the firstPerson object, you will now be presented with the DataTip window. You will notice that it doesn't contain null as a value but the full name of the its class. You will also notice a + icon at its left side, clicking this will show all the properties and fields(if any) of the current object together with their respective values.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

You might also notice the magnifying glass icon on some members. Clicking this will bring the Text Visualizer window which shows you the full content of the varaible incase it is too large.

If you click the values in the DataTip window, you change them. For example, click on the value of the FirstName field and change the value from "John" to "Joseph" then press enter. Note that this editing capability can also be done in the Quick Info window.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Locals Window


The Locals Window is a central location where you can view all the values of variables and objects currently in use by the program. The Locals Window is automatically shown when you run the program in Debug Mode. It is located at the lower left portion of the IDE. Press Step Over until you reach the first WriteLine statement. Now look at the Locals Window

You will see a list of all the variables currently in use. The columns consist of the Name, Value and Type. For complex types such as classes, you will see a + icon at the left side of the name, click these will show the members of the class together with their values. You can also modify the values of the variables by double clickng the values in the Locals Window.

The Watch Window


The Watch Window allows you to type a name of the variable and view its current value. You can even do arithmetic expressions with the variable such as finding the resulting value when another value is added to the variable. The Watch Window can be accessed(by default) as a tab where the Locals Window is located.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can type the name of the variable at the Name column. Once the enter key is pressed, the value of the variable will show up in the Value column. You can also try out arithmetic expressions such as adding a constant value or another variable inside the Name column so you can test the value of a variable after modification.

Collections
We learned that arrays allows you to store multiple values with the same datatype. The arrays inherit the System.Array abstract class which provides methods and properties for simple data such as the length of the array. Ordinary arrays in C# have fixed length and once they have been declared with an initial length, you cannot increase or decrease the length of that particular array. The .NET Framework offers a better alternative to arrays and most of those classes and interfaces are contained inside the System.Collections namespace. For example, the ArrayList class has the same basic behavior as the normal Array but it allows you to dynamically change the length and add or remove its elements during program execution. In the following exercises, we will discover how to create a class that contains a collection of objects by implementing or inheriting certain interfaces and methods.

ArrayList Class
The ArrayList class allows you to store values of different data types and also gives you the ability to add and remove elements anytime you want. The following examples show a simple functionality of the ArrayList class.
1 using System; 2 using System.Collections; 3 4 namespace ArrayListDemo 5 { 6 public class Program 7 { 8 public static void Main() 9 { 10 ArrayList myArray = new ArrayList();

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

11 12 13 14 15 16 17 18 19 20 21 22 23 24}

myArray.Add("John"); myArray.Add(5); myArray.Add(true); myArray.Add(3.65); myArray.Add('R'); foreach (object element in myArray) { Console.WriteLine(element.ToString()); } } }

Example 1 - ArrayList Demo


John 5 true 3.65 R

To be able to use the ArrayList class, you must import System.Collections namespace. We created an new instance of the ArrayList class. To add new elements to the array, the Add method was used. It accepts an argument of type object therefore, you can pass any type of values to it since everything inherits object in C#. We then add five values of different data types to show the ability of the ArrayList class to hold different types of values. We then read each of the values using a foreach loop. Since the ArrayList class has different data types, we cannot use a specific datatype for the variable that will hold each of this values inside the for loop. We used object instead so every element can be stored. Inside the loop, we used the ToString() method to show the values. Note that you can also access each elements using their index just like normal arrays. For example, the code below uses a for loop to read each element.
for (int i = 0; i < myArray.Count; i++) { Console.WriteLine(myArray[i].ToString()); }

Note the use of the Count property. The Count property is like the Length property of an ordinary array. It counts the number of elements of the ArrayList object. We accessed each element using their index. Another thing to note is that you can give an initial capacity for the ArrayList class. For example, you can indicate that the ArrayList object can have five elements using an overloaded constructor.
ArrayList myArray = new ArrayList(5);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Those five slots will have empty values unless you use the Add method to add new ones. If the slots are full and you add another one, the size of the ArrayList object will be adjusted accordingly. You can resize the size of the capacity of the ArrayList object by changing the value of the Capacity property. Another version of the ArrayList class' constructor is the one that accepts an object that implements ICollection interfaces. The System.Array is an example of that object. Therefore, you can pass an array to the constructor and the values of that array will be copied to the ArrayList object.
object[] array = {"John", 5, true, 3.65, 'R' }; ArrayList myArray = new ArrayList(array);

You can use the Remove method of the ArrayList class to remove elements. The Remove method accepts an object that matches the value of an element in an array. It will remove the first occurance of the element that has that value. If you remove an element that is not in the last position, any element following it will adjust their position so that the empty position that the removed element was used to be will be occupied. This is demonstrated by the following code.
1 using System; 2 using System.Collections; 3 4 namespace ArrayListDemo2 5 { 6 public class Program 7 { 8 public static void Main() 9 { 10 ArrayList myArray = new ArrayList(); 11 12 myArray.Add("John"); 13 myArray.Add(5); 14 myArray.Add(true); 15 myArray.Add(3.65); 16 myArray.Add('R'); 17 18 for (int i = 0; i < myArray.Count; i++) 19 { 20 Console.WriteLine("myArray[{0}] = {1}", i, myArray[i]); 21 } 22 23 //Remove element number 1 24 myArray.Remove(5); 25 26 Console.WriteLine("\nAfter removing myArray[1] (The value 275)...\n"); 28 29 for (int i = 0; i < myArray.Count; i++) 30 { 31 Console.WriteLine("myArray[{0}] = {1}", i, myArray[i]); 32 } 33 }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

34 }

Example 2 - Using the Remove() Method


myArray[0] myArray[1] myArray[2] myArray[3] myArray[4] = = = = = John 5 True 3.65 R

After removing myArray[1] (The value 5)... myArray[0] myArray[1] myArray[2] myArray[3] = = = = John True 3.65 R

Since we removed the value inside myArray[1], all the succeeding elements will adjust their positions. So myArray[2] will now be myArray[1], myArray[3] will be myArray[2] and so on. You can also specify the index of the element you wish to remove by using the RemoveAt method. It has one parameter which is the index of the element you are removing in the array.

Adding and Removing Multiple Items


You can add or remove multiple items at the same time using the AddRange and RemoveRange methods. Add range can accept an array of values and add those values to the ArrayList object.
ArrayList myArray = new ArrayList(); myArray.Add(1); myArray.Add(2); int[] numbers = { 3, 4, 5 }; myArray.AddRange(numbers); foreach(object element in myArray) { Console.WriteLine(element); } 1 2 3 4 5

The RemoveRange method is quite different compared to AddRange. It accepts two int parameters, the index of the starting element and the number of elements to remove. For example, if you want to remove elements 2 to 6, you can use the following code:
myArray.RemoveRange(2, 5);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Searching for Values


You can check if a particular value is inside the list by using Contains() method. It accepts an object argument and returns true if that value is found inside the list of elements. You can also use the IndexOf() and LastIndexOf() methods to determine the index of a certain value. The IndexOf() method returns the index of the first occurance of a given value. The LastIndexOf() returns the index of the last occurance of the value. They will both return -1 if the value was not found within the list of elements. You can also use the BinarySearch method that also accepts the value to be searched. The BinarySearch() method is suitable if you are searching a value within a very long list of elements.

Sorting ArrayList Values


You can use the Sort() method to sort the elements in the array. Numbers are sorted from lowest to highest, while strings and characters are arranged alphabetically. If you use this method, all the elements should be comparable. For example, you cannot mix up a string and an int inside the ArrayList and then use the Sort() method. You will learn in a later chapter that you can also use a comparer to customize the way the Sort() method sorts elements.

Creating Your Own Collection


C# gives you the ability to create your own collection classes. For example, you can create a class that can contain multiple instances of another class. This class will have the features such as adding and removing new instances from its collection. The following program shows an example.
1 using System.Collections; 2 3 namespace CreatingYourOwnCollection 4 { 5 public class Animal 6 { 7 public string Name { get; set; } 8 public int Age { get; set; } 9 public double Height { get; set; } 10 11 public Animal(string name, int age, double height) 12 { 13 Name = name; 14 Age = age; 15 Height = height; 16 } 17 } 18 19 public class Animals : CollectionBase 20 { 21 public void Add(Animal newAnimalnewAnimal) 22 { 23 List.Add(newAnimalnewAnimal); 24 }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

25 26 27 28 29 30 31}

public void Remove(Animal oldAnimal) { List.Remove(oldAnimal); } }

Example 1 - Creating Your Own Collection The above code declares two classes. First is the Animal class (lines 5-17) which will represent an element in our collections class. The second is our collection class named Animals (lines 1930) which will contain a collection of Animal objects. To benefit with the functionality of collections, our class inherits the CollectionBase class. We need to import the System.Collections namespace. The CollectionBase class has methods such as Add() and Remove() and a List property that will contain the collection of objects. If we want to add or remove objects, we simple use the List property and the corresponding methods. The methods of the List property accepts an object and not an Animal for example. So when defining an indexer, we need to cast the result first before returning it to the user.
public Animal this[int index] { get { return (Animal)List[index]; } set { List[index] = value; } }

The code above is added to our collection class so we can access each objects in the collection through their index positions. Again, we used the List property to access the objects and by using the specified index. Since the List contains object elements, we need to cast them to Animal objects first. Let's try to create a program that uses the classes we have just created.
1 namespace CreatingYourOwnCollection 2 { 3 public class Program 4 { 5 public static void Main() 6 { 7 Animals animalCollection = new Animals(); 8 9 animalCollection.Add(new Animal("Jack", 10, 100)); 10 animalCollection.Add(new Animal("Sussy", 5, 10)); 11 animalCollection.Add(new Animal("Frank", 3, 5)); 12 13 for (int i = 0; i < animalCollection.Count; i++) 14 { 15 Console.WriteLine("Animal {0}", i + 1); 16 Console.WriteLine("Name: {0}", animalCollection[i].Name); 17 Console.WriteLine("Age: {0}", animalCollection[i].Age); 18 Console.WriteLine("Height: {0}\n", 19animalCollection[i].Height); 20 }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

21 22 }

} }

Example 2 - Custom Collection in Action


Animal 1 Name: Jack Age: 10 Height: 100 Animal 2 Name: Sussy Age: 5 Height: 10 Animal 3 Name: Frank Age: 3 Height: 5

We created a new instance of the Animals collection class then added three instances to it using the Add method. We then iterate through each element using a for loop to show that we can access them by their indexes. You can also use a foreach statement to loop for each animal.
foreach (Animal animal in animalCollection) { }

Once you learn generics, there is an easier way of creating a collection of any types without creating a class that inherits from CollectionBase.

Creating Dictionaries
You can also make a class that dirives from DictionaryBase. This way, you can access each elements by key (usually of type string) and they will return its associated value. When calling an item from a dictionary, we can call it by its key and not by its index. The following code creates a class that implements DictionaryBase.
1 using System.Collections; 2 3 namespace DictionariesDemo 4 { 5 public class Animal 6 { 7 public string Name { get; set; } 8 public int Age { get; set; } 9 public double Height { get; set; } 10 11 public Animal(string name, int age, double height) 12 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37}

Name = name; Age = age; Height = height; } } public class Animals : DictionaryBase { public void Add(string key, Animal newAnimalnewAnimal) { Dictionary.Add(key, newAnimalnewAnimal); } public void Remove(string key) { Dictionary.Remove(key); } public Animal this[string key] { get { return (Animal)Dictionary[key]; } set { Dictionary[key] = value; } } }

Example 1 - Creating Your Own Dictionary We defined a class Animal that will be used by our dictionary class. We then create a class that inherits the DictionaryBase class. You can now define the methods for adding and removing dictionary entries. The Add method requires a string key and the Animal object we are adding to the dictionary. We used the Dictionary property of the DictionaryBase class to add the entry to the dictionary using the passed arguments. The Remove method only requires the key of the object we are trying to remove. We also use the Dictionary property to remove items. We defined an indexer that accepts an string key instead of an int value. Lets create a class that demonstrates the capability of our dictionary class.
1 using System; 2 3 namespace DictionariesDemo 4 { 5 public class Program 6 { 7 public static void Main() 8 { 9 Animals animalDictionary = new Animals(); 10 11 animalDictionary.Add("Animal1", new Animal("John", 10, 100)); 12 animalDictionary.Add("Animal2", new Animal("Sussy", 5, 10)); 13 animalDictionary.Add("Animal3", new Animal("Frank", 3, 5)); 14 animalDictionary.Add("Animal4", new Animal("Mark", 7, 15)); 15 16 Console.WriteLine("Accessing entries by their keys");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

17 18 19 20 211)].Name); 22 23 24 25 26 27 28 29 30 31 32 } 33 } }

for (int i = 0; i < animalDictionary.Count; i++) { Console.WriteLine(animalDictionary["Animal" + (i + } animalDictionary.Remove("Animal3"); Console.WriteLine("\nFrank was removed from the dictionary."); Console.WriteLine("\nIterating using foreach loop."); foreach (DictionaryEntry animal in animalDictionary) { Console.WriteLine((animal.Value as Animal).Name); }

Example 2 - Custom Dictionary In Action


Accessing entries by their keys John Sussy Frank Mark Frank was removed from the dictionary. Iterating using foreach loop. John Mark Sussy

We created a new instance of the Animals dictionary class. We then add some instances to it and their respective keys. We first demonstrated using a for loop that we can access each of its entries by using their keys as their index. We used the Remove() method to remove the third entry in the dictionary using its key. We then use a foreach loop to try to read all the values. But you might notice that something is different. We used the DictionaryEntry as the type because each item in a dictionary class has that type instead of, for example, an Animal. Tha actual object is inside the Value property of the DictionaryEntry. We cast this value to its appropriate type. We will learn next how we can avoid using a DictionaryEntry and use the actual type by using iterators.

Iterators
An iterator is a block of code that supplies all the values to be used in a foreach loop. A class that represents a collection can implement the System.Collections.IEnumerable interface. This interface requires an implementation for the GetEnumerator() method which returns an IEnumerator interface. The IEnumerator interface has a Current property which contains the current value that was returned by the iterator. It also has a MoveNext() method which moves the

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Current property to the next item and returns false if there is no more item left. The Reset() method returns the iterator back to the first item. The IEnumerator interface is implemented by different types of collections in the .NET library and this includes arrays which is why you can use the foreach loop on them. Supposed we have a code like this which reads every element of an array using a foreach loop.
int[] numbers = { 1, 2, 3, 4, 5 }; foreach(int n in numbers) { Console.WriteLine(n); }

To better understand iterators, let's translate the above foreach loop into a call to an array's GetEnumerator() method.
int[] numbers = { 1, 2, 3, 4, 5 }; IEnumerator iterator = numbers.GetEnumerator(); while(iterator.MoveNext()) { Console.WriteLine(iterator.Current); }

As you can see, we first retrieve the array's iterator using the GetEnumerator() method which returns an IEnumerator interface. We used this iterator in a while loop and called the MoveNext() method. The MoveNext() method retrieves the first element of a collection such as an array and if it is successful in retrieving, the method will return true. It will then retrieve the second element on the next call and so on until it reaches the end of the array where it will return false because there is no more to retrieve. The retrieved value of the element can be accessed using the IEnumerator.Current property. Now that you know how an iterator works and its major contribution when using iterating values from collections, let's consider creating our own iterators. Using an iterator requires a yield return statement. A yield return statement is different from an ordinary return statement. One visible difference is the use of the keyword yield before the return keyword. Consider the following example:
1 using System; 2 using System.Collections; 3 4 namespace IteratorsDemo 5 { 6 class Program 7 { 8 public static IEnumerable 9 { 10 yield return "Message 11 yield return "Message 12 yield return "Message

GetMessages() 1"; 2"; 3";

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

13 14 15 16 17 18 19 20 21 22 23}

} public static void Main() { foreach (string message in GetMessages()) { Console.WriteLine(message); } } }

Example 1 - A Simple Iterator


Message 1 Message 2 Message 3

The GetMessages() method returns an IEnumerable object which in turn contains a definition for a GetEnumerator() method. The yield return statement brings the value it will return to the variable that will hold each of the values in a foreach loop. The first yield return statement in the method is returned to the foreach loop inside our Main() method. When the foreach loop calls again the GetMessages() method, then the next yield return statement is returned to it. This continues until no more yield return statement is found. You can interupt the returning of values from the method by using the yield break statement.
public static IEnumerable { yield return "Message yield return "Message yield break; yield return "Message } GetMessages() 1"; 2"; 3";

Creating Our Own Iterator


Let's take a look an an example of using an iterator by creating a new class which contains an ArrayList field that will hold some values. We will then create an iterator which will provide a foreach loop with the values from the ArrayList field.
1 using System.Collections; 2 using System; 3 4 namespace IteratorsDemo2 5 { 6 public class Names : IEnumerable 7 { 8 private ArrayList innerList; 9 10 public Names(params object[] names) 11 { 12 innerList = new ArrayList();

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

13 14 foreach (object n in names) 15 { 16 innerList.Add(n); 17 } 18 } 19 20 public IEnumerator GetEnumerator() 21 { 22 foreach (object n in innerList) 23 { 24 yield return n.ToString(); 25 } 26 } 27 } 28 29 public class Program 30 { 31 public static void Main() 32 { 33 Names nameList = new Names("John", "Mark", "Lawrence", 34"Michael", "Steven"); 35 36 foreach (string name in nameList) 37 { 38 Console.WriteLine(name); 39 } 40 } 41 } }

Example 2 - User Defined Iterator We created a collection class named Names which will hold a list of names. The definition of the class in line 6 shows that we did not implement the CollectionBase class. This is because the CollectionBase class implements the IEnumerable iterface and already has an implementation of the GetEnumerator() method. We are creating our collection class from scratch and we will define our own iterator. Our class simply implements the IEnumerable interface which now requires our class to have an implementation of the GetEnumerator() method. Our own iterator is defined in lines 20-26. Inside it, we iterate through each of the value from the innerList field. Each value is converted to string and then yield returned to the caller. Lines 35-38 shows our own iterator in work. Since the yield returns in our iterator converts each value to string, we can simply use string as the type of the range variable of the foreach loop. When the next value will be retrieved from the iterator via the foreach loop in our Main() method, the foreach loop inside the iterator goes to the next iteration and yield return the next value from the innerList. Without the iterator, we won't be able to use foreach loop for our Names class. Creating our own iterator gives us a great control on the behavior of the foreach loop when dealing with our class. For example, we can edit our iterator to only return names starting with letter M.
public IEnumerator GetEnumerator()

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

{ foreach (object n in innerList) { if (n.ToString().StartsWith("M")) yield return n.ToString(); } }

We used the StartsWith() method of the System.String class to determine if a name starts with letter M. If the names starts with letter M, then we yield return it. If not, then it is ignored and then next name in the innerList is inspected. With our modified GetEnumerator() method, when you use a foreach loop on an instance of the Names class, only names starting with letter M will be retrieved. Even if you can do the above technique of modifying GetEnumerator() method, it would be more practical to just define a separate method for retrieving names starting with a specified letter.
public IEnumerable GetNamesStartingWith(string letter) { foreach (object n in innerList) { if (n.ToString().StartsWith(letter)) yield return n.ToString(); } }

We now have a more flexible iterator that you can use to retrieve names which starts with a specified letter or substring. Note that we used IEnumerable instead of IEnumerator. The rule is use IEnumerable for all iterators except the GetEnumerator() method which is used as default by the foreach loop. The IEnumerable already has a GetEnumerator() method. When you call this iterator, you need to modify our foreach loop in lines 35-38.
foreach (string name in nameList.GetNamesStartingWith("M")) { Console.WriteLine(name); }

Improving Our Animals Dictionary Class


A more practical use of an iterator is applying it to a collection or dictionary class. For example, the dictionary class we made in the last lesson uses DictionaryEntry as the type of variable that will store each of the elements inside a foreach loop. By using an iterator, we can use Animal as the type of the class and save as a little casting. The following code demonstrates this to you.
1 2 3 4 5 6 7 using System.Collections; using System; namespace IteratorsDemo3 { public class Animal {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64}

public string Name { get; set; } public int Age { get; set; } public double Height { get; set; } public Animal(string name, int age, double height) { Name = name; Age = age; Height = height; } } public class Animals : DictionaryBase { public void Add(string key, Animal newAnimalnewAnimal) { Dictionary.Add(key, newAnimalnewAnimal); } public void Remove(string key) { Dictionary.Remove(key); } public Animal this[string key] { get { return (Animal)Dictionary[key]; } set { Dictionary[key] = value; } } public new IEnumerator GetEnumerator() { foreach (object animal in Dictionary.Values) { yield return (Animal)animal; } } } public class Program { public static void Main() { Animals animalDictionary = new Animals(); animalDictionary.Add("Animal1", animalDictionary.Add("Animal2", animalDictionary.Add("Animal3", animalDictionary.Add("Animal4", new new new new Animal("John", 10, 100)); Animal("Sussy", 5, 10)); Animal("Frank", 3, 5)); Animal("Mark", 7, 15));

foreach (Animal animal in animalDictionary) { Console.WriteLine(animal.Name); } } }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Example 3 - Adding an Iterator to a Custom Dictionary Lines 38-44 defines an iterator for our Animals dictionary class. The DictionaryBase class already implements the IEnumerable interface which has the GetEnumerator() method that is used for getting values from a collection using a foreach loop. We implement our own GetEnumerator() method. Notice that it has a return type of IEnumerator.The new keyword simply indicates that the program should use this version of GetEnumerator() instead of the one already defined in the DictionaryBase. Inside the method, we use a foreach loop to cast and yield return each of the Animal objects from the Values properties. Recall that without an iterator, using a foreach loop for our dictionary class looks like this:
foreach (DictionaryEntry animal in animalDictionary) { Console.WriteLine((animal.Value as Animal).Name); }

With the new iterator defined in our dictionary class, you can now use the type of each element in a foreach loop without using the DictionaryEntry class.
foreach (Animal animal in animalDictionary) { Console.WriteLine(animal.Name); }

Each iteration of the above foreach loop triggers an iteration of the foreach loop inside our iterator and each loop executes a yield return statement.

Generics
Generics are classes, methods, or interfaces that adapts their behaviors depending the data types assigned to them. For example, we can make a generic method that can accept any kinds of data. We can make one method showing int, double, or string values depending on the type indicated. If you don't use generics, then you have to make multiple methods, or even overloaded methods for each of the possible types.
public void Show(int number) { Console.WriteLine(number); } public void Show(double number) { Console.WriteLine(number); } public void Show(string message) { Console.WriteLine(message); }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

By using generics, we can use one generic method that can accept any values.
public void Show<E>(E item) { Console.WriteLine(item); }

Generic methods will be explained in the next lesson. You might wonder, why can't we just use the object type since object can accept any values in C#. You can see that by using generics, we didn't use any casting. You will learn about some limitations of generics.

Generic Methods
If you are creating multiple methods with the same functionality but varies on the data type that they will accept or contribute on their functionality, then you can use generic methods to save you some typing. A general structure of a generic method is as follows:
returnType methodName<type> (type argument1) { type someVariable; }

You can see that a type was indicated after the method name, wrapped inside angle brackets. Now every occurance of this type will be substituted by the type that was indicated inside these brackets. The program below shows an example of using a generic method.
1 using System; 2 3 namespace GenericMethodDemo 4 { 5 public class Program 6 { 7 public static void Show<X>(X val) 8 { 9 Console.WriteLine(val); 10 } 11 12 public static void Main() 13 { 14 int intValue = 5; 15 double doubleValue = 10.54; 16 string stringValue = "Hello"; 17 bool boolValue = true; 18 19 Show(intValue); 20 Show(doubleValue); 21 Show(stringValue); 22 Show(boolValue); 23 } 24 } 25}

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Example 1 - Using a Generic Method


5 10.54 Hello true

We created a generic method that can accept any kind of data and then show its value. We then pass different datas to the same function. The method changes that type of X depending on the type of data passed as an argument. When we passed for example an int value, all the occurance of X in the method will be replaced by int so the method will look like this if an int value is passed.
public static void Show (int val) { Console.WriteLine(val); }

You can also explicitly indicate the type to use by the generic method when you call that method (although it is not necessary). For example the calls to the method above can be rewritten like this:
Show<int>(intValue); Show<double>(doubleValue); Show<string>(stringValue); Show<bool>(boolValue);

Note about using generic methods, we cannot include inside the code computations such as adding two numbers because the compiler cannot determine the actual type of the operands and if they can be properly added to each other. We simply show the values inside our method because the compiler can show any type of data using the Console.WriteLine() method.
public static void Show<X>(X val1, X val2) { Console.WriteLine(val1 + val2); }

You can also specify multiple type specifiers for a generic method. Simply seperate each type with a comma.
public static void Show<X, Y>(X val1, Y val2) { Console.WriteLine(val1); Console.WriteLine(val2); }

You can pass two different values to the method like this:
Show(5, true); // OR

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Show<int, bool>(5, true);

Therefore, X will be of type int and Y will be substituted with bool. You can also pass two arguments with the same type.
Show(5, 10); // OR Show<int, int>(5, 10);

Generic Classes
Defining a generic class is as simple as defining a generic method. It has a similar syntax of using angle brackets and specifying a type parameter. The following program shows an example of a generic class.
1 using System; 2 3 namespace GenericClassDemo 4 { 5 public class GenericClass<T> 6 { 7 private T someField; 8 9 public GenericClass(T someVariable) 10 { 11 someField = someVariable; 12 } 13 14 public T SomeProperty 15 { 16 get { return someField; } 17 set { someField = value; } 18 } 19 } 20 21 public class Program 22 { 23 public static void Main() 24 { 25 GenericClass<double> genericDouble = new 26GenericClass<double>(30.50); 27 GenericClass<int> genericInt = new GenericClass<int>(10); 28 29 Console.WriteLine("genericDouble.SomeProperty = {0}", 30 genericDouble.SomeProperty); 31 Console.WriteLine("genericInt.SomeProperty = {0}", 32 genericInt.SomeProperty); 33 34 genericDouble.SomeProperty = 100.32; 35 genericInt.SomeProperty = 50; 36 }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

37 }

Example 1 - Creating a Generic Class


genericDouble.SomeProperty = 30.50 genericInt.SomeProperty = 10

We created a generic class that has a field, property and a constructor (Lines 5-19). All the occurances of T will be substituted by the type that will be indicated when we create the generic class. When creating a new instance of our generic class, we specify the type inside the angle brackets. Like generic methods, you can also specify multiple type parameters for a generic class.
public class GenericClass<T1, T2, T3> { private T1 someField1; private T2 someField2; private T3 someField3; }

You cannot create new objects of type T1, T2 or T3 because you don't know what types they actually are so the following is not allowed.
public GenericClass //Constructor { someField1 = new T1(); someField2 = new T2(); someField3 = new T3(); }

Non-generic class can inherit generic classes. But you must define a type of the type parameter for the generic base class.
public class MyClass : GenericClass<int> { }

A generic class can also inherit a non-generic class.

Type Constraints
Generic code must work for every type of data. You can specify type constraints for a generic method or class which only allows type specified in the list of constraints.
public class GenericClass<T> where T: constraint { //some code }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

To specify a type constraint, we use the where keyword, then the name of the type parameter, a colon, then a comma seperated list of allowed types for the type parameter. For example, suppose we have a class named Animal. We can specify a generic class with a type constraint of Animal.
public class GenericClass<T> where T: Animal { //some code }

The type parameter T can now accept the Animal type. It can also accept any type that is a derived class of Animal, for example, a Dog class. You can use the keyword struct as the type constraint to allow all value types, or class keyword, to allow all reference types. You can also use the interface keyword so it can only accept objects that implements the interface that was indicated.
public class GenericClass<T> where T: struct { //some code } public class GenericClass<T> where T: class { //some code } public class GenericClass<T> where T: interface { //some code }

You can also specify that the type parameter must only accept classes that has a parameterless constructor. You can do this by using new() as the constraint.
public class GenericClass<T> where T: new() { //some code }

In cases where there are multiple constraints, you must put the new() in the last position. If there are mulitiple type parameters and you want to assign different constrains for each, you can follow another where statement right after the first.
public class GenericClass<T1, T2> where T1 : Animal where T2 : Plant { //some code }

If the generic class is inheriting from another class, then it must come first before the constraints.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

public class GenericClass<T1, T2> : BaseClass where T1 : Animal { //some code }

One note when using type constraints, you can only use non-sealed types. Primitive types are invalid such as int, double ,boolean, and string. Suppose we have the following generic class:
public class GenericClass<T> where T : int { //some code }

Sealed classes cannot be inherited. If we used a sealed type such as int, then the generic class will not be "generic" since we can only pass a single type.

Generic Collections
We can define a generic collection which is a collection of any type that you specify. For example, we can use the List<T> class fro the System.Collections.Generics namespace. The List<T> can a collection of objects of T type. So List<int> for example will be a collection of integer values.
1 using System; 2 using System.Collections.Generic; 3 4 namespace GenericCollectionDemo 5 { 6 public class Animal 7 { 8 public string Type; 9 10 public Animal(string type) 11 { 12 Type = type; 13 } 14 } 15 public class Program 16 { 17 public static void Main() 18 { 19 List<Animal> animals = new List<Animal>(); 20 21 animals.Add(new Animal("Dog")); 22 animals.Add(new Animal("Cat")); 23 animals.Add(new Animal("Rat")); 24 25 foreach (Animal animal in animals) 26 { 27 Console.WriteLine(animal.Type); 28 } 29 } 30 }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

31}

Example 1 - Using the List<T> Generic Collection


Dog Cat Rat

The List<T> class also offers AddRange(), Remove(), RemoveAt() and other methods that we used on our collection class in the previous lessons. You can also use the Dictionary<TKey, TVal> class that also resides in the same namespace. The TKey determines the type of the key (usually string), and the TVal specifies the type of the value.
using System; 1 using System.Collections.Generic; 2 3 namespace GenericCollectionDemo2 4 { 5 public class Animal 6 { 7 public string Type; 8 9 public Animal(string type) 10 { 11 Type = type; 12 } 13 } 14 public class Program 15 { 16 public static void Main() 17 { 18 Dictionary<string, Animal> animals = new Dictionary<string, 19 Animal>(); 20 21 animals.Add("Animal1", new Animal("Dog")); 22 animals.Add("Animal2", new Animal("Cat")); 23 animals.Add("Animal3", new Animal("Rat")); 24 25 foreach (Animal animal in animals.Values) 26 { 27 Console.WriteLine(animal.Type); 28 } 29 } 30 } 31 }

Example 2 - Using the Dictionary<K,V> Generic Dictionary We defined a dictionary that has string keys and Animal values. To iterate through the dictionary items, you can use the Values property which contains all the items in the dictionary. You can also use the Keys property to get all the keys in the dictionary.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

The classes we presented are quite similar to the collection and dictionary classes that inherit from CollectionBase and DictionaryBase classes. But we don't need to create those collection class anymore. The List<T> and Dictionary<TKey, TVal> made it instant just by supplying the type of the items. You may still prefer using custom collections and dictionaries if you want to add additional functionality for the Add, Remove and other common methods.

Nullable Types
You can make simple types such as int and double to allow null to be their values. Null values are only storable to reference types like string and other objects. C# allows you to transform value types so that they can handle null values. You can use the System.Nullable<T> type where T is the type that will be transformed into a nullable type.
Nullable<int> nullInt = null; Nullable<double> nullDouble = null;

Alternatively, you can append the ? to the type.


int? nullInt = null; double? nullDouble = null;

You can use the following code to test if a variable contains a null value.
if (nullInt == null) { } if (nullDouble.HasValue) { }

Since we turned them to nullable types, they can't be stored into a variable with an original nonnullable type. The following is not allowed.
int? nullInt = null; int myNumber = nullInt;

You need to convert it back first to its original type.


int myNumber = (int)nullInt;

If you convert a nullable type with a null value back to its original form, then an exception will be thrown. When involving two nullable types(except bool?) in an operation, if any of the operands is null, then the result will be also null. For bool?, the following table shows the possible results. (Note that & and | also represents && and ||). var1 var2 var1 & var2 var1 | var2 true null null true

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

var1 var2 var1 & var2 var1 | var2 false null false null null true null true null false false null null null null null If you want to prevent an expression from resulting into a null even if one of its operands can have a value of null, you can use the ?? operator which is called the null coalescing operator .
int? nullInt = null; int number = nullInt * 5 ?? 10;

The second line demonstrates the use of the ?? operator. To further illustrate the meaning of that operator, the below code which uses the ternary operator is equivalent to it.
int number = (nullInt * 5) == null ? (nullInt * 5) : 10;

If the expression of the left operand of the ?? operator results to null, then the operand at the right of the ?? operator will be picked and stored inside the variable. If the left operand does not result into a null, then the result or the value of the left operand will be stored instead.

Events
Events are behaviors or happenings that occur when the program is running. Events are often used in visual programming like windows and web forms. Some examples of events are clicking a mouse, typing a text in a text box, changing the selected item in a list and many more. In console applications, we can manually trigger events. You must subscribe to an event which means adding event handlers or code blocks that will be executed when a particular event happens. Multiple event handlers can subscribe to an event. When an event triggers, all the event handlers will execute. The following example shows a simple usage of events.
1 using System; 2 3 namespace EventsDemo 4 { 5 public delegate void MessageHandler(string message); 6 7 public class Message 8 { 9 public event MessageHandler ShowMessage; 10 11 public void DisplayMessage(string message) 12 { 13 Console.WriteLine(message); 14 } 15 16 public void ExecuteEvent() 17 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

18 ShowMessage("Hello World!"); 19 } 20 } 21 22 public class Program 23 { 24 public static void Main() 25 { 26 Message myMessage = new Message(); 27 myMessage.ShowMessage += new 28MessageHandler(myMessage.DisplayMessage); 29 30 myMessage.ExecuteEvent(); 31 } 32 } }

Example 1 - Events Demo


Hello World!

An event handler is a method that matches the signiture of a delegate. For example, we defined a delegate that has a void return type and one string parameter. This will be the signiture of the event handler method. After defining the delegate, we created a class that contains an event. To define an event, the following syntax is used.
accessSpecifier event delegateType name;

The delegate type is the type of delegate to be used. The delegate is used to determine the signiture of the event handler that can subscribe to it. We created an event handler DisplayMessage that has the same signiture as the delegate. We also created another method that will trigger the event manually. Events cannot be triggered outside the class the contains it. Therefore we will use this method to indirectly execute it. Inside our Main method, we created a new instance of the Message class. On the next line, an event handler subscribed to our event. Notice we used the += operator which means, we are adding the event handler to the list of event handlers for an event. We created a new instance of MessageHandler delegate and inside it, we passed the name of the event handler. We then call the ExecuteEvent method to trigger the event and show the message. You will see the usefullness of events when you work with windows forms or web forms in ASP.NET.

Anonymous Methods
Anonymous methods are methods that are not actually defined, therefore, only suited for onetime use. Anonymous methods are targeted for delegates. The following shows the syntax of an anonymous method.
delegate (parameters) { //Code for the anonymous method };

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

For example, we can define a delegate, create an object of that delegate, and assign the anonymous method to it.
1 using System; 2 3 namespace AnonymousMethodsDemo 4 { 5 public delegate void MessageDelegate(string message); 6 7 public class Program 8 { 9 public static void Main() 10 { 11 MessageDelegate ShowMessage = new MessageDelegate( 12 delegate(string message) 13 { 14 Console.WriteLine(message); 15 } 16 ); 17 18 ShowMessage("Hello World!"); 19 } 20 } 21}

Example 1 - Anonymous Method Demo


Hello World

Here, the delegate has a return type of void, and one string parameter. When we created our delegate object, we passed an anonymous method to it. Notice that the anonymous method has also a string parameter to match its delegate. The return type is automatically detected. If no return statement was found, then it will have a return type of void. If your delegate has a return type, then your anonymous method should have a return statement returning the proper type of value. You can even simplify the code above like this:
MessageDelegate ShowMessage = delegate(string message) { Console.WriteLine(message); };

Anonymous methods can also be used when subscribing to events.


myClass.myEvent += delegate(string message) { Console.WriteLine(message); };

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Initializers
Initializers allow you to initialize values of properties within a class. If you have several properties for example, and you don't want to define a constructor that will get all the values that will be supplied for those properties, then you can use an object initializer. For example, consider the code below.
1 using System; 2 3 namespace ObjectInitializerDemo 4 { 5 public class Sample 6 { 7 public int Property1 { get; set; } 8 public string Property2 { get; set; } 9 public bool Property3 { get; set; } 10 } 11 12 public class Program 13 { 14 public static void Main() 15 { 16 Sample sampleClass = new Sample(); 17 sampleClass.Property1 = 100; 18 sampleClass.Property2 = "Sample"; 19 sampleClass.Property3 = true; 20 } 21 } 22}

Example 1 - Using an Object Initializer As you can see, we need to assign new values to each of the properties one by one if we don't define a proper constructor that will get all the three values in the initialization. By using object initializers, we can simplify our code.
public class Program { public static void Main() { Sample sampleClass = new Sample { Property1 = 100, Property2 = "Hello", Property3 = true }; } }

You used curly braces instead of parentheses and inside it, you list the properties and the values to be assigned to them. You seperate each property with a comma. When you use object initializers, the default parameterless constructor is called before each of the properties is

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

assigned with a value. Since the default constructor is executed before the values are assigned to properties, you can specify default values for properties so that you dont need to specify values for all the properties in the initializer. If you add a non-default constructor for your class, you must still provide a parameterless constructor to be able to use object initializers. You can even nest object initializers. Let's say our Sample class has a property of type Animal that has a Name and Age property.
Sample sampleClass = new Sample { Property1 = 100, Property2 = "Hello", Property3 = true, Property4 = new Animal { Name = "Kitty", Age = 3 }; };

Another type of initializer are collection initializers. Collection initializers are similar to array initializers but they are used on generic collections.
List<Person> people = new List<Person> { new Person("John"), new Person("Jenny"), new Person("Joe") };

The code below shows that without using collecition initializers, you need to manually add the each items using the Add() method or create a constructor that accepts the items for the collection.
List<Person> people = new List<Person>(); people.Add(new Person("John")); people.Add(new Person("Jenny")); people.Add(new Person("Joe"));

Type Inference
Type inference allows a variable to infer the type being assigned to it. No more should a variable be strongly typed. C# offers the var keyword for type inferece.
var myInt = 10; var myDouble = 5.67; var myString = "Hello";

The three variables above are implicitly typed, meaning that they will automatically change their types depending on the values assigned to them. You simply use the var keyword as the type of the variable. You can even store objects in a var variable.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

var sample = new SampleClass();

It can even hold arrays.


var myArray = new int [] { 1, 2, 3 }; //OR var myArray = new [] { 1, 2, 3 };

Notice that you can omit the type since the type will be infered depending on the values given. Since the type of the variable is determined by the value being assigned to it, you cannot simply declare a variable having a var type. The following code will not compile because it cannot determine the type to be assigned to the variable since no value was supplied.
var someVariable;

One final note about the var used as type. You cannot use it as return types or as types of parameters of a method.

Anonymous Types
You can define anonymous types which is a great way to define temporary types used for data storage types. Suppose that you just want a class that can hold three values inside its properties.
public class Sample { public int Property1 { get; set; } public double Property2 { get; set; } public string Property3 { get; set; } }

With anonymous types, you don't need to create storage classes such as the one shown above. You can define an anonymous type that has the same properties as the one above.
var anonymousType { Property1 = Property2 = Property3 = = new 10, 5.35, "Hello" };

The var keyword was used. The syntax is the same as object initializers but we didn't indicate a name of the class. After that declaration, you can use the properties of the anonymous type.
Console.WriteLine(anonymousType.Property1); Console.WriteLine(anonymousType.Property2); Console.WriteLine(anonymousType.Property3);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Note that once initialized, you cannot modify the values of the property of an anonymous type because they are readonly properties.

Extension Methods
Extension methods are methods that adds more functionality to .NET types or types that you have defined. For example, you can extend the System.String class by adding a Reverse method that reverses the string. The following program shows an example of an extension method.
1 using System; 2 3 namespace ExtensionMethodsDemo 4 { 5 public static class StringExtender 6 { 7 public static string Reverse(this string myString) 8 { 9 char[] reverse = myString.ToCharArray(); 10 11 for (int i = myString.Length - 1, j = 0; i >= 0; i--, j++) 12 { 13 reverse[j] = myString[i]; 14 } 15 16 string returnString = new string(reverse); 17 18 return returnString; 19 } 20 } 21 22 public class Program 23 { 24 public static void Main() 25 { 26 string myMessage = "This message will be reversed."; 27 28 Console.WriteLine(myMessage); 29 Console.WriteLine(myMessage.Reverse()); 30 } 31 } 32}

Example 1 - Extention Methods Demo


This message will be reversed. .desrever eb lliw egassem sihT

To define an extension method, you first need to create a static class that will hold the extention method. You must import the neccessary namespace for the type that you want to extend. Inside the static class, we defined the extention method. Extention methods must also be static, can have any return type, and can possess any number of parameters just like any function. But extention methods follow a different syntax.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

public static returnType methodName(this type name, param1 ... paramN) { method codes... }

As you can see inside the parameters list, we first used the this keyword then the type (such as string) that we want to extend followed by an instance name. This will hold the instance of that type so that we can used it inside our method for manipulation. We then followed them by a comma-seperated list of parameters. The extension method we defined in Figure 1 needs no parameters. You can now create strings in your program and use the Reverse method. Note that extension methods are usefull if you want to extend predefined types and classes from the .NET Framework. You can also use it on your custom classes but it would be better to just add the method to the class itself. Inside the method, we declared a character array and assigned the value of the string message. We used the ToCharArray() method to convert the string into a series of characters. We do this so that we can modify each of the character of the message. We used a for loop that will iterate the character array from the beginning and the message from the last position. The last character of the string was assigned to the first position of the character array. The second to the last character of string is assigned to the second position of the character array and so on. Since the return type of the extention method is string, we need to convert the character array back to a string. We do this by creating a new instance of the string and use its constructor that accepts a character array. We then return the converted reversed string back to the caller. To give you an example of an extention method that has parameters, lets modify our extention method in figure one so that it will accept a boolean value that will determine whether to retain the casing of the string message.
1 using System; 2 3 namespace ExtensionMethodsDemo2 4 { 5 public static class StringExtender 6 { 7 public static string Reverse(this string myString, bool retainCase) 8 { 9 char[] reverse = myString.ToCharArray(); 10 11 for (int i = myString.Length - 1, j = 0; i >= 0; i--, j++) 12 { 13 reverse[j] = myString[i]; 14 } 15 16 string returnString = new string(reverse); 17 18 if (retainCase == false) 19 { 20 returnString = returnString.ToLower(); 21 } 22 23 return returnString;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38}

} } public class Program { public static void Main() { string myMessage = "THIS MESSAGE WILL BE REVERSED."; Console.WriteLine(myMessage); Console.WriteLine(myMessage.Reverse(false)); } }

Example 2 - Parametered Extention Methods


THIS MESSAGE WILL BE REVERSED. .desrever eb lliw egassem siht

We added a boolean parameter that will determine if the reversed message will retain the casing of the original message. We added an if statement that will use the parameter to determine whether to ratain the casing of the reversed message. The ToLower() method of the System.String class converts all the characters into its lowercase representation. The returned converted string is then assigned to the variable that will be returned by the extension method.

Lambda Expressions
Lambda expressions simplifies the syntax of anonymous methods. For example, the program below used an anonymous method that will be assigned to a delegate.
using System; namespace AnonymousMethod { public delegate void MessageDelegate(string message); public class Program { public static void Main() { MessageDelegate ShowMessage = new MessageDelegate( delegate(string message) { Console.WriteLine(message); } ); ShowMessage("Hello World!"); } } }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

By using lambda expressions, we can simplify the code like this:


using System; 1 2 namespace LambdaExpressionsDemo 3 { 4 public delegate void MessageDelegate(string message); 5 6 public class Program 7 { 8 public static void Main() 9 { 10 MessageDelegate ShowMessage = (message) => 11 Console.WriteLine(message); 12 13 ShowMessage("Hello World!"); 14 } 15 } 16 }

Example 1 - Using a Lambda Expression First, we indicate the parameter(s) without any type, then we use the => operator. We then write the statement(s) to be executed. The type of the parameter will automatically be detected by the compiler. Of course the lambda expression must still match the signiture of the delegate. There are many forms of lambda expressions. For example, the first lambda expression we introduced in Example 1 only has a single statement to execute. This is called an expression lambda. If your delegate for your lambda expression has no parameters, then all you need to do is don't provide any parameters in the lambda expression.
MessageDelegate ShowMessage = () => Console.WriteLine("Hello");

Note that you can also indicate the type of the parameters in a lambda expression.
MessageDelegate ShowMessage = (string message) => Console.WriteLine(message);

If you indicate the type of one parameter, then the other parameters should also have their type. For example, you cannot do the following.
MessageDelegate ShowMessage = (string message1, message2) => Console.WriteLine(message1);

If your lambda expression needs multiple statements, then you simply put braces. When a lambda expression has braces, it is called a statement lambda.
MessageDelegate ShowMessage = (message) => { Console.WriteLine(message);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Console.WriteLine("Some more message"); }

The following is an example of a lambda expression which returns a value.


SampleDelegate GetSquare = (number) => { return number * number; };

Note that when using the return statement, you should always use statement lambdas by enclosing the statement in curly braces. If a lambda expression should only contain a single return statement, then you can simplify the above code even more by transforming it to its expression lambda version.
SampleDelegate GetSquare = (number) => (number * number);

Note the use of parentheses to make the return expression more clearer. If a lambda expression has a single parameter and return statement, then you can simplify it even more by removing the parentheses.
SampleDelegate GetSquare = number => number * number;

But if a lambda expression has 2 or more parameters, then you must enclose the parameters in parentheses.
SampleDelegate GetSum = (num1, num2) => num1 + num2;

The above lambda expression has two parameters and returns the sum of the values of that two parameters.

Lambda Expression Example


Using lambda expressions, it is now easier to pass anonymous methods as arguments to other methods. Consider the example below.
1 using System; 2 3 namespace LambdaExpressionsDemo2 4 { 5 public delegate int Arithmetic(int x, int y); 6 7 public class Program 8 { 9 public static int GetResult(Arithmetic Operation, int num1, int 10num2) 11 { 12 return Operation(num1, num2); 13 } 14 15 public static void Main() 16 { 17 Console.Write("Enter first number: ");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

18 int num1 = Convert.ToInt32(Console.ReadLine()); 19 Console.Write("Enter second number: "); 20 int num2 = Convert.ToInt32(Console.ReadLine()); 21 22 Console.WriteLine(" Sum = " + GetResult((x, y) => x + y, num1, 23num2)); 24 Console.WriteLine("Difference = " + GetResult((x, y) => x - y, 25num1, num2)); 26 Console.WriteLine(" Product = " + GetResult((x, y) => x * y, 27num1, num2)); Console.WriteLine(" Quotient = " + GetResult((x, y) => x / y, num1, num2)); } } }

Example 2 - Lambda Expressions in Action


Enter first number: 5 Enter second number: 2 Sum = 7 Difference = 3 Product = 10 Quotient = 2

We created a delegate (line 5) that accepts two integer arguments and returns an integer value. We then use this delegate as a parameter for the GetResult method (lines 9-12). The other two parameters are the two numbers that will be involved in different operations as we will see. Since the first parameter is a delegate, the argument must be a reference to a method, an anonymous method, or a lambda expression. Using a lambda expression makes the code more readable and requires less typing. Lines 21-24 invokes the GetResult() method. Notice that each call has a lambda expression as its first argument. The only difference is the operation that every lambda expression will do on the two values. If we use anonymous methods instead, then our code would be longer and harder to read.

END OF LANGUAGE FUNDAMENTALS

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

C# WINDOWS FORM Visual Programming


Graphical User Interfaces (GUI) allow a user to interact easily with the program using different visual components. On the early days of the computer world, applications are text based and you type commands and input to make the program useful. You need to memorize a long list of commands to be able to work properly with the program. Modern software applications have graphical user interfaces. You see them in almost every program you use now. A professional looking graphical user interface is easy in the eyes and has a simple, yet attractive look and feel. A good graphical user interface also makes the commands more accessible and organized by using menus and grouping components. But creating a program with a user interface was once a tedious task. For you to even create a simple window that displays a message, you need to type lots of code. Creating an application with a graphical user interface was hard until the arrival of Visual Programming. Visual Programming makes it easy for you to create GUI applications by providing you a "canvas" where you simply drag the controls from the toolbox. Controls are visual elements that compose the GUI. You can interact with these controls to perform their functionality. Examples of controls are buttons, text boxes, labels, check boxes, and radio buttons. The term "visual" in Visual C# was from the concept of visual programming. Microsoft uses the term Windows Forms to represent every window in an application. Visual Studio allows you to create Windows Forms Applications easily. You can then create and design the form in the Design View.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 - Visual C# Express Design View Figure 1 shows the Design View in Visual C# Express 2010. You can see the form and some controls "drawn" in its surface. With the Designer View, you can see how the form will look when you run the program. The code for drawing and initializing controls are hidden from the programmer so you can concentrate on the functionality of the application. You can use Visual Studio's tools for designing controls such as aligning, anchoring, docking, and resizing controls. Visual programming saves development time and suitable for Rapid Application Development. Other languages that does not support visual programming requires dozens of code before you can even create a simple window that shows a short message.

Creating a Simple Windows Forms Application


You will now experience visual programming which is the "Visual" in Visual C#. Please note that this lesson guides you to the creation of a simple windows application which uses basic event-handling. I will show the steps for doing these and briefly discuss them. The concepts of forms, controls, event-handling, and certain parts Visual Studio used for designing will be discussed in their respective lessons.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Open Visual C# Express and go to File > New Project. Then from the list of templates, choose Windows Forms Application. A Windows Forms Application is a type of application that has a graphical user interface. Name the project MyFirstWindowsApplication.

Figure 1 - New Project Window You will be presented with a blank form. The selected tab tells that you are viewing the Form1.cs file in Designer View.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 2 - Newly Created Blank Form Two code files will be created that represent the form. But for now, we will concentrate on the file that is used to add functionality to the form. The form can be viewed in two modes, the Design View and Code View. The Designer will be shown if you are in design view. You will see here the actual form and any visual and non-visual controls you will add soon. You can also resize the forms by dragging the resizing handles of the form while in the Design View.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 3 - The Resizing Handles of the Form

Adding Controls to the Form


All the controls are located in the Toolbox. The Toolbox can be accessed via the Toolbox tab located by default at the left of the IDE. If it is not shown, you can go to View > Other Windows > Toolbox. Hover your mouse over or click the Toolbox tab to show the actual Toolbox.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 4 - Toolbox Tab The Toolbox is divided into categories and the most commonly used controls are located in the Common Controls category. To open a category and expose its control, simply click the category. The Toolbox will auto-hide by default. If you don't want that behavior, then you can click the pin icon beside the close button of the Toolbox. To add controls to the form, choose a control in the Toolbox and double click it. Alternatively, you can drag the control from the Toolbox to the form. Please note that you can only add controls to the client area of the form. The client area is the blank area of the form. You can delete a control or controls by selecting it in the designer and hitting Delete in your keyboard. Add a button control to the form. Most controls also has resizing handles just like the form itself. Resize and position the button as shown if Figure 5.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 5

Changing the Properties of Controls


You can change certain properties of the form and controls. We use the Properties Window to view and change the value of all the available properties of a selected control in the Design View. Note that some properties are not shown in the Properties Window and can only be accessed in code. Selecting a control is equivalent to single clicking a control in the Designer. For a demonstration of modifying control properties, select the button in the form, then go to the Properties Window. You can pin the Properties Window if you will be working with it frequently.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 6 - Changing Properties Find the Text property and change its value to "Click Me".

Figure 7 - Changing the Value of a Property

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The text inside the button in the Designer will update.

Figure 8 - Updated Windows Form You can also click the form in the Designer and change the Text property. When selecting the form, you need to click on any area of the form but not on the controls it contain.

Adding Event Handlers to Controls


The final part of this tutorial is showing you how to add event handlers to certain events of the controls. Events trigger when certain happenings occur. We put event handlers to an event. Event handling will be discussed in detail in a separate tutorial. Each control has its own default event. For example, the Button control has Click as its default event while the Form control has a default event of Load. Event handlers are methods that is associated with an event, and they execute when the associated event happens. The easiest way to add an event handler is to double click a control in the Designer. You can only do this if you want to add event handlers to the default event of a control. To demonstrate this, double click the button in the Designer. Visual Studio will automatically create an event handler and attached that event handler to the default event of the double clicked control. Once the event handler is created, you will be taken to the Code Editor, with the cursor positioned inside the generated event handler. All you need to do is type the codes that will run when the event occurs.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 9 - Newly Created Event Handler Don't mind the other parts of the code as there will be a seperate lessons that discuss them. Type the following code inside the event handler. Please only type the code inside the event handler of the following code. I included the event handler so you can clearly see where to type the code.
private void button1_Click(object sender, EventArgs e) { MessageBox.Show("You clicked the button!"); }

The MessageBox class allows you to call a message box used to prompt user with messages and information. The Show method shows the message box with a specified message. You will learn more about the MessageBox class later. Run the program and click the button. You will be presented with a message window with the message you specified as an argument to the Show method.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Another way of adding event handlers to events of controls especially for non-default events, is by going to the Properties Window. To demonstrate this, let's add a Load event to the form. Go back to Design View by clicking the Design Tab or using the Shift + F7 shortcut.

Select the form in the designer then go to the Properties Window and find the Events button. It is represented by a thunder bolt icon. If it is not visible, be sure that a control is selected in the Designer.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Properties Window will now show a list of events for the selected control in the Designer. Find the Load event of the form. Clicking the combo box beside it will show you the list of valid methods for the event that exist in the code of the form. You can then choose which method to attach to this event. We can also create a new event handler by double clicking the selected event in the Properties Window. You will be taken to the Code Editor with the proper event handler created for you. Add the highlighted code.
private void Form1_Load(object sender, EventArgs e) { button1.Text = "Text changed by the Load event"; }

This statement will modify the Text property of button in the form. The Load event of the form occurs once the form is finished loading. So when you run the program once more, as soon as the program has finished loading, the text inside the button will be changed.

You have now successfully created an simple event-driven windows forms application using the tools available in Visual Studio and Visual C# Express.

Event Handling
Graphical user interfaces in .NET and Visual C# uses event handling mechanism to handle events that occur while the program is running. Events are behaviors or happenings that occur when the program is running. Event handling is the process of monitoring for certain events to occur, and then executing codes when a specific event happens. Windows forms uses event handling to add functionality and respond with the user. Without event-handling, forms and user interfaces are pretty much useless. This tutorial assumes that you already learned the concepts of delegates and events . Events are declared using a delegate as a type. Delegates hold references to methods. The following is an example of declaring a delegate and an event.
public delegate void SampleEventHandler(int); public event SampleDelegate SampleEvent;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Based on the declaration of the delegate, the methods that it can accept must not return a value(void) and accepts a single int argument. We then used this delegate type to create our event. We will now add event handling to the event. Event handlers are methods that match the delegate type of the event and the ones that will be executed when the event occurs. Event handlers are attached to an event. Attached event handlers are executed when the event occurs. You can attach multiple event handlers to the event and they will all run when the event occurs. To attach an event handler to an event, you first create it. When creating an event handler, be sure that it matches the signiture of the delegate that the event uses. For example, considering the delegate created above which has a return type of void and an int paramater, our event handlers should also have a void return type, and an int parameter (please note that access specifier is not important).
public void ShowMessage(int number) { MessageBox.Show("Hello World"); }

We can then attach the event using the += operator like this:
SampleEvent += new SampleEventHandler(ShowMessage);

To activate the event, we call it passing the required arguments the same way we call methods.
SampleEvent(3);

Event Handling in Windows Forms


To demonstrate using events on windows forms, create a new Windows Forms Application and name it EventHandling. Double click the form and Visual Studio will automatically create an event handler and attach it to the Load event of the form. The Load event has a delegate type of EventHandler. Most events of controls have a delegate type of System.EventHandler. The following is the definition of the EventHandler delegate.
public delegate void EventHandler(object sender, EventArgs e)

As you can see with the definition of the delegate, it has no return type and has two parameters, an object and an EventArgs instance. The object sender represents the control that activates the event. We will demonstrate its use later. The second argument is an instance of the EventArgs class. This can be called as the event argument and they contain data about the event that happened. The EventArgs is actually a base class and contains no useful members. Certain events will have event arguments that is derived from EventArgs and contain useful properties that the event handler can use. You will notice that the created event handler by Visual Studio matches the signiture of the EventHandler.
private void Form1_Load(object sender, EventArgs e) {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

If you want to create event handlers manually, then be sure to follow the signiture of the delegate type of the event. Visual Studio propose a naming convention for event handlers, as seen in the generated event handler. When naming event handlers, type the name of the control(specified by its Name property) followed by an underscore and then the name of the event. You can ignore this convention if the event handler will be used by multiple events as we will see later.
Comminicating with the Source Control

You have seen that the EventHandler delegate has two parameters, and the first of them is an object which represents the control that sent the event. Since it is of type object, any control can be a source of the event because every control is derived from the object base class. Since the sender is converted to an object, we need to convert it back to the proper control to access its useful properties. To demonstrate it's use, add a button to the form. Change the Text property of the button to "Hello World!".

Double click the button to generate an event handler for its Click event. Like the Load event, the Click event also has a type of EventHandler. Use the following code for the event handler.
private void button1_Click(object sender, EventArgs e) { Button source = (Button)sender; MessageBox.Show("The message inside the button is " + source.Text); }

Run the program and click the button. A message box will be shown telling the text inside the button that sent the Click event.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The first line of the event handler converts the sender object to a Button using casting so we can access its Text property. We then call the Show method of the MessageBox class to show the value of the Text property of the button that sent the event.
Event Arguments

The second parameter which actually varies depending on the event, is an event argument. The most common is the EventArgs which is the base class of event arguments. It has no properties you can use in your event handler. To demonstrate an event that has a different event argument, we will use the MouseClick event of the button which is a better version of the Click event. Since it is not the default event, we can access it in the events section of the Properties Window. Be sure that the button is selected in the designer. Click the thunderbolt icon to show the events of the button. We need to remove the Click event handler first so it will not conflict with the MouseClick event. Find the Click event and delete the value next to it. Then find and double click the MouseClick event. The MouseClick event has a different delegate type of MouseEventHandler. It has the same signiture as the ordinary EventHandler delegate but it has a different type for its event argument which is MouseEventArgs. The MouseEventArgs is derived from EventArgs. It contains useful properties such as which button(left or right) of the mouse is clicked, the number of clicked done, how much the mouse wheel was rotated, and the point location of the click relative to the source control. Use the code below for the MouseClick event handler.
private void button1_MouseClick(object sender, MouseEventArgs e) { MessageBox.Show("You clicked at point (" + e.X + ", " + e.Y + ")"); }

The code above uses the event argument parameter to access the x and y coordinates of the point where the mouse was clicked. The output below my vary depending on where you click on the button.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

There are many more event argument types and each offers useful properties about the event that took place.
Using the Properties Window to Attach Event Handlers

We already know that aside from double clicking controls, we can use the Properties Window to attach event handlers to events. We click the thunderbolt icon to go to the Events section of the Properties Window.

The top combo box is used to select controls in the Designer. This is useful when you can't select certain controls because they aren't visible or very small. Find the desired event. To attach an event handler to an event you can double click the name of the event to generate an event handler for the specified event. Alternatively, if you already have created event handlers, you can click the dropdown button to view all the valid event handlers that match the signiture of the delegate type of the specified event.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Using Identical Event Handlers for Multiple Events

Please note that you can use a single event handler for multiple events that has the same delegate type. To do this, you need to first create the event handler with the proper signiture. Then go to the Events section of the Properties Window and find the events you want. Instead of double clicking, choose the event handler you created. Now find another event and choose the same event handler.

Separating Design and Functionality


When we create a new windows form, a class that inherits from System.Windows.Forms.Form is generated. This class is seperated in two files thanks to the feature called partial classes. Partial classes allows you to seperate definitions of a class in different files within the same project and namespace. With the introduction of partial classes in .NET 3.5, Visual Studio was able to seperate design from functionality. This allows a programmer to concentrate on the functionality of the application. The name of the files will have the following pattern:
FormName.cs FormName.Designer.cs

where FormName is the name of the form, for example, Form1. A third file with .resx extention, is used for resources of the form and will be discussed in a seperate lesson. When we create the form, add controls, and modify properties, all the code is written in a somewhat hidden file with a .Designer.cs extension. If you can't see it, find the .cs file for the form in the Solution Explorer and click the arrow button beside it.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Double clicking the that file will allow you to see all the codes that were generated by Visual Studio. The code contain methods for disposing and initializing the controls. You can see the controls being declared and properties, such as Location and Text, are set depending on what you specified in the Properties Window. You will also see event handlers being attached to events of controls. If you cant see the code, it is hidden by default and is labeled "Windows Forms Designer generated code". Just click the plus icon to its left to show it. You will see that the code for initializing the controls and their properties and events is located inside a method called InitializeComponent. This method is called in the form's constructor located at the main code file for the form's class. The codes in the Designer file is initially hidden because Visual Studio want's you to use the Designer and the Properties Window instead of writing all these codes manually.

The MessageBox Class


The System.Windows.Forms.MessageBox is a static class that is used to show message boxes for prompting, confirmation and warning users. To show a message box, simply call the Show method of the MessageBox class. The simplest version of the Show method is the one that accepts a string message as an argument.
MessageBox.Show("Hello World!");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can also specify the title of the message box by using another overloaded version of the Show method.
MessageBox.Show("Hello World!", "A Message");

You can also change the buttons that will be shown in the message box if you don't want to use the default OK button. You can do this by using the System.Windows.Forms.MessageBoxButtons enumeration.
MessageBox.Show("Hello World!", "A Message", MessageBoxButtons.OKCancel);

The table below shows the members of the MessageBoxButtons enumeration. Member Buttons Shown AbortRetryIgnore Abort, Retry, Ignore OK OK OKCancel OK, Cancel

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Member RetryCancel YesNo YesNoCancel

Buttons Shown Retry, Cancel Yes, No Yes, No, Cancel

The Show() method returns a value from the System.Windows.Forms.DialogResult enumeration. This is useful to determine what button you pressed in the message box. For example, if you click the "Yes" button in the message box, then the Show() method will return the value DialogResult.Yes.
DialogResult result; result = MessageBox.Show("What is your choice?"); if (result == DialogResult.Yes) { //You pressed the Yes button } if (result == DialogResult.No) { //You pressed the No button }

Please note that the Form class also has a DialogResult property. This is not the System.Windows.Forms.DialogResult. You can also add an icon for your message box to further imply the purpose of the message. You do this by using the members of the MessageBoxIcon enumeration.
MessageBox.Show("Hello World!", "A Message", MessageBoxButtons.OK, MessageBoxIcon.Information);

The table below shows the different icons that you can use for your message box. Icon Member Asterisk Information Usage Used when showing information to the user.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Icon

Member Error Hand Stop Exclamation Warning Question

Usage Used when showing error messages. Used when showing warning messages. Used when asking a question to the user.

You can use the MessageBoxIcon.None to indicate that the message box will have no icon. The MessageBoxDefaultButton enumeration tells which of the button is the default, that is, the one that is pressed when the enter key in the keyboard is pushed. It has only 4 member which are Button1, Button2, Button3, Button4. For example, in a message box that has an OK and a Cancel buttons, using MessageBoxDefaultButton.Button1 will make the OK button as the default. When the message box is shown and you pressed Enter in the keyboard, the OK button is pressed.
MessageBox.Show("Hello World!", "A Message", MessageBoxButtons.OKCancel, MessageBoxDefaultButton.Button1);

Controls
Controls are visual components that compose the graphical user interface. Everything you see in a GUI is a control, including the form itself. Controls are located at the Toolbar grouped inside different categories. Most of the controls inherit from the System.Windows.Forms.Control base class which exposes several properties, methods, and events common to those controls.

Control Properties
The following are some of the useful properties of the Control class. Description Specifies how the control relocates and resizes whenever the form is Anchor resized. If set to true, the control will automatically size itself to fit the AutoSize contents. BackColor The background color of the control. BackgroundImage Allows you to add a background image to the control. BackgroundImageLayout Specifies the way the background image is placed and resized. Gets the distance in pixel between the top of the control's container Bottom and the bottom of the control. Properties

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Properties CausesValidation ContextMenuStrip Controls Dock Enabled ForeColor Height Left Location Locked MaximumSize Margin MinimumSize Name Padding Parent Right Size TabIndex TabStop Tag Text TextAlign Top Visible Width

Description Specifies whether the control will raise validation events. Allows you to add a context menu to the control. A collection of child controls within this control. Docks the control to one of the edges of the window. Tells whether the user can interact with the control. Set to false to disable the control. The foreground color of the control. This is also the font color of the text inside the control. The height of the control in pixels. Gets or sets the distance between the left edge of the control and the left edge of its container. The location of the control relative to its container. Specifies whether the control can be moved or resized in the designer. Specifies the maximum size of the control. Specifies the margin between this control and another control. Specifies the minimum size of the control. The name of the control. This is used to reference the control in code. Specifies the interior spacing of the control. The parent of the control. The distance between the right edge of the control and the left edge of its container. The size of the control. Composed of Width and Height subproperties. Specifies the number of the control in the tab order of its container. Specifies whether the control can be accessed by the tab key. Used to assign special or useful values about the control. The text shown inside the control. Specifies the alignment of text of the control. The distance between the top edge of the control and the top edge of its container. Sets the visibility of the control. The width of the control in pixels.

Figure - Control Properties The most important property in the table is the Name property. This property allows you to reference the control in code. The following discusses more properties common to most of the controls.

Changing the Background Color of the Control

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We use the BackColor property of the control to change the color of the background. Find the BackColor property in the Properties Window and click the drop down button. You will be presented with a window with three tabs. Each tabs presents a different set of color.

The System colors the colors your operating system uses as default colors for controls. The Web tab shows colors that are safe to use for the web. And the Custom tab shows much more colors. Alternatively, you can type the RGB values of the color separated by commas in the text box next to the property.

Adding a Background Image


We can change the background image of a control by using the BackgroundImage property. As an example, let's change the background image of a form. Go to Properties Window while the form is selected and find the BackgroundImage property.

You will be presented with a window which allows you to choose a resource. For now, choose local resource and browse for an image by clicking the Import button.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Once you choosed an image, click OK. The background image will now show up on the form. The alignment and size of an image may not be what you desired. There is another property called the BackgroundImageLayout property. It accepts values from the System.Windows.Forms.ImageLayout enumeration. Value Description None The image will be positioned using its top left corner with no resizing of the image. If the image is smaller than the client area of the control, the image will be repeated until Tile it fills the form. Center The image is centered within the controls client area. Stretch The image will be resized to fit the client area of the control. Zoom The image will be fitted to the client area of the control without loosing its aspect ratio. Most of the time, Stretch will work fine. The form below has a background image with an image layout of Stretch.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Text Property


The Text property defines the text or caption inside the control. The text that the Text property represents varies on different controls. For example, Text property of the form gets or sets the caption located in its caption bar. The Text property of the button represents the Text inside the button. The Text property of a text box represents the text inside the text box. We can use the TextAlign property to align the text in different locations of the control. If you click the TextAlign properties' drop down box in the Properties Window, you will be presented with a small window that allows you to easily point which location you want the text to be aligned.

Changing the Font of the Control


We can change the font type, color, size, and style of the control by using the Font and ForeColor properties. Let's use a button control as an example.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

To change different font properties of the control, find the Font property in the Properties Window. You will notice a drop down button in its left. Open it up and more properties about the font will be exposed.

The useful once are the Name, which defines the type of font to use, the Size which indicates the size of font, Unit which tells the unit to use for the size of the font, and Italic, Strikeout, Underline and Bold to add styles to the control. Alternatively, you can use the button to the right of the font property to open the Font Window.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Here, you can choose the font type, the font style, the size and add certain effects. You can even see a preview of the font. With these, you can customize the font of the controls.

Enabling and Disabling Controls


We can use the Enabled property to tell whether a control can receive focus and user interaction. We set the property to false to disable the control and true to enable it. When we disable the control, its appearance may change. For example, when we disable a button (setting its Enabled

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

property to false), its color and appearance will change. Note that the change is only visible when you run the form and not in the designer.

When a control is disabled, it will not receive focus or events. For example, if a button is disabled, you cannot click it.

Making Controls Invisible


You can temporarily hide a control by setting the Visible property to false. The Visible property is a boolean property which tells whether the control is visible or not. Setting to false makes the control hidden, and setting it to true makes the control visible. Note that you will only see the effect when you run the form and not in the designer. This allows you to still select the control in the designer even if the Visible property is set to false. More about the properties and features of controls will be discussed in the following lessons.

Control Events
The following table shows the some useful events common to most controls. Event Description BackColorChanged Occurs when the background color was changed. BackgroundImageChanged Occurs when the background image was added or changed. Click Occurs when you click the control with the left mouse button. ControlAdded Occurs when a child control is added to this control. ControlRemoved Occurs when a child control was removed from this control. DoubleClick Occurs when you double click the control. DragDrop Occurs when the drag drop operation is completed. EnabledChanged Occurs when the control is enabled or disabled. Enter Occurs when the control is entered. FontChanged Occurs when the font properties are changed.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Event ForeColorChanged GotFocus KeyDown KeyPress KeyUp Leave LostFocus MouseClick MouseDoubleClick MouseDown MouseEnter MouseHover MouseLeave MouseMove MouseUp MouseWheel Move Paint ParentChanged Resize TextChanged Validated Validating VisibleChanged

Description Occurs when the fore color of the control is changed. Occurs when the control got the focus. Occurs when a key in the keyboard is pressed while the control has the focus. Occurs when the key in the keyboard is pressed and released while the control has the focus. Occurs when a pressed key in the keyboard is released while the control has the focus. Occurs when the input focus leaves the control. Occurs when the focus of the control is lost. A more advanced version of the Click event. A more advanced version of the DoubleClick event. Occurs when a button in the mouse is down while inside the control. Occurs when the mouse pointer enters the control. Occurs when the mouse pointer rests on the control Occurs when the mouse pointer leaves the control. Occurs when the mouse pointer moves while inside the bounds of the control. Occurs when a pressed button of the mouse is released while inside the control. Occurs when you move the mouse wheel while the control has the focus. Occurs when the control is moved. Occurs when the control is redrawn. Occurs when the parent control of this control changes. Occurs when the control is resized. Occurs when the Text property of the control is modified. Occurs when the control is finished validating. Occurs when the control is validating. Occurs when the Visible property is changed.

We will discuss most of the events above in later chapters.

Control Methods
The following are the most useful methods of the Control class. Methods BringToFront Description Brings the control to the front of the z-order.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Methods Description Contains Tells whether a child control is contained inside this control. CreateControl Creates a new control and add it to this control. FindForm Retrieves the form that the control is on. Focus Sets the focus to this control. GetContainerControl Gets the control that serves as the container of this control. Hide Hides the control. Forces the control to invalidate its client area and immediately redraw itself Refresh and any child controls. Select Activates the control SendToBack Brint the control to the back of the z-order. Show Shows a hidden control. Update Causes the control to redraw the invalidated regions within its client area. The Control class also offers some methods that allow you to manually trigger events of the control. Such methods starts with On followed by the name of the event. For example, the OnClick event triggers the Click event when called. Note that some events cannot be triggered by user interaction such as the Paint event. If you want to trigger such events, use the methods offered by the Control class. You will learn more about these methods when we delve deeper into the world of C#. Note that these properties, events, and methods are inherited by most of the controls thanks to inheritance. Therefore, I may not include them again when I present the properties, events, and methods of individual controls unless they are very significant to the control.

Naming Your Controls


Always make a habit of naming controls. We name our control using its Name property. Naming controls follows the guideline for naming variables such as spaces,special characters, and the use of keywords are prohibited. There has been many naming conventions that emerged when it comes to naming controls. You can name the control depending on its use. For example, a text box use to retrieve the first name of the user can simply be named firstName just like a normal variable. But when naming controls, it is better to prefix the actual names with the name of the control. For example, instead of simply firstName, we can use textBoxFirstName. With that convention, we will know, using IntelliSense, that we are working with a text box or any control. Another technique used by others is abbreviating the control names. For example, instead of using textBoxFirstName, you can use txtFirstName. The txt is short for text box. There has been a list of abbreviations for every control and you can even use your own abbreviation as long as it is clear to you and to others who will look at your code.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Another naming convention is the reverse of the first one where you place the descriptive name first followed by the type of control and also uses camel casing. For example, a text box for retrieving the first name of the person can be named firstNameTextBox or a button used for calculating can be named calculateButton. The following lessons use the first naming convention where you simply use the name of the control in camelCasing style followed by a descriptive name. You don't have to memorize a set of abbreviations or invent one. When you drag a control from the ToolBox, you simply need to remove the number suffix and add a descriptive name. When you are typing and you want to easily find what control you want to work with, simply type what kind of control it is, for example, a text box, and all the text box controls will show up in the IntelliSense. The only downside is some names might become too long. It is still up to you as to what naming convention you are more comfortable to use. The following gives you some example name depending on the control and its use. Scenario A Button used to confirm a message. A TextBox used to accept email address from user. A Form used for obtaining personal information. A ComboBox to show a list of products. A RadioButton which tells if a person is male. A MenuItem for saving a file. A CheckBox to subscribe to newletter. Name buttonConfirm, confirmButton, btnConfirm textBoxAddress, addressTextBox, txtAddress formPersonalInformation, personalInformationForm, frmPersonalInformation comboBoxProducts, productsComboBox, cmbProducts radioButtonMale, maleRadioButton, radMale menuItemSave, saveMenuItem, mnuSave checkBoxSubscribe, subscribeCheckBox, chkSubscribe

It is not necessary to name every control in the form. Controls that will never be accessed in code can be left by their default name. Examples of this are labels that are merely used to label other controls. Have a habit of naming the control after you place them onto the form.

The Windows Form


Windows Forms (or simply forms) are the windows you see in a Windows Application. You can create multiple forms in a single application. Each form inherits the properties and methods of the System.Windows.Forms.Form class. The namespace System.Windows.Forms contains components you will need for creating forms and controls. The following are the parts of a typical windows form.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

At the top, you will find the Caption Bar. The Caption Bar is composed of the icon, the caption, and the control box. The control box contains buttons such as minimizing, maximizing, closing, or a help button. The Client Area is where we add the controls. The border or frame which includes the caption bar, encloses the client area and allows you to resize the form. The following are some of the useful properties of the Form base class. Property AcceptButton CancelButton Description The button on the form that is pressed when you hit the Enter key. The button on the form that is pressed when you hit the Esc key. Gets or sets the client area of the form. The client area is the portion of the ClientSize form inside the frame borders. Specifies whether to show the control box at the top right portion of the form. ControlBox The control box contains the buttons minimize, maximize, and close. Controls A collection of Control objects contained inside the form. DesktopBounds The size and location of the form in the Window's desktop.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Description The font that the form will use. Controls inside the form will inherit this Font property. FormBorderStyle The border style of the form. Shows a help button right before the close button of the form. (minimize and HelpButton maximize buttons should be disabled) Icon The icon that will be used by the form. Location The coordinates of the form in the screen. MainMenuStrip Specifies the main menu to be used by the form. MaximizeBox Tells whether the maximize box located at the top right is displayed. MinimizeBox Tells whether the minimize box located at the top right is displayed. Modal Tells whether the form is modal. Name The name of the form that is used to reference it in code. OwnedForms A collection of forms that this form owns. Owner The form that owns this form. ShowIcon Tells whether the icon is displayed at the left side of the caption bar. Size The size of the form. StartPosition The starting position of the form when it is initially shown. Text The text shown in the caption bar of the form. Figure 1 Figure 2 shows some useful methods of the Form class. Method Description Activate Gives the focus to this form and activates it. AddOwnedForm Adds a new form that this form owns. CenterToScreen Centers the position of the form in the screen. Close Closes the form. Hide Hides this form. OnLoad Raises the Load event. Show Shows the form. Figure 2 Figure 3 shows the available events for the form. Event Activated Click Description Occurs when the form is activated. Occurs when the form is clicked.

Property

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Event Description Deactivated Occurs when the form is no longer in focus. FormClosed Occurs after the form is closed. FormClosing Occurs when the form is closing. Allows you to halt the closing of the form. HelpButtonClicked Occurs when the help button is clicked. KeyPress Occurs when a key on the keyboard is pressed. Load Occurs when the form is finished loading just before it is displayed. MenuComplete Occurs when the menu of the form loses focus. MenuStart Occurs when the menu of the form recieves focus. ResizeBegin Occurs when the form enters resizing mode. ResizeEnd Occurs when the form exits resizing mode. Shown Occurs after the form is shown for the first time. Figure 3 The Form class is a child of the System.Windows.Forms.Control base class so methods and properties from the that class are also inherited by the Form class.

Modifying the Control Box


We use the ControlBox property to hide or show the ControlBox. This is useful when you are planning to disable minimizing or maximizing of control or you want to only close the form through code. The image below shows you how the form will look when you set ControlBox property to false.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

If you want to disable only the minimize or the maximize button, then you can use the MinimizeBox and MaximizeBox and set them to false.

The form above has its minimize and maximize box hidden. Unfortunately, you cannot hide only the close button.

Changing Form's Border Style


We can change the border style of the form. For example, let's say you don't want the user to be able to resize the form The default border of the form allow a user to do that. We can set the FormBorderStyle property to different values of the System.Windows.Forms.FormBorderStyle Enumeration. Value None FixedSingle Fixed3D Description

The form has no border. The form has a non-resizable single line border. The form has a non-resizable 3d border. The form has a thick, non-resizable, dialog style border that has no FixedDialog minimize or maximize boxes. Sizable The default. The form has a resizable border. The form has a non-resizable border that has only a close button. This style FixedToolWindow is used for tool windows. SizableToolWindow Same as FixedToolWindow but resizable. The following are screenshots of forms using different FormBorderStyle.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

None

FixedSingle

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Fixed3D

FixedDialog

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Sizable

FixedToolWindow

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

SizableToolWindow

Form Icons
We use the Icon property to change the icon displayed at the upper left side of the form. Click the browse button next the Icon property in the Properties Window and find the .ico file which is the file extention for an icon image. The ShowIcon property allows you to hide or show the icon in the caption bar.

Accept and Cancel Buttons


You can add a button control to the form and set them as either an Accept or a Cancel button. You do that using the AcceptButton and CancelButton properties. If a button is an accept button, whenever the user hits Enter while the form is active, that button's Click event will be executed. The Cancel button is activated whenever the Escape key is pressed. Just go to the Properties Window, find the desired property and click the drop down button. You will be presented with the names of all the button control in the form. Choose the desired button. For example, suppose you are creating a login form. You can set the button used for logging in as the Accept button. This way, the user can simply press Enter when he is finished typing the password. There are many more to discover on windows forms and they will be discussed in later lessons.

The Button Control


The Button control (System.Windows.Forms.Button) is commonly used to execute commands when it is clicked. When a button is clicked, you specify codes that will be used. Buttons are typically used to confirm or cancel an action, to perform different actions, and to open some

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

more dialogs. The Button control has several properties that you can use. The table below enumerates them. Description Specifies whether to append dots (...) when the text in the button is too long and AutoEllipsis can't fit the button. AutoSize Specifies whether the button will automatically resize to fit its content. Determines the style of the button. Popup makes the button flat, and when you hover on the button, the button will pop out. Flat makes the button flat and when FlatStyle you move point your mouse inside the button, the background color of the button changes. Enabled If set to false, the button cannot be clicked or receive focus. Image An optional image that you can place inside the control. ImageAlign The alignment of the image in the button. Text The caption inside the button. Visible Tells whether the button is visible or not. Figure 1 - Button Properties A button is still useless by just editing its properties. It needs to react to events to do some work. The following are the most common events available for the Button control. Event Click Enter Leave LocationChanged MouseDown MouseEnter MouseHover MouseUp MouseLeave Description Occurs when you click the button. Occurs when the control becomes the active control of the form. Occurs when the control becomes inactive anymore. Occurs when the location of the button is changed. Occurs when the mouse pointer is in the button and the mouse button is pressed down. Occurs when the mouse enters the button. Occurs when the mouse stays stationary in the button for an amount of time. Occurs when you pressed the button and you let go of the mouse button. Occurs when the mouse pointer leaves the button. Property

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You have already seen the Click event which is the default event for a button. Lets create another application that demonstrates the use of other events. Create a new form and drag a button to the form from the toolbox. Its not important what text you put for the button. In the properties window, find the Name property and change its value to buttonSample. We will now refer to that button in the code using that name. Our program will demonstrate the MouseEnter and MouseLeave events. To access these events, the easiest way is to go to the properties window and click the button with the lightning symbol.

First, find MouseEnter and double click it. Visual Studio will generate an event handler for you for that specified event. Type the highlighted code inside the method.
private void buttonSample_MouseEnter(object sender, EventArgs e) { buttonSample.Text = "Mouse has entered!"; }

After typing the code, return back to the Properties Window and now choose the MouseLeave event and double click it to generate an event handler. Again, type the highlighted code inside the event handler method.
private void buttonSample_MouseLeave(object sender, EventArgs e) { btnSample.Text = "Mouse has left!"; }

Now run the program. Roll over your mouse to the button and notice that the text has changed. Take away the mouse pointer from the button and the text of the button will change again.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Label Control


The Label control (System.Windows.Forms.Label) is used to add text to a form that can be used to show messages, or add labels to identify what other controls' functionality is. Drag a label control from the toolbox to the form. By default, it will have an initial text. The following properties are the most common ones that you will modify. Description If true, the size of the borders of the label control AutoSize in the designer will be resized automatically depending on the text inside it. BorderStyle Specifies the type of border around the label. Used to change the font properties of the Font text inside the label control. Text The text of the label. TextAlign The alignment of the text inside the Label control The Text property is the most important one because the main purpose of the Label control is to show text in the form.
Label1.Text = "Hello World!";

Property

You can modify the Font property to change the font family, font size and many font properties.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

There are events that are also available for the Label control, but most of the time, you won't be needing them.

The TextBox Control


The TextBox control (System.Windows.Forms.TextBox) is the most basic means of input in a windows forms. You give the input data by typing it inside the textbox. The text you type can be accessed by using the Text property of the control. The following table shows some useful properties that you can use for the TextBox control. Description Used with Multiline. Tells if whether the return key is included in the input. The AcceptsReturn return will be converted into a \n escape sequence. Indicates whether to accept tab as an input. By default, hitting tab will bring the AcceptsTab focus to the control with the next TabIndex in the form. Set to false to make the text box read-only therefore making the text box act like Enabled a label. Font The font properties that will be used by the textbox. Lines The lines of text in a multiline text box. Multiline Set to true to allow multiple lines in a text box. Text The text inside the text box. PasswordChar Accepts a character that will be used to mask each character typed by the user. ReadOnly Tells whether the text in the form can be edited. Visible Tells whether the text box is visible inside the form. WordWrap Used with Multiline. Set to true to enable automatic wrapping of words. Figure 1 The following example shows the use of textboxes. Create a new Windows Application project. The program will ask two numbers and then when a button is pressed, the sum is shown using a label. Drag two textboxes to the form and name them textBoxFirstNumber and textBoxSecondNumber. Also drag one label for each textbox indicating their purpose. Drag another label that will be used to show the sum and name it labelSum. Place a Button control and name it buttonAdd. Adjust the position and sizes of the controls to match the layout below. Property

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Double click the button to add an event handler to it's click event. Type the following codes.
private { int int int } void buttonAdd_Click(object sender, EventArgs e) num1 = Int32.Parse(textBoxFirstNumber.Text); num2 = Int32.Parse(textBoxSecondNumber.Text); sum = num1 + num2;

labelSum.Text = "Sum = " + sum;

The code converts the contents of textBoxFirstNumber and textBoxSecondNumber into integers using the Parse method of the Int32 class and stored them in their respective variables. We require conversion because the Text property is of type string. Their contents is accessed using the Text property. The sum is then determined. The sum is displayed afterwards by assigning it to the Text property of labelSum. The most useful event of the TextBox is the TextChanged event which occurs when the text inside the textbox is modified. The following program shows an example of using this event. Create another windows forms application and add a textbox and a label in the form. Name them you can leave their default names right now.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Delete the text of label1 by removing the content of its Text property. Note that it would be hard to select this label now if the AutoSize is set to false so you can select this label using the top combo box of the Properties Window. The default event of the TextBox control is the TextChanged event so double clicking it will create an event handler for the said event. Add the following code to the event handler.
private void textBox1_TextChanged(object sender, EventArgs e) { label1.Text = textBox1.Text; }

Now run the program and type anything in the text box. Notice that the text of the label copies the text you type in the text box.

When the text inside the textbox is modified, the event handler executes and copies the text inside textbox1 to label1. By default, a textbox can only handle single line of text. To make it a multiline textbox, simply set the Multiline property to true. Once you do that, you will notice that you can change the height of the textbox in the designer.

You can set the WordWrap property to true to automatically bring the cursor below when it reaches the right edge of the text box. If it is set to false, the the text will continue to the to the right clipping the ones at the left side. You can set the ScrollBar property to Horizontal, Vertical or Both to add scroll bars to a multiline text box. When using a multiline textbox, you can use the Lines property to retrieve the individual lines of text.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

If your textbox is expected to accept passwords, then you must set the PasswordChar to something like * to mask each character type in the textbox by the character indicated in the PasswordChar property.

The RichTextBox Control


The RichTextBox control (System.Windows.Forms.RichTextBox) is similar to a TextBox control but it allows you to format different parts of the text inside it. The TextBox control is typcially used to accept text input from the user while the RichTextBox control is used to show formatted text and save it in Rich Text Format (RTF).

Figure 1 Figure 1 shows a difference between a TextBox(top) and a RichTextBox(bottom) controls. Although you can do formatting in a normal text box, it is always applied to all of the text inside it. The RichTextBox control allows you to format parts of the whole text of the control. You can also use a rich text box control to accept input from the user as both TextBox and RichTextBox are derived from TextBoxBase class therefore, they share the most common properties such as the Text property. The following are some common properties available when using the RichTextBox control.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Property AcceptsTab

Description Specifies whether to accept focus as a result of pressing the tab key. Specifies the indentation used in the RichTextBox control when the bullet BulletIndent style is applied to the text. Specifies a whether there are actions that have occurred within the CanRedo RichTextBox that can be reapplied. Specifies whether the user can undo the operations done in a CanUndo RichTextBox control. Specifies whether to automatically detect and add the target link to urls DetectUrls inside the RichTextBox control. Lines A collection of individual lines in a RichTextBox control. Tells whether the contents of the RichTextBox control has been modified Modified since the last time it was set. Tells whether the RichTextBox control can have multiple lines of text Multiline (true by default). ReadOnly Tells whether the RichTextBox control is read-only. Specifies the name of the action than can be redone once an undo RedoActionName operation is made and the Redo method is called. Contains the text of of the RichTextBox control including the rich text Rtf format (rtf) codes. Scrollbars Specifies the type of scrollbars to display. Gets or sets the currently selected rich text format (RTF) formatted text in SelectedRtf the control. SelectedText Gets or sets the selected text within the RichTextBox. SelectionAlignment Specifies the alignment to apply to the current selection or insertion point. SelectionBackColor Specifies the background color of the selected text. Specifies whether the bullet style is applied to the current selection or SelectionBullet insertion point. Specifies whether the selected text in the control appears on the baseline, SelectionCharOffset as a superscript, or as a subscript below the baseline. SelectionColor Specifies the color of the selected text. SelectionFont Specifies the font that the selected text will use. SelectionLength Specifies the number of characters of the selected text. Tells whether the selected text or all the text after the insertion point is SelectionProtected protected. The distance (in pixels) between the right edge of the RichTextBox SelectionRightIndent control and the right edge of the text that is selected or added at the current insertion point. SelectionStart Specifies the starting position of the selection or the insertion point. ShortcutsEnabled Specifies whether predefined or defined shortcut keys are enabled. ShowSelectionMargin Specifies whether a selection margin is displayed in the RichTextBox.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Property Text UndoActionName WordWrap

Description The plain text inside the RichTextBox control. Specifies the action that can be undone in the control when the Undo method is called. Specifies whether to wrap the text inside the RichTextBox control.

Figure 2 - RichTextBox Properties The following are some events that you can handle for the RichTextBox control. Event Description LinkClicked Occurs when a link was clicked. Protected Occurs when the user attempts to modified a protected text. TextChanged Occurs when the text inside the RichTextBox is modified. SelectionChanged Occurs when the selected text is changed. Figure 3 - RichTextBox Events

Changing Format of the Selected Text


A lot of the properties of the RichTextBox control is used for the currently selected text. For example, the SelectedText specifies the currently selected text by the user. You can also use the Select method to select texts.
richTextBox1.Select(10, 11);

The first parameter specifies the starting index of the selection and the second parameter specifies the length of the selection starting from the starting index. Once we have selected a text, we can format the seleted text using more properties that focuses on the current selection. For example, to change the color of the currently selected text, you can use the SelectionColor property or the SelectionBackColor to change its background color.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

richTextBox1.SelectionColor = Color.Red; richTextBox1.SelectionBackColor = Color.Yellow;

You can then deselect the selected text by clicking anywhere in the form or by using the DeselectAll method.
richTextBox1.DeselectAll();

Please note that when no text is selected, the effect of the selection properties starts from the insertion point. The insertion point is simply the location of the blinking I-beam which specifies the insertion of text will start there. Every new character that you type will now receive the new format you have specified.

Adding A Selection Margin


The selection margin is the little margin on the left side of the RichTextBox control.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The selection margin (indicated by the arrow) is used to easliy select a single line of text. For example, the screen shot above shows the third line selected by clicking the selection margin space beside it. We can set the SelectionMargin property of the RichTextBox control to show the selection margin.

Adding Scrollbars
To add scrollbars, we use the ScrollBars property which accepts a value from the RichTextBoxScrollBars enumeration. This enumeration contains values Horizontal, which adds a horizontal scroll bar when the length of the line is too long and the WordWrap property is set to false; Vertical, which adds a vertical scroll bar when the number of lines of text doesnt fit the height of the RichTextBox; and Both, which automatically adds horizontal and vertical scroll bar when neccessary. When the SelectionMargin property is set to false, you need to use a different set of enumeration values, ForcedHorizontal, ForcedVertical, and ForcedBoth. To disable scroll bars completely, set it RichTextBoxScrollBars.None.

Changing Alignment of Selected Text


We can use the SelectionAlignment property to change the alignment of the selected text, more properly, the paragraph where the selected text or the insertion point is located. The property accepts a value from the HorizontalAlignment enumeration which includes Left, Right, and Center. It is important to know how paragraphs are made inside the control. Initialily, typing your the first character to the rich text box will create a paragraph. To create the next paragraph, you simply press the Enter or Return key.

Undoing and Redoing


You can specify whether the user can undo or redo operation using the CanUndo and CanRedo properties. Undoing simply reverts the change you have done to the contents of the RichTextBox control while redoing negates the effect of undo and brings back the change you have made to the content. The properties UndoActionName and RedoActionName are used to restrict the undo and redo operation to specific actions only. These properties accepts actions in form of strings. The possible actions are: Action Description Typing Typing operation Delete Delete operation DragDrop Drag and Drop operation Cut Cut operation Paste Paste operation For example, you can assign the string "Delete" to the UndoActionName property to only allow the user to undo a delete operation.
richTextBox1.UndoActionName = "Delete";

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

For an unknown reason, Microsoft did not make an enumeration for these properties so you have to strings as actions.

Detecting URL's
The RichTextBox control has the capability to automatically detect URL's that are typed or pasted to the control. The DetectUrls property allows the control to automatically detect url's and create a link to their target web page. Setting that property to true activates the feature and setting it to false deactivates it. Shown in the image below, you can see that URL's to website resemble a link and putting your mouse cursor over them will change the cursor to a hand.

Clicking the link opens the website using your default web browser.

Adding Bullets
You can create bullets inside a RichTextBox control. You use the SelectionBullet property and set it to true to indicate that the selected text should became buletted text. The BulletIndent property specifies the distance between the bullet and the starting position of the text. The program below has a button that adds a bullet to the beginning of each selected line, or paragraph or to where the insertion piont is located.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Enabling and Disabling Shortcut Keys


The ShortcutsEnabled property enables or disables shortcut keys such as those for cutting and pasting text to the text box. When this is set to true, the following shortcut keys will be accepted by the RichTextBox control. Shortcut Function Ctrl + Z Undo Ctrl + E Center Alignment of Text Ctrl + C Copy Ctrl + Y Redo Ctrl + X Cut Ctrl + Backspace Deletes an entire word to the left of cursor. Ctrl + V Paste Ctrl + Delete Deletes an entire word to the right of the cursor. Ctrl + A Select All Text Ctrl + L Left Justify Ctrl + R Right Justify Setting ShortcutEanbled to false disables these shortcuts.

Protecting Texts
You have the ability to protect certiain parts of text using the SelectionProtected property which when set to true, protects the currently selected text. A protected text cannot be modifies. When the user tries to modify a protected text, then teh Protected event will trigger. You can handle this event to, for example, show a message telling the user that the text he is trying to modify is protected.

Rich Text Format (RTF)


The Rich Text Format is a document file format that remembers the formatting of your text or document. The normal TextBox control cannot save text formats because it simply contains plain text. The RichTextBox control has the Text and Rtf properties where the Text property contains the plain text of the control while the Rtf property contains the text and the RTF codes used to format the text. The screenshots below show you the formatted text, and the RTF codes behind that formatted text.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The RTF code allows other programs (such as Word) to read the formatting and present to you the formatted text. The SelectedRtf gets the selected text together with the RTF codes associated to it. This allows you to include the format when cutting and pasting formatted texts.

The RadioButton Control


The RadioButton control (System.Windows.Forms.RadioButton) is a button that can be either turned on or off. The radio button is a circular button with a label. You simple click a radio button to change it from off to on or vice versa. When the radio button is turned on, a dot can be seen and when it is turned off, the circle appears empty. Radio buttons are usually used when a user must select one choice from a set of choices. For example, if you want to determine the gender of the user, then you can use two radio buttons labeled Male and Female. Since you used a radio button, you can only choose one of the two. The following are some properties of the radio button control. Property Description Appearance The radio button can be displayed as a normal button,

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Description or a circular button with a label beside it. Determines the alignment of the button. The default is CheckAlign MiddleLeft, which will show the button to the left of the label. When set to true, the radio button will be in Checked its "ON" state and a dot will be seen inside the button. Sets the text inside the label of Text the radio button. The radio button has a CheckChanged and Click event. The CheckChanged event is sent when the state of the button is changed. For example if the radio button turns from off to on, then the CheckChanged event will execute. The Click event is sent when the radio button is clicked. By default, clicking a radio button will change its state, which will therefore trigger the CheckChanged event. The difference of the Click event is that you can actually change this default behavior of the radio button. There is a property for the radio button control called AutoCheck which if set to false, clicking the radio button will not change its state, but will sent a Click event and through code, you can manually set the radio button's Checked property to true. The default event for the radio button is the CheckChanged event, therefore, double clicking a radio button while in the VS/VCE forms designer will generate an event handler for the said event. The following example demonstrates the use of the radio button. Drag two radio buttons to the form. Name them radioButtonYes and radioButtonNo. Drag a button control, name it buttonShow, and set its text to Show Message.

Property

Double click the buttonShow to generate a handler for its Click event. Write the highligted code inside the event handler.
private void buttonShow_Click(object sender, EventArgs e) { if (radioButtonYes.Checked) MessageBox.Show("You choosed yes!"); else MessageBox.Show("You choosed no!"); }

When you click the button, the program will determine which radio button is checked. You can do this by using the Checked property. We used an if statement to determine whether radio

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

button is checked (on). If its not, then the other radio button is checked since there are only two radio buttons in the form and at least one of them is always checked.

The CheckBox Control


The CheckBox control (System.Windows.Forms.CheckBox) is also a type of button and apears as an empty box with a label beside it. By default, when the empty box is clicked, a check will show up inside the box telling that the checkbox control is in its "checked" state. Unlike a radio button, you can check multiple or even all of the checkboxes. The CheckBox control contains similar properties as the radio button control. The following are some properties that are exclusive to the CheckBox control. Property Description Checked Determines if the check box is checked. CheckState Tells whether the checkbox is Checked, Unchecked. ThreeState If true, the checkbox can accept an Intermediate state. Unlike the radio button, the CheckBox control can have three states by setting the ThreeState property to true. Those three states are Checked, Unchecked or Intermediate. Intermediate indicates that value of the checkbox is invalid or cannot be determined. The screen shot below shows the appearance of each of the three states.

You can change the state of the control in code by using the CheckState property. The CheckState accepts values from the CheckState enumeration.
checkBox1.CheckState = CheckState.Checked; checkBox2.CheckState = CheckState.Unchecked; checkBox3.CheckState = CheckState.Intermediate;

If the checkbox is set to only accept two states, on or off (by setting ThreeState property to false), then you can simply use the Checked property of the checkbox which accepts either true to make the checkbox checked, or false to make it unchecked. The default event of the CheckBox control is also the CheckChanged event. But there is a minor difference between the CheckChanged event of the RadioButton and the CheckChanged event of the CheckBox control. If for example ThreeState property of the checkbox is set to true, when a checkbox changes its state from checked to intermediate, the CheckChanged event will not be

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

sent. If you want to trigger an event when the checkbox changes from unchecked to intermediate, then you can use the CheckStateChanged event instead. The following example demonstrates the use of the CheckBox control. Create a form and drag a label, three checkboxes and a button. Change the texts of the controls and align them properly as seen below.

Name the checkboxes checkBoxSoap, checkBoxShampoo, and checkBoxToothpaste respectively. Name the button buttonCheckOut. No need to name the label since we are not using it in our code. Double click the button and copy the following type the following code inside the event handler.
string items = String.Empty; if (checkBoxSoap.Checked) items += "\n Soap"; if (checkBoxShampoo.Checked) items += "\n Shampoo"; if (checkBoxToothpaste.Checked) items += "\n Toothpaste."; MessageBox.Show("You have bought: " + items);

Launch the program and select some items by checking them. As you check the item, they will be added to the list that will be shown when you click the Check Out button.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

In the code, we declared a string variable and initialize it into an empty string by using the Empty property (which contains an empty string) of the String class. We then check if each of the checkboxes are checked, if so add the product represented by a string using the += operator to concantenate the string to the content of output. We then use a message box to show the final output.

The Panel and GroupBox Controls


The Panel control is used to group controls on a form. One good use of a panel is when you want to group radio buttons. Only one radio button from a set of radio buttons is allowed to be on. By grouping radio buttons, you can have more than one radio button that is turned on. To try this out, drag two panels to the form. It can be found in the Containers tab of the toolbox. Adjust their sizes using the resizing handles. To add a control to a panel, simply put the controls inside it. Place two radio buttons inside each of the panels. Below is how your form should look like in the designer view.

Once you place a control inside a panel, the control becomes the child of the panel. The panel therefore becomes the parent of the control. To better illustrate that relationship, try moving the panel. All controls inside the panel moves with it. The relationship also allows the parent and the child to share the values of common properties. For example, setting the Enable property of the panel to false not only disables the form, but every control inside of it as well. You could notice that the panel in the designer view is represented by dashed box (by default). This will not be visible when you run the actual program. But you will have an option to add visible borders for the panel. Below are some properties of the Panel control. Property BorderStyle Controls Enabled Description Sets the border style of the panel. A collection of child controls inside the panel. Allows you to disable or enable a control.

Now run the program. You can now turn two radio buttons from different groups.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The GroupBox control is a similar control but allows you to add captions for each group. You do that by using the Text property of the GroupBox control. The GroupBox control also has a default border.

The ComboBox Control


The ComboBox control is another way of allowing a user to choose from a set of options. The ComboBox control looks like a text box with a button in its right side. When the button is clicked, the ComboBox show a drop-down box containing the list of options/items available. The user can then choose from these options by clicking one of them. The selected option will then be the text inside the ComboBox. The following are some of the properties of the ComboBox control. Description A list of data that the control will DataSource use to get its items. The height in pixels of the drop-down DropDownHeight box in a combo box. The format specifier characters that FormatString indicate how a value is to be displayed. Items The items in the combo box. Property

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Property Sorted Text

SelectedIndex

SelectedItem

Description Specifies whether the items on the combo box should be sorted. The default text when there is no item selected. Gets or sets the selected index. Every item has an index starting from 0 to (number of items - 1). A value of -1 indicates that no item is selected. Gets or sets the item of the currently selected item.

The following table are some of the events available for the ComboBox control. The default event isthe SelectedIndexChanged event. Description Click Occurs when the component is clicked. Occurs when the drop-down portion of the DropDown combo box is shown Indicates that the drop-down portion of DropDownClosed the combo box has been closed. Occurs when the value of the SelectedIndex SelectedIndexChanged property is changed. The following example shows the basic functionality of a ComboBox control. Place a combo box on a blank form. Name it comboBoxNames by changing the Name property. Go to the Properties Window and find the Items property. You should see a button with three dots in it. Click it to open the String Collection Editor. Alternatively, you can click Edit Items located below the list of properties in the Properties Window. Event

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

In the String Collection Editor, type the names show in the figure below then press OK.

Change the Text property of the combo box to "Choose a name" so it will have a default text when no name is chosen. Double click the combo box so VS/VCE will generate an event handler for the SelectedIndexChanged event. Type the following code inside the event handler.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

string selectedName = comboBoxNames.SelectedItem.ToString(); MessageBox.Show("Hello " + selectedName);

Run the program and choose a name. The program will greet the name you have selected immediately after you selected that name.

When you selected an option, the SelectedIndexChanged event is triggered. The SelectedItem property contains the data of the currently selected item. We stored the value of it into a string variable by converting the value of the SelectedItem property into a string using the ToString() method since that property returns an object. (Alternativaly you can use the Text property but we used the SelectedItem for demonstration). We then display a text containing the output message. The SelectedIndex property determines the index of the currently selected item. The first item has an index of 0 and each succeeding items has an index of 1 greater than the previous. The last item has an idex of (number of items - 1). So if you have 10 items, the last index is 9. If no item is selected, then the selected index is -1. If you want to add the items programmatically or during runtime, you can use the Items property of the ComboBox control. The Items property of type ObjectCollection has an Add method that you can use to add new items to the ComboBox.
string[] names = { "Johnny", "Kenneth", "Mark", "Ralph", "Sussie" }; //Add each names from the array to the combo box foreach(string name in names) { comboBoxNames.Items.Add(name); }

We created a list of names and stored it in a string array. We then use a foreach loop to add each names to the ComboBox. Alternatively, you can use the DataSource property.
comboBoxNames.DataSource = names;

The DataSource Property can accept a collection or array that the combo box will use to fill its list.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The ListBox Control


The ListBox control is used to show a list of strings which you can select. By default, you can only select one item. The ListBox control is best used if you are trying to display a large number of items. The following are the commonly used properties of the ListBox control. Property ColumnWidth DataSource Items MultiColumn SelectedIndex SelectedIndices SelectedItem SelectedItems Description Specifies the width of each column if MultiColumn is set to true. Specifies the source of data that the ListBox will display. Contains the items that the ListBox will display. Tells whether the ListBox supports multiple column. The zero-based index of the selected item. Contains the zero-based index of each selected item. Returns the selected item as an object. An object collection of the selected items. Specifies the number of items you can select at the same time.

SelectionMode

SelectionMode.None - you cannot select anything SelectionMode.One - you can only select one item SelectionMode.MultiSimple - you can select multiple items by simply clicking them SelectiomMode.MultiExtended - you can select multiple items by holding ctrl, shift and arrow keys

ScrollAlwaysVisible Sorted Text

Tells whether the scroll bars are always visible regardless of the number of items in the ListBox. Tells whether to sort the items in the ListBox alphabetically or in ascending order. If you set a string value, the first item that matches will be selected. This property returns the text of the first selected item.

Figure 1 - ListBox Properties The following are the useful methods you can use. Methods ClearSelected() FindString() Description Unselects all selected items of the ListBox. Finds the first item in the ListBox that starts with the specified string. The search starts at a specified index.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Methods Description FindStringExact() Finds the first item in the ListBox that matches the specified string. GetSelected() Tells whether the item in the specified index is selected. SetSelected() Selects or deselects the item at the specified index. Figure 2 - ListBox Methods To manipulate the items in the ListBox, we use the Items property which is of type ObjectCollection. You can use the typical collection methods such as Add, Remove, and Clear. Create a new Windows Form and add a ListBox and a TextBox. Set the TextBox's Multiline property to true. Follow the layout shown below.

Name the ListBox listBoxInventory and the TextBox textBoxDescription. Double click the form to add a Load event handler to it. Use the Form1_Load handler(line 16-29) of Example 1.
1 using System; 2 using System.Collections.Generic; 3 using System.Windows.Forms; 4 5 namespace ListBoxDemo 6 { 7 public partial class Form1 : Form 8 { 9 private Dictionary<string, string> products; 10 11 public Form1() 12 { 13 InitializeComponent(); 14 } 15 16 private void Form1_Load(object sender, EventArgs e) 17 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

18 19 20shiny."); 21 22body."); 23 24 25 26 27 28 29 30 31 } } }

products = new Dictionary<string, string>(); products.Add("Shampoo", "Makes your hair beautiful and products.Add("Soap", "Removes the dirt and germs on your products.Add("Deodorant", "Prevents body odor."); products.Add("Toothpaste", "Used to clean your teeth."); products.Add("Mouthwash", "Fights bad breath."); foreach (KeyValuePair<string, string> product in products) { listBoxInventory.Items.Add(product.Key); }

Example 1 We created a Dictionary collection that has a string key, and a string value. Inside the Load event handler of the form, we added some products together with their description to this collection. Using a foreach loop, we add each product's name to the ListBox's Items property. Not that each item in the generic Dictionary collection is of type KeyValuePari<TKey, TValue>. When you run the program, you will see that the five products can now be seen inside the ListBox. Note that if the height of the ListBox is insufficient to display all the items, then a vertical scrollbar will be visible to the right of the ListBox.

Now let's add an event handler to the ListBox's SelectedIndexChanged event. The SelectedIndexChanged event occurs when the index of the selected item is changed. This is the default event of the ListBox so double clicking the ListBox will automatically add an event handler for the said event. Add this single line of code.
private void listBoxInventory_SelectedIndexChanged(object sender, EventArgs e)

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

{ textBoxDescription.Text = products[listBoxInventory.Text]; }

Now run the program and select a product. It's corresponding description should display in the text box.

Please note that you can also use the String Collections Editor as shown in the last lesson to add items to the ListBox.

The CheckedListBox Control


The CheckedListBox control is similar to the ListBox control except that each item is represented by a CheckBox control. You can select each item like an ordinary ListBox, but in addition, you can also check the box beside each item.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 - Appearance of CheckedListBox Control The properties and methods of the ListBox control can also be found in the CheckedListBox control. But the CheckedBoxControl has some exclusive properties listed below. Properties CheckedIndices CheckedItems CheckOnClick Description A collection of checked indices of the CheckedListBox control. A collection of checked items. Specifies whether to check the box of an item if the item is selected. Specifies whether the checkbox should be flat(two-dimensional appearance) ThreeDCheckBoxes or normal(three-dimensional appearance). Figure 2 - CheckedListBox Properties The following are methods exclusive to the CheckedListBox control. Methods Description GetItemChecked() Tells whether the item at the specified index is checked. GetItemCheckState() Returns the CheckState value of the item at the specified index. SetItemChecked() Checks or unchecks the item at the specified index. SetItemCheckState() Sets the CheckState of the item at the specified index. Figure 3 - CheckedListBox Methods Let's create an example application that uses the CheckedListBox control. Create a new form and add a CheckedListBox control and name it checkedListBoxProducts. Add a ListBox and name it listBoxShoppingCart. Your form should look like this:

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Find the Items property of the CheckedListBox control in the Properties Window. Click the button with three dots to open the String Collection Editor. Add the following values.

Press OK and the items should now appear inside the CheckedListBox.

The default event of the CheckedListBox is the SelectedIndexChanged event which is same as the ListBox. What we want to do is add the checked items to the shopping cart. The CheckedListBox control has an ItemCheck event which occurs when the check state of one of the items is changed. Since this event is not the default event of the CheckedListBox, we can't simply double click the control. We need to go the the Events portion of the Properties Window and find the ItemCheck event.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Double click the ItemCheck to create an event handler for this event. Now add the following code.
private void checkedListBoxProducts_ItemCheck(object sender, ItemCheckEventArgs e) { if (e.NewValue == CheckState.Checked) listBoxShoppingCart.Items.Add(checkedListBoxProducts.Items[e.Index]); else if (e.NewValue == CheckState.Unchecked) listBoxShoppingCart.Items.Remove(checkedListBoxProducts.Items[e.Index]); }

Inside the event handler for the ItemCheck event has a second parameter of type ItemCheckEventArgs which containts the properties CurrentValue, NewValue, and Index. The CurrentValue property is the CheckState value of the item that triggered the event before it was changed. The NewValue property is the new CheckState value of the item. The Index property is the zero-based index of the item. We test if the NewValue of the item is checked, and if it is, we add that item to the shopping cart. If the NewValue is unchecked, then we remove the item from the shopping cart.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The NumericUpDown Control


The NumericUpDown control is typically used to get numeric inputs and automatically restricts user for giving invalid non-numeric values. The NumericUpDown control appears like a TextBox control but there are arrow buttons on its right or left side that is used to increment or decrement the value of the control.

The numeric value of the NumericUpDown control can be accessed or retrieved using the Value property which is of type decimal. The following are some of the properties of the NumericUpDown control. Property DecimalPlaces Description Indicates the number of decimal places to display. Indicates whether the NumericUpDown control should display its value in Hexadecimal hexadecimal. Indicates the amount that will be incremented or decremented to the current Increment value when the arrow buttons are pressed. If set to true, you can use the arrow keys in your keyboard to increment or InterceptArrowKeys decrement the value. Indicates the maximum value that the NumericUpDown control can Maximum contain. Minimum Indicates the minimum value that the NumericUpDown control can contain.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Description Indicates whether the value will be displayed with thousands seperator. ThousandsSeperator (example: 1,000) Indicates where the arrow buttons are positioned. Set to Right to place the UpDownAlign buttons to the right side and Left to place them to the left side. Value The current value of the NumericUpDown control. Figure 1 - NumericUpDown Control Properties The default and most useful event of the NumericUpDown control is the ValueChanged event which executes whenever the Value property of the NumericUpDown control is changed. Let's create an example program which uses the NumericUpDown control. Create a new Windows Forms Application and name it NumericUpDown Demo. Add two labels, and two NumericUpDown controls. Change the text of the labels to "Price" and "Quantity" respectively. Add a Button control and change its caption to "Calculate". Align the controls as shown in Figure 2.

Property

Figure 2 ChChange the properties of the following control: Control button1 Property Value Name buttonCalculate Name numericUpDownPrice Decimal 2 numericUpDown1 Increment 0.50 Maximum 10000 Name numericUpDownQuantity numericUpDown2 Maximum 100 Figure 3

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The numericUpDownPrice control's Decimal property was set to 2 so it can have a precision of 2 decimal places. It's Increment property is set to 0.50 so every increments or decrements adds or subtracts the value by 0.50. The Maximum property indicated was 10000, so the price is limited to this amount. The numericUpDownQuantity controls Maximum value was set to 100 so you can only order a maximum of 100 items. Double click the button and to add an event handler to its Click event. Add the following code:
private void buttonCalculate_Click(object sender, EventArgs e) { decimal price = numericUpDownPrice.Value; int quantity = (int)numericUpDownQuantity.Value; decimal total; total = price * quantity; MessageBox.Show(String.Format("The total price is {0:C}", total)); }

Run the program. Try incrementing or decrementing the values of the numericUpDownPrice and you will see that it increments at 0.50 interval.

Click the Calculate button and the program determines the total price by multiplying the Values of both NumericUpDown control.

The PictureBox Control

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can display images on your form by using the PictureBox control. It is a simple control which has a main purpose of displaying images. All you have to do is browse for the desired image and Visual Studio/VCE will import it to your project. You can use several image formats such as JPEG, GIF, PNG, and BMP.

The following are the useful properties of the PictureBox control: Description The image that will be displayed when the loading of the actual image failed or is ErrorImage canceled. Image The image that will be displayed by the control. ImageLocation The path of the image to be displayed by the PictureBox. InitialImage The image that is initially displayed while the main image is loading. Tells how the image will be displayed. Accepts values from the SizeMode System.Windows.Forms.PictureBoxSizeMode WaitOnLoad If set to true, blocks all interaction to the form while the image is being loaded. Figure 1 - PictureBox Properties To display an image using the PictureBox control, there are multiple ways you can use. You can go to the Properties Window and find the Image property. Click the button to the right of it to bring out the Select Resource Dialog. Properties

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You have to choices, to import the image to the control's resouce file (Local resource) or to the project's resouce file. Research files are used to store resources that the application will use. Both choices has an Import button that will allow you to browse your desired image. Once you have picked the image, VS/VCE will import that image to the control or project's resource file. Your image will now display inside the PictureBox. Note that you can use the ImageLocation property instead which requires the path of your image inside your hard drive. You can even use an image url which is located in the web. Once the image is displayed, it may not look like you want it to. If the loaded image is larger the the size of the PictureBox, then the image will be clpped. You can use the SizeMode property to change the way the image is positioned or resized inside the control. The property uses values from the System.Windows.Forms.PictureBoxSizeMode enumeration which are presented below. PictureBoxSizeMode Normal StretchImage AutoSize CenterImage Zoom Description The image will be positioned in the upper-left corner of the PictureBox and if the image is larger than the PictureBox, the image will be clipped. Resizes the image to match the size of the PictureBox. Resizes the PictureBox to match the size of the image. The image is centered inside the PictureBox. If the image is larger than the PictureBox, the image will be clipped. Fits the whole image inside the PictureBox w while maintaining the image's size ratio.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 2 - System.Windows.Forms.PictureBoxSideMode Values The most common and default event of the PictureBox control is the Click event which is called when the image is clicked.

The LinkLabel Control


The LinkLabel control is similar to an ordinary label. But it has an underline and resembles a link on a webpage. The LinkLabel control can be used to link to files, directories, or web pages. When you place your mouse over the LinkLabel, the mouse pointer will turn into a hand.

The properties of the LinkLabel control is as follows: Property BorderStyle Description The style of the border around the label. Determines the appearance of the LinkLabel. When set to Popup, the button is FlatStyle slightly raised when you hover over it. LinkArea Indicates Indicates the portion of the text that wil be displayed as a link. LinkColor The color of the unvisited link. A collection of links that will be displayed. These are not the actual links that Links will be visited but portions of the LinkLabel that will be displayed as links. When set to true, the color of the link will be swapped by the color of the LinkVisited VisitedLinkColor property. TextAlign Specifies the location of the text within the control. VisitedLinkColor The color The color of a visited link. Figure 1 - LinkLabel Properties The LinkArea property will allow you to consider only portion of the text as links. The LinkArea requires two values, the starting index and the length. For example, if we only want to consider "C#" as the link, then we can provide values 7 for the index and 2 for the length. You can click the button right next to the LinkArea property in the Properties Window that will bring you to the LinkArea editor. Simply highlight the area you want to be considered as link then press OK.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Links property allows you to have multiple links within the text. Unfortunately, you can't access this property in the Properties Window so you have to do it using manual typing of code and values. You can put the code in the Form's Load event.
private void LinkLabelForm_Load(object sender, EventArgs e) { linkLabel1.Links.Add(new LinkLabel.Link(0, 6)); linkLabel1.Links.Add(new LinkLabel.Link(10, 9)); }

The Links property is a collection of LinkLabel.Link objects so we used the Add method and created new instances of LinkLabel.Link class. (Note that Link is a class within the LinkLabel class). The LinkLabel control must have an event handler hooked to its LinkClicked event. The actual navigation to the desired location is contained in the event handler.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { System.Diagnostics.Process.Start("http://visualcsharptutorials.com"); linkLabel1.LinkVisited = true; }

We use the System.Diagnostics.Process.Start static method to open your browser and navigate to the website's homepage. We then set the LinkVisited property to true to change the color of the link and indicate that it was already been visited. Note that you can also give directory of file paths to open a directory or file. If you have multiple links inside your LinkLabel control, you can use the Links property of the LinkLabelLinkClickedEventArgs when handling the event to know which link was actually clicked.

private void LinkLabelForm_Load(object sender, EventArgs e) { LinkLabel.Link googleLink = new LinkLabel.Link(0, 6); LinkLabel.Link bingLink = new LinkLabel.Link(11, 4); googleLink.Name = "Google"; bingLink.Name = "Bing"; linkLabel1.Links.Add(googleLink); linkLabel1.Links.Add(bingLink); }

We created new instances of the LinkLabel.Link class with their respective locations in the LinkLabel. We then attached names to each links using their Name property.
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { switch (e.Link.Name) { case "Google": System.Diagnostics.Process.Start("http://google.com"); break; case "Bing": System.Diagnostics.Process.Start("http://bing.com"); break; } }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Inside the LinkClicked event handler of the LinkLabel, we get the reference of the Link that was pressed using the Link property of the event argument. Finally, we checked the Name of the link that was clicked so that the browser will open and navigate to the appropriate site.

The MonthCalendar Control


The MonthCalendar control (System.Windows.Forms.MonthCalendar) resembles a calendar and shows a month and all its dates. The MonthCalendar control allows you to choose a month and a date. To choose a month, click the left and right arrows to move the month to the next or previous month.

Clicking the month header, will show all the months of the current year. Clicking the header even further will show all the years of the current decade, and clicking it once more will show all the year of the current century. You can customize the MonthCalendar control using the different properties it offers. Description A collection of dates of every year that will be displayed as bold in the AnnualyBoldedDates MonthCalendar control. Property

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Property Description BoldedDates A collection of non-recurring dates that will be displayed as bold. CalendarDimensions Specifies the number of rows and columns of months to display. FirstDayOfWeek Specifies what day the calendar will consider as the first day of the week. MaxDate Specifies the maximum allowable date. MaxSelectionCount Specifies the maximum dates that the user can simultaneously select. MinDate Specifies the minimum allowable date. MonthlyBoldedDates A collection of dates within a month that will be bolded monthly. ScrollChange The number of months to move when clicking the navigation arrows. If the user selects a range of date, this property indicates the last date in the SelectionEnd range of dates. If the user selects a range of date, this property contains all the dates SelectionRange whithin the range of dates. If the user selects a range of date, this property indicates the first date in SelectionStart the range of dates. ShowToday Specifies whether to show the date today at the bottom of the control. If set to true, the date today in the control will be enclosed with a square or ShowTodayCircle a circle. Specifies whether the week number will be shown at the left of each row ShowWeekNumbers of the control. TodayDate The date used by the MonthCalendar as today's date. Figure 1 - System.Windows.Forms.MonthCalendar Control Properties You can bold certain dates annually. For example, you can indicate to bold every 25th of December to indicate Christmas. We use the AnnuallyBoldedDates property which accepts a collection of dates. Simply go to the Properties Inspector, find the property and click the drop down arrow. You will be presented with the DateTime Collection Editor.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Simply click the Add or Remove buttons to add or remove dates. Click an item and you can specify the date by using the Value property inside the Properties Window to the right. Clicking the drop down button shows a date time picker that you can use to choose a date. Alternatively, you can simply type the date inside the text box. The MonthlyBoldedDates property marks dates monthly while the BoldedDates properties marks specific dates only once whithout repeating it monthly or annually. By default, you can select a maximum of 7 consecutive dates. You do this by holding the Shift key and selecting the first and last dates. You can change the value of MaxSelectionCount property. All the dates between the two selected dates will be selected. If the selected dates exceed the number specified by MaxSelectionCount property, then the number of selected dates will be equal to that property. You can use the SelectionStart, SelectionEnd, and SelectionRange properties to retrieve the dates form the selection. If there is only one date selected, then you can simply use the SelectionStart to retrieve that date. By default, only one month is shown, that is, 1 column and 1 row. You can change this using the CalendarDimensions property. For example, below shows a 2 by 2 MonthCalendar control which shows 4 months at the same time.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can handle the events DateSelected and DateChanged. The DateSelected event occurs when a date or a range of dates are selected. The DateChanged event occurs when the user changes the selected date or range of dates.

The DateTimePicker Control


The DateTimePicker control (System.Windows.Forms.DateTimePicker) is used to pick a single date. The control appears by default, as a combo box with a calendar icon at the right part. You can select each date component and such as the month and use the arrow keys to adjust individual components.

Figure 1 - Initial Appearance of a DateTimePicker control

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The DateTimePicker control shows (by default) the current date or the selected date. By clicking the calendar icon during runtime, you will be presented with a calendar where you can choose dates.

You can then use this calendar to choose a specific date. You use the left and right navigation arrows to move to the previous or next month.

The initial view of the calendar shows all the days plus some trailing dates of the past and next months. Clicking the Title that displays the month and year changes the view and shows all the available month of the current year.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Clicking the year will show all the years in the current decade and clicking it even more allows you to easily choose dates way back in the past. There are several properties that allows you to customize the appearance and behavior of the DateTimePicker control. Property Description CalendarFont Gets or sets the font style applied to the calendar. CalendarForeColor Gets or sets the foreground color of the calendar. CalendarMonthBackground Gets or sets the background of the calendar month. CalendarTitleBackColor Gets or sets the background color of the calendar title. CalendarTitleForeColor Gets or sets the foreground color of the calendar title. CalendarTrailingForeColor Gets or sets the foreground color of the calendar trailing dates. The ShowCheckBox property should be set to false to work with this property. When this value is true, the date in the be Checked changed/updated. When this is false, the selected date cannot be changed. CustomFormat Accepts a custom format string the will format the date displayed. Format Determines the format of the date displayed by the control. Gets or sets the maximum date and time that can be selected in the MaxDate control. Gets or sets the minimum date and time that can be selected in the MinDate control. If true, shows a text box to the left part of the DateTimePicker ShowCheckBox control. When checked, the selected date can be changed. When unchecked, the selected date cannot be changed. When set to true, shows an up-down button in place of the drop ShowUpDown down button. You can't access the calendar when this is shown.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Property

Value

Description Instead, you need to select a date component and use the up-down arrows to adjust the date. The currently selected date.

Figure 2 - DateTimePicker Properties If you are using Windows Vista or Windows 7 and using themes such as Aero, then the properties that modifies the color of the calendar has no effect. To see the results of changing the colors of the calendar, we need to disable Visual Styles. For the sake of demonstration, we will do just that. Find Program.cs in the solution explorer and open it by double clicking it. Comment out or delete the line:
Application.EnableVisualStyles();

Just note that when you do this, the controls will use the old style classic look. You can now change the colors of the calendar using the different properties that modifies the color.

You can change the format of the date displayed using the Format property. You can use the Long, Short, Time, or Custom formats. When the Custom format is selected, you can specify a format string in the control's CustomFormat property. For example, setting the format to MMdd-yy shows the date using the month number, the date, and the last two digits of the year where each date component is separated with dashes. Example output would be 04-08-11. For a list of format specifiers for date and time, go here. The ShowCheckBox property shows indicates whether to show a checkbox at the left side of the control.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

When the check box is checked, you can select date or time components and modify them using the arrow keys. If the check box is unchecked, then you are not allowed to do that. Clicking the dropdown button that shows the calendar checks the checkbox. The state of the check box can be accessed using the Checked property. The ShowUpDown property transforms the dropdown button into an up-down button and hides the calendar icon as shown by the following screen shot.

This will prohibit you from accessing the calendar and limits you to using the up-down button. You select a date or time component and use the up-down button to adjust their values. We can use the Value property to get or set the selected date of the DateTimePicker control. We can also handle the ValueChanged event of the control to react to changes in date.

The ListView Control


The ListView control (System.Windows.Forms.ListView) allows you to show a list of items in different views and add icons to each of them. The ListView control is composed of ListViewItems which form a grid-like structure of row and columns. Each ListViewItem has a label and the every ListViewItem in the first column can have an icon beside them. One common use of the ListView control is to show a list of files and folders to the user. Figure 1 shows how a ListView will look like.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 - ListView Example You can see that the Windows Explorer uses a ListView to show files and folders. The one shown above uses the Details View, although there are more types of Views available such as Large Icons and Small Icons. The following tables shows some useful properties, methods, and events offered by the ListView control. Description Specifies how the user can activate an item in the ListView. Posible values are: Activation OneClick: Activates an item using a single click. TwoClick: Activates an item using double click. Standard: Use the computer's settings. Specifies the alignment of the items in the ListView. Possible values are: Default: Uses no alignment for the items. Alignment Left: Aligns the items to the left of the ListView. Top: Aligns the items to the top of the ListView. SnapToGrid: Creates an invisible grid where the items will snap to it. Specifies whether the user can reorder the columns by dragging their AllowColumnReorder column headers to the left or to the right. When set to true, items will automatically be arranged depending on the AutoArrange Alignment property. The effect can only be seen when using the LargeIcon or SmallIcon Views. Specifies whether to show a checkbox to the left of each item when using CheckBoxes the Details View. CheckedIndices Specifies a collection of indices of checked items. CheckedItems Specifies a collection of checked items. Contains a collection of columns for the ListView and allows you to add Columns or remove a column. FocusedItem Contains the item that is selected in the ListView. Returns null if nothing
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Property

Property FullRowSelect GridLines

Description is selected. Specifies whether to select the whole row when an item is clicked. Specifies whether to draw grid lines when the ListView is using the Details View. Specifies the style of each column header. Possible values are: Clickable: Allows you to click the header just like a button. NonClickable: The header won't respond to mouse clicks. None: The headers will be hidden. Specifies whether to select an item just by hovering your mouse pointer over it. Contains a collection of Items in the ListView. Specifies whether the user is able to edit the text of an item. Specifies whether the labels should wrap over multiple lines to occupy the text. Specifies the ImageList control that contains the icons to use when using the LargeIcon View. Specifies whether the user can select multiple items. Specifies whether to show scrollbars. Contians a collection of indices of selected items. Contains a collection of selected items. Specifies whether to show tool tips for each item that has a ToolTip associated to it. Specifies the ImageList control that contains the icons to use when using the SmallIcon View. Allows the ListView to sort the items using one of these possible values: Ascending: Sorts the items in ascending order. Descending: Sorts the items in descending order. None: Do not sort the items. Specifies the ImageList to use that determines the state of each item. When checkboxes are shown at the left or each item, the two images containd in the ImageList of this property replaces the unchecked and checked appearance of those checkboxes. Contains the item at the top of the ListView. Specifies how the items are shown. Possible values are: LargeIcon: Items are displayed using 32x32 icons and a label. SmallIcon: Items are displayed using 16x16 icons and a label. List: Displays the items as a list with icons and labels. Details: Displays multiple columns that can contain information about the each item. Tile: Displays large icon and a label with sub-informations for each of the items.

HeaderStyle

HoverSelection Items LabelEdit LabelWrap LargeImageList MultiSelect Scrollable SelectedIndices SelectedItems ShowItemToolTips SmallImageList

Sorting

StateImageList TopItem

View

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 2 - ListView Properties Description Tells the ListView to temporary stop drawing visual updates until EndUpdate() is BeginUpdate called which prevents the control from flickering. Clear Removes all items in the ListView. Signals the ListView to draw all the updates. You can call this method after EndUpdate calling the BeginUpdate() method. Automatically scrolls the ListView so the item with the index you specified is EnsureVisible shown. GetItemsAt Gets the ListViewItem specified in position x, y (row, column). Figure 3 - ListView Methods Event Description AfterLabelEdit Triggers after the editing of a label. BeforeLabelEdit Triggers before the user begins editing a label. ColumnClick Triggers when the user clicks a column. ItemActivate Triggers when the user activates or selects an item. Figure 4 - ListView Events Now that you are familliar with the properties, methods, and events of the ListView control, let's create a sample application that will demonstrate tha capability of the ListView control. We will create a simple file browser that displays the contents of a specified directory. Each subdirectory will be represented by folders and files will be represented with a blank paper. You need to download the following .ico files that we will use in this exercise. Download Icons Here Extract the contents of the WinRAR file to a location that you can easily find. Create a new windows forms application and name it ListViewDemo. The following shows the GUI for the application that we will create. Method

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Label 1 2 3 4 5 6 7 8

Properties View Details ListView listViewFolderFiles SmallImageList imageListSmallIcons LargeImageList imageListLargeIcons TextBox textBoxPath Text C:\ Button buttonGo Text Go RadioButton radioButtonLargeIcons Text Large Icons RadioButton radioButtonSmallIcons Text Small Icons Text Details RadioButton radioButtonDetails Enabled True RadioButton radioButtonList Text List RadioButton radioButtonTile Text Tile

Type

Name

Figure 5

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

After constructing the GUI, we need to create two ImageList controls. An ImageList control is used to contain a collection of images to be used by other controls such as ListView or a menu. The images contained by the ImageList control should be of the same size. The ImageList control is located in the Components section of the ToolBox so drag two of them to the form. Notice that the controls are added to the component tray since they have no visual representation. Name the controls imageListSmallIcons and imageListLargeIcons.

Figure 6 The imageListSmallIcons will contain small icons and the imageListLargeIcons contains icons that will be shown when the ListView is required to show the items with large icons. Let's first add the images for the imageListLargeIcons. You will find a small square button with an arrow at the upper right of the control. Click it and change the image size to 32, 32 which means that we will be adding 32x32 pixel images.

Figure 7 Click Choose images to open the Image Collection Editor.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 8 Click the Add button and browse for the folder where you placed the extracted images from the file you downloaded earlier. Select the folder_large.ico and files_large.ico files and click Open. The files will now show up in the Images Collection Editor. The up and down arrows in the middle allows you to change the index of each image which we will use later. Be sure that folder_large.ico is in the index 0.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 9 Click OK to add the images to the imageListLargeIcons. Do the same for the imageListSmallIcons. Leave the size to 16,16 and browse for the folder_small.ico and files_small.ico files. Also ensure that the folder_small.ico is at index 0. The final step for preparing our GUI is to assign the ImageLists we created to the LargeImageList and SmallImageList properties of the ListView. In the properties window, find the LargeImageList property and click the drop down button then choose imageListLargeIcons. Do the same for the SmallImageList and use the imageListSmallIcons for it. We are now ready to add codes to our application. Go to the code editor by pressing F7 while in the Designer. Import the System.IO namespace as we will use it later. Write the following method that will create the necessary columns for the ListView control.
1 private void CreateColumns() 2 { 3 ColumnHeader filenameHeader = new ColumnHeader(); 4 filenameHeader.Text = "Filaname"; 5 filenameHeader.Width = 150; 6 listViewFolderFiles.Columns.Add(filenameHeader); 7 8 ColumnHeader lastAccessTimeHeader = new ColumnHeader("Last Accessed"); 9 lastAccessTimeHeader.Text = "Last Accessed"; 10 lastAccessTimeHeader.Width = 150; 11 listViewFolderFiles.Columns.Add(lastAccessTimeHeader); 12

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

13 14 15 16 17}

ColumnHeader sizeHeader = new ColumnHeader("Size"); sizeHeader.Text = "Size"; sizeHeader.Width = 80; listViewFolderFiles.Columns.Add(sizeHeader);

Example 1 - CreateColumns() Method We created 3 ColumnHeaders for the ListView control. The first column will show the File and Directory names. The second shows the last access time of the file or directory, and the last one shows the size of every file. We also set the sizes of each column to appropriate size to occupy the text of the headers. We then use the Add() method of the Columns property of the ListView to add the headers to the control. Write the following method which will handle the showing of the files and directories to the ListView.
1 private void ShowItemsOfDirectory(string directory) 2 { 3 DirectoryInfo currentDirectory = new DirectoryInfo(directory); 4 DirectoryInfo[] subdirectories = currentDirectory.GetDirectories(); 5 FileInfo[] files = currentDirectory.GetFiles(); 6 7 listViewFolderFiles.Items.Clear(); 8 listViewFolderFiles.BeginUpdate(); 9 10 foreach (DirectoryInfo dir in subdirectories) 11 { 12 ListViewItem item = new ListViewItem(); 13 item.Text = dir.Name; 14 item.ImageIndex = 0; 15 16 ListViewItem.ListViewSubItem subitem = new 17ListViewItem.ListViewSubItem(); 18 subitem.Text = dir.LastAccessTime.ToString(); 19 item.SubItems.Add(subitem); 20 21 subitem = new ListViewItem.ListViewSubItem(); 22 subitem.Text = String.Empty; 23 item.SubItems.Add(subitem); 24 25 listViewFolderFiles.Items.Add(item); 26 } 27 28 foreach (FileInfo file in files) 29 { 30 ListViewItem item = new ListViewItem(); 31 item.Text = file.Name; 32 item.ImageIndex = 1; 33 34 ListViewItem.ListViewSubItem subitem = new 35ListViewItem.ListViewSubItem(); 36 subitem.Text = file.LastAccessTime.ToString(); 37 item.SubItems.Add(subitem);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

38 39 40 41 42 43 44 45 }

subitem = new ListViewItem.ListViewSubItem(); subitem.Text = (file.Length / 1000) + " KB"; item.SubItems.Add(subitem); listViewFolderFiles.Items.Add(item); } listViewFolderFiles.EndUpdate();

Example 1 - ShowItemsOfDirectory() Method The method has one parameter which is the path of the directory whose contents will be shown to the ListView. Line 3 creates a DirectoryInfo object based on the directory path passed to the method. We then extracted the subdirectories and files (lines 4-5) using the DirectoryInfo.GetDirectories() and DirectoryInfo.GetFiles() mehtods. Line 7 removes any existing items in the ListView using the Clear() method. In line 8, we used the BeginUpdate() method because we will begin the adding of rows to the ListView control. Lines 10-25 uses a foreach loop to add every subdirectory of the given directory. Line 12 creates a ListViewItem which represents an item or row in the ListView. We used the Text property and assign the Name of the directory to show the name of the directory as the label for the item. Line 14 specifies the index of the image to use in the assigned ImageLists controls. We used the ImageIndex property of the ListViewItem and assigned zero because we placed the folder icon for both ImageLists at index 0. We then add the FullName which represents the full path of the directory to the Tag property because we will use it later in another method. Every subsequent column is the ListViewItem's subitems. Since we have 3 columns, the last 2 columns are subitems of the first column. Line 16 creates a ListViewSubItem object. Note that ListViewSubItem is an inner class of the ListViewItem so you need to address this class as ListViewItem.ListViewSubItem. Line 17 assigns the LastAccessTime of the directory to the label of the second column. Line 18 adds the subitem to the SubItems property of the ListViewItem. A new instance of ListViewSubItem was created in line 20 for the third column. We won't be showing the size of every subdirectory so we assigned String.Empty to the Text property of the third column. We also add it to the SubItems proeprty of the ListViewItem. Line 24 finally adds the full constructed ListViewItem to the Items property of the ListView. Line 27-42 creates another foreach loop to enumerate the files in the given directory. The code is pretty much simillar to the first forloop except that we will now use 1 for the ImageIndex. Line 38 also assigns the size of the file to the label of the third column. Note that the size was converted to KB for a more practical look. After all the files has been added to the ListView, we called to EndUpdate() method to show the changes and the added rows to the ListView. Modify the Form1() constructor to add some line of code to add codes that call the CreateColumns() and ShowItemsOfDirectory() methods.
1public Form1() 2{

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

3 4 5 6 7}

InitializeComponent(); CreateColumns(); ShowItemsOfDirectory(textBoxPath.Text);

Line 6 calls the CreateColumns() method we created to create the three columns for our ListView. Line 7 calls the ShowItemsOfDirectory() method and we passed the text of textBoxPath which is initially C:\. Therefore, when you run the program, the contents of C:\ are initially shown. Go back to Designer and double click buttonGo and use the following event handler for its Click event.
private void buttonGo_Click(object sender, EventArgs e) { ShowItemsOfDirectory(textBoxPath.Text); }

When the user types a directory path in the text box, pressing buttonGo will show the contents of that directory. Finally, we now need to add event handlers for the radio buttons that changes the view of the ListView control. Double click each of the radio button and simply assign the right View to the View property of the ListView.
private void radioButtonLargeIcons_CheckedChanged(object sender, EventArgs e) { listViewFolderFiles.View = View.LargeIcon; } private void radioButtonSmallIcons_CheckedChanged(object sender, EventArgs e) { listViewFolderFiles.View = View.SmallIcon; } private void radioButtonDetails_CheckedChanged(object sender, EventArgs e) { listViewFolderFiles.View = View.Details; } private void radioButtonList_CheckedChanged(object sender, EventArgs e) { listViewFolderFiles.View = View.List; } private void radioButtonTile_CheckedChanged(object sender, EventArgs e) { listViewFolderFiles.View = View.Tile; }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Run the program and you will see that the contents of C:\ are initially shown. Type another directory and press Go to check its contents. Change the view of the ListView using the radio buttons to see how each View looks.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The TabControl
The TabControl control (System.Windows.Forms.TabControl) allows you to create tabbed windows that you can see in many applications. An example of a tabbed window are the properties window of files and the tabs in Visual Studio.

Figure 1 - Tabs in Visual Studio

Figure 2 - Tabs in a Properties Window of a file

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The TabControl serves as a container to other controls. You can access a tab by clicking it. The appearance of an active tab will change so you can distiguish which tab is activated. Once you click a tab, the controls that belong to it will be shown. The TabControl allows you to properly organize the a form into different tabs where each tabs represents a category. For example, you can place a form that gets personal information on the Personal Info tab and the educational background in the Educational Background tab. To add a tab control, go to the Containers category of the toolbox and find the TabControl. Drag it to the form. You can resize the control but perhaps the best way is to use the Dock property so it will always take up the whole space of the form. You can go to the Properties window and find the Dock property. Click the drop down then click the middle button which means that the TabControl will be docked to all side of the form.

The TabControl consists of TabPage controls which represents the actual tab and its content. The tab pages of a tab control can be accessed using its TabPages property. The following are some useful methods of the TabPage control. Property Description Controls The controls that are exist inside this TabPage. ImageIndex Gets or sets the index displayed on this tab. Gets or sets the key accessor for the image in the ImageList of the associated ImageKey TabControl. Text The text that shows in the tab button of the TabPage. Figure 3 - TabPage Properties

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

To add a tab page, you can click the small arrow button located at the upper right side of the TabControl. This will open the smart menu where you can add or remove tab pages.

Alternatively, you can go to properties window and find the TabPages property of the TabControl. Make sure that the TabControl is the control selected and not a TabPage. Click the button of the TabPages property to open the TabPages Collection Editor.

The TabPage Collection Editor allows you to add and remove tabs and change properties such as the text of individual tabs. You can add controls to individual containers of the tab. For example, drag some controls to the body of the first tab. Then you can click on the second tab in the Designer and you can add another set of controls for that tab.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Let us now discuss the TabControl itself. The following are some properties of the TabControl. Property Description Alignment The area (top, bottom, left, right) where the tabs are aligned. The default is top. Appearance The appearance of the control's tabs. ImageList Contains a list of images that will be displayed for each tab. ItemSize Specifies the size of the tab. Multiline Allows you to create multiple rows of tabs. SelectedIndex Specifies the index of the selected tab page. SelectedTab Gets or sets the selected tab. TabCount Returns the number of TabPages of the TabControl. Allows you to access the tab pages of the TabControl and add or remove tab TabPages pages. Figure 4 - TabControl properties The Alignment property specifies where the tabs are located. The default value is Top which displays the tab in the top of the TabControl. The Appearance property changes the appearance of the tabs. It can accept three values such as Normal (the default), Buttons (which makes the tab look like a button), or FlatButtons (buttons that are not popping out). Figure 4 shows the apperances of the tab using different values for the Appearance property.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 4 - TabControl Appreances The ImageList Property allows you to add image icons to each tab. This property accepts a referecnce to an ImageList control. The ImageList control is commonly used for this property which is also available in other controls such as menus and tree views. We will discuss briefly here how to use the ImageList to provide images to other control, in this case, the TabControl. Drag an ImageList from the toolbox to the form. It is located in the Components section of the Toolbox. The ImageList will then be located in the component tray of the Designer. The ImageList will use the following two images:

Save it to any location in your hard drive. Now click the ImageList control located in the component tray of the Designer. Find the Images property in the Properties Window and click the button beside it. You will be presented with the Image Collection Editor.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Clicking the Add button allows you to browse for an image. Add the two images I have provided then click OK. You must now assign the image list to the ImageList property of the TabControl. Go to the ImageList property of the TabControl and choose the image list we have created. To show this icons beside the tabs of the TabControl, select the individual tab page in the designer (by clicking its body) then go to the Properties Window and find the ImageIndex property. Clicking the dropdown beside it will show you the indexes and a preview of each image. Assign your desired index to each tab. You can use the same index for different tabs. Your tabs will now show images beside the their text.

You can adjust the ItemSize property to adjust the size of tabs. This is useful when the images you placed in tabs are too big.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

If the number of tabs is too many and it doesn't fit the width of the form, then arrow buttons will show up to the top right of the TabControl next to the last visible tab.

You can click the arrows to scroll the tabs to the left or to the right. The MultiLine property allows you to create multiple columns of tabs. If the tabs are too many, then you can set this property to true.

The TabPages property allows you to add or remove tab pages to the TabControl. The following code programatically adds three more tab pages to the TabControl.
TabPage tab1 = new TabPage("Tab 1");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

TabPage tab2 = new TabPage("Tab 2"); TabPage tab3 = new TabPage("Tab 3"); tabControl1.TabPages.Add(tab1); tabControl1.TabPages.Add(tab2); tabControl1.TabPages.Add(tab3);

The TabPages has a type of TabPageCollection which is a collection of TabPage objects. Therefore, we can use typicall collection methods such as Add, Remove, or AddRange. You can use the SelectedIndex property to get the index of the selected tab. The index is the position of the selected tab in the TabPages collection.
MessageBox.Show("The selected tab is " + tabControl1.TabPages[tabControl1.SelectedIndex].Text);

The SelectedTab simply returns or sets the selected TabPage object.


TabPage selectedTab = tabControl1.SelectedTab; MessageBox.Show("The selected tab is " + selectedTab.Text);

The TabCount simply returns the number of TabPages of the TabControl. The TabControl has a SelectedIndexChanged event which triggers when the selected tab changes. The TabControl is very useful when your form has different sections or categories. A good example where a TabControl will be useful is in a Form that provides the options or settings of an application.

The ToolTip Control


You can use the ToolTip control (System.Windows.Forms.ToolTip) to display tooltips which offers description about the the a certain control of part of the GUI. Tooltips can be seen in numerous applications including Visual Studio. Tooltips give you a brief description to the functionality of a certain GUI component or control.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can find the ToolTip control in the common controls category. When you drag a ToolTip control from the toolbox to the form, you will find it in the component tray section of the Designer.

Once a tooltip is placed, you need to assign it to a control. Whenever a tool tip is added to the form, a new property named ToolTip is added to every control in the form. You can find it in the properties window.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

This new property specifies the text inside the tool tip that will be shown. Each tool tip you add will also add its own property to every control. So if for example, we have two ToolTips control added to the form, then two ToolTip properties will be added to each control. Let's take a look at some properties of the ToolTip control. Property Description Active This property activates or deactivates the ToolTip. AutomaticDelay This affects the value of other delay properties. AutoPopDelay Determines the time the tooltip will stay visible. InitialDelay Determines the time to wait before the tooltip will pop out. IsBalloon Specifies whether the tooltip should use a ballon-styled window. Specifies the length of time that must transpire before subsequent ToolTip ReshowDelay windows appear as the pointer moves from one control to another. Specifies whether a ToolTip window is displayed, even when its parent control ShowAlways is not active. ToolTipIcon An optional action shown to the left of the tooltip window. ToolTipTitle Adds a title to the tooltip message. UseFading Specifies whether a fade effect should be used when displaying the ToolTip.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can also change the appearance of the tooltip window by setting the IsBalloon property to true.

You can add multiple ToolTip controls to the form so each control can use a different ToolTip with a different set of properties. Although a single control can use multiple tooltips at the same, time, it is not practical and looks wiered when the tooltips pop out.

The TrackBar Control


The TrackBar control (System.Windows.Forms.TrackBar) looks like a slider with a thumb that you can move to adjust it's value. The part where the thumb points represents the current value. The following shows you how a track bar looks like.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 The user can slide the thumb to the left or to the right or you can change the orientation to vertical so you can slide the thumb up or down. Each tick marks below represents a value, with the lowest being in the left or bottom, and the highest in the right or top. Let's take a look at some properties of the TrackBar control. Description The value to add or subtract when the user presses the Page Up or Page Down LargeChange key or when he/she clicks either side of the TrackBar. Specifies the maximum value that the TrackBar can handle. It is also the value of Maximum the rightmost or topmost tick. Specifies the minimum value that the TrackBar can handle. It is also the value of Minimum the leftmost or bottommost tick. Orientation Specifies whether the orientation of the TrackBar is Horizontal or Vertical. Specifies the value added or subtracted when the user presses the arrow keys to SmallChange move the thumb of the TrackBar. TickFrequency Specifies how frequent the ticks will show depending on the range of value. Specifies the position where the ticks will show. Possible values are: None: Don't show the ticks. TickStyle Bottom: Show the ticks at the bottom. Top: Show the ticks at the top. Both: Show the ticks at both top and bottom. Value Contains the current value specified by the TrackBar. Figure 2 - TrackBar Properties The TrackBar control uses the Scroll event to react to the scrolling of the thumb of the TrackBar. Let's look at an example program that shows you how to use the TrackBar control. Create a new Windows Forms Application and add three track bars and labels. The TrackBar can be found in the All Windows Forms section of the Toolbar. Also add a panel control and set it's BackColor property to Black. Property

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 3 Name the three track bars as trackBarRed, trackBarGreen, and trackBarBlue. Set their Maximum property to 255 and TickFrequency to 15. Switch to Code View and type the following event handler that will be used by the three track bars.
private { int int int void trackBar_Scroll(object source, EventArgs e) red = trackBarRed.Value; green = trackBarGreen.Value; blue = trackBarBlue.Value;

Color color = Color.FromArgb(red, green, blue); panelColor.BackColor = color; }

Example 1 Go back to the Designer and select each track bar. Go to the Events section of the Properties Window and find the Scroll event then choose the trackBar_Scroll which is the event handler we created. Inside the event handler, we used the Value property of each track bar and stored it to three variables. These three values represent the RGB values of a color. We created a System.Drawing.Color object and used the FromArgb() method with the values of the track bars.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We then changed the BackColor of the panel with the new color constructed based on the values of the track bars. Run the program and slide the different track bars and notice how the color of the panel changes.

The Timer Control


The Timer control (System.Windows.Forms.Timer) is used to execute commands for every tick of time which is specified with an interval. For example, if you wan't to print your name for every 5 seconds, then you can use the Timer control. The Timer control is a non-visual control and can be seen in the component tray after you drag it to the form from the tool box. The Timer control doesn't have that much properties. The two properties that is most important are the Enabled and Interval properties. The Enabled when set to true starts the timer, and stops it when set to false. The Interval property specifies the interval time between calls to the Tick event, which is the default event of the Timer used to execute commands. Note that the value that is accepted by the Interval property is in milliseconds. If you give the value 5000 as the interval, then the Tick event will be called for every 5000 milliseconds or 5 seconds. Let's take a look at an example application of the Timer control. The following application has a button that will be animated to move up and down and bounce from the bounds of the client area of the form. Start by creating a new Windows Forms Application and naming in TimerDemo. Add a button control to the center of the form as seen in Figure 1.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 Drag a Timer control to the form. It can be found in the Components section of the tool box. You will notice that it now appears inside the component tray at the bottom portion of the Designer.

Figure 2 Select the timer control in the component tray and change it's Interval property to 50 and it's Enabled property to true so the animation will begin the moment the user runs the program. Double click the timer control to generate an event handler for it's Tick event. Remember that this event handler will be called for every 50 milliseconds. Add the following class member that will hold the number pixels to move for every tick.
private int velocity = 5;

Use the following event handler for the Timer's Tick event.
private void timer1_Tick(object sender, EventArgs e) { if (button1.Top <= 0 || button1.Bottom > this.ClientSize.Height) velocity = -velocity; button1.Top += velocity; }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The very first that the timer ticks, this handler will be called. It will first test if the button hits the topmost or bottommost corner of the form. To determine if the button hits the top corner, we used the Button.Top property which returns the Y coordinate of the top of the button. If it returns 0 or less, then it means that the button is or beyond the top bound of the client area of the form. Note that the coordinate system used by the form starts it's origin from the top-left. The second part of the condition in the if contidion tests if the button hits the bottom bounds of the client area. We used the Button.Bottom property to get the Y coordinate of the bottom of the button. We then check if it exceeds the bottom of the form by comparing it to the Height of the client area of the form. We do this using the Form.ClientSize property and accessing it's Height property. If any of the condition is true, then we simply reverse the value of the velocity by using the operator to multiply the value by -1. This would produce a bouncing effect. If the button is moving up (because it moves 5 pixels up), and it hits the top corner, then the velocity will be inverted and become's -5. Moving -5 pixels up is equivalent to moving 5 pixels down. Run the program and see the button bounce from the top and bottom corners of the form.

Designing Windows Forms


When designing a user interface, you must consider the location, size, alignment, and colors. Thankfully, Visual Studio has some tools that will aid you when designing user interfaces. For the demonstration of these tools, create a new windows forms application. When you are dragging a control to a form, you might notice some lines that appear. The Snap Lines allows you to snap a control to the edges of a form or automatically position your control with respect to the position of other controls.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can snap a control to the different edges of a form. If there are other controls on the form, the control you are dragging can automatically align itself to other controls.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can align a control to the top, center, bottom, left, or right of a bigger control.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Visual Studio also has commands to automatically align, and equalize spacing and sizes of controls. Consider a form with multiple controls:

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can select each control that you want to align by clicking them while holding the Shift key. You can also select controls by dragging your mouse and enclosing all the controls that will be selected in the selection box.

Once controls are selected, the control with a white box in its upper left corner will be the source control that other controls will align to. You can align other controls to the different edges of this control. To align controls, go to Format > Align and then choose which edge to align. For demonstration, choose Left. Other controls will now align to the left edge of the source control.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can also center a control in a form vertically or horizontally. Just go to Format > Center Form and choose which direction you want your control to be centered. You can also use another command for equilizing the spacing or the distances between controls. Consider this example form:

The form above contains controls that has unequal spacing between each other. To equalize their spacing, Select the controls and then go to Format and choose Vertical Spacing for the spacing

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

above or below the control, or Horizontal Spacing for the spacing at the left or the right side of the control. Choose Vertical Spacing and then click Make Equal.

The spacing vertical spacing between the controls are now evenly spaced. You can also select multiple controls and equilize their sizes. Consider another form below:

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The control with the white resizing handles will the be the reference control. And other controls will be resized according to the size of this control.

Go to Format > Make Same Size, then you can choose to make all the widths the same, all the height the same, or both. Choose Both all the controls will have the same size as the reference control.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You now know some techniques on making the design of your form neat and uncluttered.

Anchoring Controls
One problem when placing controls in a windows form is that their location stays the same when the form is resized. This could result in a total mess of the forms layout. It will also look very unprofessional. Consider the example below. We created a simple form with several controls in it. When we run the program at first, you will see that nothing is wrong.

But when we resize the form by dragging the sides of the form or hitting the maximize button, you will definitely see the problem.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Note that the image above was resized to fit the page. As you can see, the position of the controls did not adjust accordingly when we resized the form. One way to fix this is using the Anchor property which are availble to most of the controls. The anchor property tells how the control behaves when we change the size of the form. We can specify if the control will anchor to the different edges of the form. We can also specify how the controls will resize. Let's try putting to anchor our controls so they will look natural whatever the size of the form is. The Anchor property accepts a value from the System.Windows.Forms.AnchorStyles enumeration AnchorStyle Description Bottom The control is anchored to the bottom edge of the container. Left The control is anchored to the left edge of the container. Right The control is anchored to the right edge of the container. Top The control is anchored to the top edge of the container. None The control is not anchored to any of the edges of the container. System.Windows.Forms.AnchorStyles Values The default anchor of every control is a combination of Top and Left. When we assign AnchorStyles values to the Anchor property of a control, the distance of the control from the particular edge remains the same even if we resize it. For example, let's anchor a button to its right edge.

Visual Studio/Visual C# Express has a tool for specifying anchor styles. Select the control that will have an anchor. Go to the Properties Window and find the Anchor property.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Click the drop down button and you will be presented with a small window with 4 rectangles on each edge.

The rectangle at the center represents the control. The gray rectangles are the edges where the control will be anchored. You simply click these rectangles to add or remove an AnchorStyle to the control. Let's try remove the anchor to the Top and Left, and add an Anchor to the Right edge.

Now run the program and try to resize the form. Examine the distance of the button from the right edge when it was not resized and after it is resized.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

As you can see, the distance of the control from the right edge regardless of the form's size is the same. Now lets say we add an anchor style to the Bottom, then we will have a combination of Right and Bottom anchor styles.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

With these combination of AnchorStyles, the control will always have the same distance from the right edge of the form and from the bottom edge of the form. Now what will happen if we specified anchor directions that are againts each other. For example, the Left is against Right. We are expecting that the control will have the same distance from its left and right edge.

Run the program and resize the form.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The button was resized to maintain the two distance from its opposite sides. If anchor the control to all the four sides, the the control will be resized horizontally and vertically to keep its distance on all sides. The control will have a different behavior when we remove all the anchors (setting the Anchor property to AnchorStyles.None). The control will move half of the amount of resizing done to one side of the form. For example, if we resize the form to the right by 100px, then the control will move to the right by 50px (half of 100). If we resize the form 100px to the right and 50px to the bottom, then the control will move 50px to the right and 25px to the bottom.

Docking Controls
The Dock property allows you to dock the control to any of the edges of the form or its container. Its another way to make your controls intact when you resize the form. When you resize the form, the control remains docked to the edge specified. The Dock property accepts a value from the System.Windows.Forms.DockStyle enumeration. The following are the values available in this enumeration. DockStyle Description Bottom The control's bottom edge is docked to the bottom edge of its containing control. All the edges of the control are docked to all the edges of its containing control and is Fill sized appropriately. Left The control's left edge is docked to the left edge of its containing control. Right The control's right edge is docked to the right edge of its containing control. None The control is not docked. Top The control's top edge is docked to the top edge of its containing control. System.Windows.Forms.DockStyle Enumeration Values Let's try docking a button control into different edges of the form.

To dock a control, select the control to dock and go to Properties Window.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Find the Dock property and then click the drop down button. You will be presented with a small window with multiple buttons specifying where to dock the control.

The center square means that you will use the DockStyle.Fill value for the Dock property. The following screenshots shows the effect of docking the control to different edges.

Bottom

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Top

Left

Right

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Fill If you have multiple controls and use the same docking values, then they will be placed beside or above each other.

Using the TabIndex Property


You can cycle the focus of each control by pressing the tab key on the keyboard. Each control has a TabIndex property which indicates the order each control will get focus when the tab key is pressed. It is important to monitor the TabIndex of each control and make sure that they are in sequence depending on the layout of the control. Consider a form with four text boxes.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Suppose that their TabIndex properties are not in sequence such as this. TextBox TabIndex txtFirstName 1 txtLastName 4 txtGender 3 txtAge 2 When you run the program, the focus will be on the control who has the lowest tab index. So therefore, the focused control will be txtFirstName. If you press tab, the focus will go to the control which has the next TabIndex. Therefore, txtAge will receive the focus. A good user experience makes use of TabIndex property. We want the receiving of focus for each control to be in the right sequence so user will not get irritated and find where the focus went. Determining the right sequence depends on the position of the controls. Since the textboxes on the form above are placed in a vertical manner (from top to bottom), the first TabIndex must be in the top textbox followed by the next below, and the bottom textbox having the highest tab index. Please note that you can also use the TabIndex property on other controls such as a button. Suppose that you are through filling the fields in a form, pressing tab while you are in the last textbox will bring you to the accept button. You can do this by giving the button a TabIndex which is higher than the last text box. TabIndex property is useless on controls that cannot receive focus such as a Label control.

Adding Menus to Your Form


Menu bars can be seen in almost every application out there. Menus are used to contain different commands that the user can use. You can add menu bars to a form by using the MenuStrip control (System.Windows.Forms.MenuStrip). The MenuStrip is the container of the different menus. To add a menu bar to your form, drag a MenuStrip control from the Toolbox. It is located in the Menus & Toolbars Section.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can also see the MenuStrip control in a section located at the bottom of the Designer. Located here are some non-visual components such as a Timer control and many more. The MenuStrip control has the following useful properties. Property Description Dock Determines which location to dock the menu bar. The default is Top. GripStyle Allows you to show the grip which is used to repositions items in the menu strip. Items A collection of top-level menus. Stretch Specifies whether the MenuStrip stretches from end to end in its container. Figure 1 - MenuStrip Properties

Adding Standard Menus


Visual Studio offers you a way to automatically add standard items to the MenuStrip control. To do this, open the smart tag, which can be done by pressing the arrow button at the upper right side of the MenuStrip.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Then choose Insert Standard Items.

Visual Studio will fill the MenuStrip with standard menus such as Creating New files, Saving Files, Loading and many more.

Adding Your Own Menus


The standard menus might not suit what you specifically need. We can create our own custom menu bar using Visual Studio's tools. You can either undo the placement of the standard menu by hitting Ctrl+Z or you can simply delete the MenuStrip and add a new one. To add a menu item, click the box labeled "Type Here" and type the name of the menu.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You will notice that as you type, another box will appear beside and below it so you can add more items. As an example, type File, Edit, and Help in the MenuStrip.

To add submenus, click a menu item it will open up a container for all its submenus. You will also see a box that will allow you to insert sub menus.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

If you want to add a separator, type the - character.

You can even create submenus of submenus. You can nest and nest menus if you want to. A submenu which contains another submenu can be identified by the arrow at its right side.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Each text menu item you add is represented by ToolStripMenuItem. The separator is represented by ToolStripSeparator. The ToolStripSeparator is only used to separate related menus. Each ToolStripMenuItem is added to the MenuStrip's Item property and each submenu is added to the ToolStripMenuItem's DropDownItems property. Visual Studio automatically adds a name to each ToolStripMenuItem control which is based on the text you specified. Let's discuss the properties of the ToolStripMenuItem. Property Description Checked Tells whether the item is checked. CheckOnClick Tells whether an item will be checked or unchecked when it is clicked. CheckState Tells whether the item is checked or unchecked. DropDownItems A collection of submenus of the current item. Enabled Enables of disables this item. Image An optional image or icon that is shown at the left of the label. ShortcutKeys The shortcut keys associated with the ToolStripMenuItem. ShowShortcutKeys Tells whether the shortcut keys for an item is shown in the menu. Text The text or label of the menu item. The text inside the tool tip that appears when you hover your mouse on the ToolTipText menu item. Figure 2 - ToolStripMenuItem Properties

Checking and Unchecking Menu Items

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The CheckOnClick property allows a menu item to be checked or unchecked. For example, you can have a menu that shows a list of windows that will be shown. You can turn their CheckOnClick properties to true. When a menu item is checked, you will see a check in its left side.

You can use the Checked or CheckState property of the menu item to tell whether it is checked or unchecked.

Adding Shortcut Keys to a Menu Item


You can add shortcut keys to a menu item. The easiest one is by using the & (ampersand) character when typing the name of the menu item.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The letter following the & character will be considered as the shorcut key. For example, &Save will have S as the shortcut key and E&xit will have the X as the shortcut key. At the designer, the shortcut key will be underlined. The underline will not be shown during runtime unless you hit the Alt key. Using this type of shortcut key requires the use of the Alt key. To activate a menu item, you hit the Alt + Shortcut Key. For example, if the shortcut Key of the File menu is F, then you use Alt + F combination to activate the menu item. If you want more complex shortcut combinations, then we have to use the ShortcutKeys property. Select a menu item and then go to the Properties Window and find the ShortcutKeys property. Click the drop down arrow to show you a small window that allows you to choose the shortcut keys for the current menu item.

Once you specified a shortcut combination, it will now appear beside the label of a menu item provided that the ShowShortcutKeys property of the menu item is set to True.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Adding Icons to Menu Items


You can add images or icons at the left side of a menu item as seen in the standard menus.

We use the Image property to do just that. Click the drop down button of the Image property in the Property Window. Choose which resource to use and then browse for the appropriate image. If the image is too large, then it will automatically be scaled based on the value of the ImageScaling property.

Adding Functionality to the Menu Items


Menu items have the Click event which occurs when the menu item is clicked. We can handle this event to give functionality to menu items. To add a Click event to a menu item, in the
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Designer, double click the menu item and Visual Studio will automatically create an event handler for you. For menu items that has CheckOnClick properties set to true, you can handle the CheckedChange or CheckStateChange events. As an example create another form and create a menu as seen below.

Double click the Exit menu item. Visual Studio will create an event handler for its Click event. Add the following code.
private void exitToolStripMenuItem_Click(object sender, EventArgs e) { Application.Exit(); }

The static method Exit of the Application class simply closes the application.

Creating Toolbars
A toolbar contains buttons and other components that serve as menu commands to the user. Like the menu, toolbars are also seen in numerous famous applications such as the Microsoft Office 2003 products. Below shows the toolbar seen in the Microsoft Word 2003 interface.

Figure 1

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

ToolStrip Control
We used a ToolStrip control (System.Windows.Forms.ToolStrip) to contain the buttons or components of a toolbar. You can move a ToolStrip using the move handles represented by vertical dots to it's left side provided that they are contained inside the ToolStripContainer control as we will see later. Below shows the important properties of the ToolStrip control.
Property CanOverflow GripStyle Items LayoutStyle Description Specifies whether the items that can't fit inside the ToolStrip will be placed in a separate hidden area accessible via a drop-down button. Specifies whether the ToolStrip move handle is visible or hidden. Contains the items that belong to the ToolStrip. Specifies how the items will be displayed.

ShowItemToolTips Specifies whether each items will show a tool tip. Stretch Specifies the Orientation of the ToolStripPanel.

Figure 2 - ToolStrip Properties

Adding Standard Items to Toolbar


Before we create our own customized toolbar, let's see how VS/VCE can automatically create standard items for use such as the Save, Open, Copy, and Paste buttons. Create a new Windows Forms Application and name it ToolBarDemo. From the Menus & Toolbars section of the Toolbar, drag a ToolStrip control to the form. You form should now look like this.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Click the small square with an arrow located to the top right side of the ToolStrip to reveal a small window.

Click the "Insert Standard Items" and VS/VCE will create standard buttons as seen below.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

ToolStrip Items
The Items property will hold the items that is contained by the ToolStrip. There are multiple kinds of items that can be placed inside a ToolStrip and they all inherit from the ToolStripItem class.
ToolStripItem ToolStripButton Description An item that represents a button. You can click this item to perform different actions. An item that represents a label used to show uneditable texts. It can also display an image instead of text. An item that represents a button with a drop down arrow beside it. Clicking the drop down arrow shows a drop down menu that you can click. The button itself has its own functionality when clicked.

ToolStripLabel

ToolStripSplitButton

Similar to the ToolStripSplitButton, this one also shows a button with a drop ToolStripDropDownButton down arrow, but the button is now represented with an image that when clicked, opens up the drop down menu. ToolStripComboBox ToolStripProgressBar An item that represents a combo box that shows a drop-down list of items that you can choose. Adds a progress bar to your toolbar.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

ToolStripItem ToolStripSeparator ToolStripTextBox

Description Adds a horizontal or vertical divider between ToolStrip items. A item that represents a text box. You can type a text in this item that will be used for processing.

Figure 3 - ToolStrip Items The following section shows you how to create and use each of these ToolStrip items.
The ToolStripButton

The ToolStripButton control is the most basic component you see in a toolbar. You click a ToolStripButton control and it will execute its Click event just like an ordinary button. Delete the previous ToolStrip with standard menus and add a new ToolStrip control. If you select the ToolStrip, you will see an icon with a drop-down button beside it. Clicking it will show you a list of ToolStrip items you can add.

Choose the Button to add a ToolStripButton control to the ToolStrip.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The button uses a default icon. If you wan't to change it, then you can use the Image property of the ToolStripButton in the Properties Window and then browse for the desired image. In the Designer, double click the created ToolStripButton to generate an event handler for its Click event. Add the following code inside the event handler.
MessageBox.Show("Button was clicked!");

The code above simply shows a message when you click the button in the ToolStrip. In a more realistic scenario, you will add codes that perform specific tasks such as changing the font style of a font in a text box.
The ToolStripLabel

The ToolStripLabel control allows you to add an uneditable text that can be used to describe other items. It also allows you to add an optional image beside the label. To add a ToolStripLabel, you click the new item icon in the ToolStrip and choose Label from the list.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

When a new ToolStripLabel has been added, you can then use the Text property to change the text of the label.

You can also add an image by using the Image property. You can go to the Properties Window and click the button beside the Image property. You can then browse an image to be displayed beside the label.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The ToolStripSplitButton

The ToolStripSplitButton control represents a button that can be clicked. Additionally, it has a drop-down button beside it that when clicked, shows a drop-down menu related to the functionality of the button. One example of this control is the Add New Item button in the Toolbar of Visual Studio.

When you click the actual button, it shows the Add New Item Window instead of showing the list of menus. To add a ToolStripSplitButton control, click the new item icon in the ToolStrip and choose SplitButton.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

When the ToolStripSplitButton is added, you can click its drop down button to add menu items by typing each one in.

The button and the menu items can react to their own Click events. Note that the button and each menu items' Click event handler are separate from each other. Like the ToolStripButton control, you can also change the icon of the ToolStripSplitButton control using the Image property.
The ToolStripDropDownButton

The ToolStripDropDownButton is similar to the ToolStripSplitButton in that it also shows a drop-down menu when clicked. The only difference is that the actual button is simply an image

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

that when clicked, shows the menu as if you clicked the drop-down button. Therefore, the button's purpose is just to open the hidden drop-down menu. Like the other ToolStripItems, you can create a ToolStripDropDownButton by clicking the new item icon in the ToolStrip and by choosing the DropDownButton.

Adding menu items is similar to the ToolStripSplitButton control. You simply type in the menu items that you want to add to the drop-down menu. Like the ToolStripButton control, you can also change the icon of the ToolStripDropDownButton control using the Image property.
The ToolStripComboBox

The ToolStripComboBox allows you to embed a combo box to your ToolStrip. It's just like an ordinary ComboBox control. You add items using the Items property and you react to SelectedIndexChanged event.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The following shows a ToolStripComboBox with some items added to it.

Note that the default event of the ToolStripComboBox is the Click event so you need to go to the Events section of the Properties Window and find the SelectedIndexChanged event if you want to add an event handler to it.
The ToolStripTextBox

The ToolStripTextBox allows you to add a text box in the ToolStrip. The ToolStripTextBox is similar to an ordinary TextBox control and the most imporant property is the Text and it reacts to the TextChanged event.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Note that the default event of the ToolStripTextBox is the Click event so you need to go to the Events section of the Properties Window and find the TextChanged event if you want to add an event handler to it.
The ToolStripSeparator

The ToolStripSeparator control has only one purpose, to separate related ToolStrip items.

As you can see above, the ToolStripSeparator divides the ToolStrip into groups.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The ToolStripProgressBar

The ToolStripProgressBar is used to show the progress of a certain process such as saving, copying, deleting, or any task that may require the user to wait. It gives the user a hint on the progress of a certain process. Without it, the user may think that the program is stuck or is not responding properly.

The most important property for the ToolStripProgressBar is the Value and Step property. The Value property specifies the current progress of the progress bar. The Step property specifies how much to increment the Value when calling the PerformStep() method. As a simple example, change the Step property to 1 and add a Timer control from the Components section of the Toolbar to the form. Change the Enabled property of the Timer to True and double click it to generate an event handler for its Tick event. Add the following code inside the event handler.
toolStripProgressBar1.PerformStep();

This performs the PerformStep() method for every 100 milliseconds (as specified by the Interval of the Timer) and increases the value of the ToolStripProgressBar by 1 (as we specified in the Step property). Run the program and watch as the progress bar gradually fills.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Adding ToolTips to ToolStrip Items

Each item has a ToolTipText property that specifies the tool tip to show when you hover you mouse to an item. Please note that the ShowItemToolTips property of the ToolStrip must be set to True for the tool tips to show.

Using the CanOverflow and Overflow Properties


So what will happen if the toolbar has too many items that it won't fit the space provided for the ToolStrip? By default, the CanOverflow property of the ToolStrip is set to True. This all the items that are out of the width or height of the ToolStrip. You can then access them using a dropdown button as seen below.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

You can also set the Overflow property of a ToolStripItem to Always. This puts an item to the hidden menu even if the ToolStrip still has lots of space.

The ToolStripContainer Control


The ToolStripContainer control (System.Windows.Forms.ToolStripContainer) serves as a container for toolbars. With this control, you can arrange and change the positions of the toolbars inside this container. The ToolStripContainer is composed of ToolStripPanels which is the actual area where you place the ToolStrips. By default, there are four panels visible to each side of the ToolStripContainer.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 The following are some of the properties of the ToolStripContainer control. Property Description BottomToolStripPanel Gets the bottom ToolStripPanel of this control. BottomToolStripPanelVisible Specifies whether the bottom ToolStripPanel is visible. ContentPanel Gets the center panel of this control. LeftToolStripPanel Gets the left ToolStripPanel of this control. LeftToolStripPanelVisible Specifies whether the bottom ToolStripPanel is visible. RightToolStripPanel Gets the right ToolStripPanel of this control. RightToolStripPanelVisible Specifies whether the right ToolStripPanel is visible. TopToolStripPanel Gets the top ToolStripPanel of this control. TopToolStripPanelVisible Specifies whether the top ToolStripPanel is visible. Figure 2 - ToolStripContainer Properties Let's look at the ToolStripContainer in action. Create a new Windows Forms Application and name it ToolStripContainerDemo. Add a ToolStripContainer from the Menus & Toolbars section of the Toolbox to the form. Change the Dock property of the ToolStripContainer to Fill.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

By default, only the top ToolStripPanel is shown. You can now add multiple ToolStrips to this panel by dragging them from the toolbox to this area. The arrows on the sides allows you to create new panels. For example, by clicking the arrow in the left side of the container, a new ToolStripPanel will be created and will be available as a container for ToolStrips.

Let's add two ToolStrips to the top panel. Also add three ToolStripButtons to each of them.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Notice that as you add new ToolStrips, the new one is placed below or next to the previous one. The size of the panel also changes automatically to accomodate the ToolStrips. Run the program to see the toolbars. By clicking and draging the move handles of each ToolStrip, you can arrange or change their position and orientation. For example, you can drag the second ToolStrip up and place it next to the first one.

Remember that we added a ToolStripPanel to the left side of the ToolStripContainer. This is invisible at runtime if it is empty. But you can drag a ToolStrip to it as seen below.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Back to the Designer. If you wan't the ToolStrip to occupy the whole row or column, then you can set it's Stretch property to True.

If you don't want the ToolStrip to be moved, then you can set its GripStyle property to Hidden.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can also disable the ToolStripPanels if you won't be needing them. To do this, select the ToolStripContainer. It may be hard to do this manually so you may go to the Properties Window and use the combo box located to the top of it. Find the toolStripContainer1 and select it.

Click the square icon to the upper right side to open up a window. Uncheck the panels that you want to disable. to open up a window. Uncheck the panels that you want to disable.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Dialogs
Dialogs are windows that has certain specific function such as saving or opening a file, choosing a color, or printing a document. The .NET frame work offeres the dialog controls which allows you to call dialogs to do specific task. The dialogs can be customized using the properties of those controls.

Dialog for Picking Colors

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Dialog for Browsing Folders

Dialog for Choosing Font Styles

Dialog for Saving a File


COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Dialog for Openning a File Although you can construct your own dialogs, using this predefined dialogs makes your application more standardized as a Windows application as almost all application in Windows uses these dialogs. Note that dialogs' appearance may look different on other versions of Windows such as Windows XP. The screenshots above are dialogs of Windows 7 operating system.

The ColorDialog Control


The ColorDialog (System.Windows.Forms.ColorDialog) is used when you want to pick different colors. For example, when you want to pick for a color of the font or a background color for the form, you can use the ColorDialog control.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The following are some of the useful properties of the ColorDialog control. Properties Description AllowFullOpen Specifies whether the user can choose custom colors. Color The color that the user selected. CustomColors A collection of custom colors picked by the user. FullOpen Specifies whether the part used to pick custom colors are automatically open. The window of the initially composed of predifined color pallettes. You can click the Define Custom Colors button to reveal a more colors where you can pick every color you can think of. You can even provide the Hue, Saturation, Luminance values or RGB values. The main window allows you to choose colors while the right slider adjusts the brightness of the color. You can click the Add Custom Colors button to put the selected color to the Custom Colors pallete so you can reuse it later. The following example, demonstrates the use of the ColorDialog. Create a similar form shown below.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Drag a ColorDialog control to the form. It will not be visible to the form but you can find it a the bottom section of the Designer.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

To change properties of the ColorDialog control, click it in the designer and proceed to Properties Window. Double click the button to create an event handler for its Click event. Use the following code for the event handler.
private void button1_Click(object sender, EventArgs e) { DialogResult result = colorDialog1.ShowDialog(); if (result == DialogResult.OK) { this.BackColor = colorDialog1.Color; } }

The first line of code calls the ColorDialog's ShowDialog static method. This method shows up the color dialog where the user can pick a color. This method returns a System.Windows.Forms.DialogResult value which indicates whether the user clicked the OK or the Cancel button of the Dialog. If the user clicked a color and pressed the OK button, the dialog closes and the color the user picked is stored in the Color property of the control. We test the value of the result to determine if the user clicks the OK button. If so, we changed the background color of the form to the color the user picked using the value of the Color property.

Run the program and click the button. The Color dialog will open up. Select a color and click OK. Watch as the color of the form changes to the color you have picked.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The FontDialog Control


The FontDialog control (System.Windows.Forms.FontDialog) is a handy control for selecting different kinds of font and font-related properties.

Using the FontDialog, you can change the font type, style, size, color, add effects and specify character sets for the font. You can also preview the actual font. The following are some of the useful properties of the FontDia control. Properties Description Color The selected color of the user. Font The resulting font constructed using the font dialog. MaxSize The maximum size the dialog can provide. MinSize The minimum size the dialog can provide. ShowApply Indicates whether to show the Apply button. ShowColor Indicates whether to show the Color option. ShowEffects Indicates whether to show the Effects option. Note that the FontDialog hides the option to chose color by default. To allow the user to choose a color, set the value of the ShowColor property to true. You can then access the selected color via the Color property. The ShowApply property allows you to show the Apply button on the FontDialog. You can then handle the Apply event to apply the changes to the target font while not closing the dialog itself.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Let's look at a simple example of using the FontDialog control. Create a form similar to the form show below.

We will be changing the font of the text box depending on the constructed font using the FontDialog control. Drag a FontDialog control to the form. Since the FontDialog control is not a visual control, it will be located at the bottom portion of the Designer. Double click the button and use the code below for the event handler.
private void button1_Click(object sender, EventArgs e) { DialogResult result = fontDialog1.ShowDialog(); if (result == DialogResult.OK) { textBox1.Font = fontDialog1.Font; } }

We first called the ShowDialog static method of the FontDialog control to show the actual dialog to the user. The user can now pick the different font properties and click OK. We check if the user presses the OK button by testing the value returned by the ShowDialog mehtod. If the user presses OK then we change the font of the textbox to the one specified by the user.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Run the program and type any text inside the text box. Click the button to open up the Font Dialog and then choose the desired font. Click OK and the font of the text box will change.

The FolderBrowserDialog Control


The FolderBrowserDialog contrl (System.Windows.Forms.FolderBrowserDialog) allows you to browse for a directory in your system. The control uses a tree view to show all the folders. The Browser shows the Desktop (by default) as the top level root folder and below it are its content. You can click the arrows or each folder to show other folders/subdirectories inside it. You can also create a new folder inside the selected folder or directory.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The following are some of the useful properties of the FolderBrowserDialog control. Description Allows you to add a descriptive text above the tree view of the Description FolderBrowserDialog. Gets or sets the folder that the FolderBrowserDialog will consider as the RootFolder root or the top level folder. SelectedPath The folder or path that the user has selected. ShowNewFolderButton Shows or hides the Make New Folder button. The Description property allows you to add a description right above the tree view of the dialog. Property

If you don't want the desktop as the top level root folder, then you can use the RootFolder property. In the properties window, find the RootFolder property and press the drop down button beside it. You will be shown with predefined paths that you can choose.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can retrieve the selected folder or path using the SelectedPath property. The path is returned as a string. We will now create an example application to show the use FolderBrowserDialog control. Our example program will allow the user to choose a directory, then it will be displayed in a text box. The contents of the directory will then be listed using a list box. Create a new form similar to the one below. which contains a button, text box, and a list box control.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Add the FolderBrowserDialog from the Dialogs category of the Toolbox. The control will be located below the bottom portion of the Designer. Double click the Browse button and use the code below for the event handler.
private void button1_Click(object sender, EventArgs e) { DialogResult result = folderBrowserDialog1.ShowDialog(); if (result == DialogResult.OK) { //Show the path using the text box textBox1.Text = folderBrowserDialog1.SelectedPath; //Obtain information about the path DirectoryInfo selectedPath = new DirectoryInfo(textBox1.Text); //Clear the list box first listBox1.Items.Clear(); //Check if there are directories then add a label if (selectedPath.GetDirectories().Length > 0) listBox1.Items.Add("== Directories =="); //Show all the directories using the ListBox control foreach (DirectoryInfo dir in selectedPath.GetDirectories()) { //Show only the name of the directory listBox1.Items.Add(dir.Name); } //Check if there are files then add a label if (selectedPath.GetFiles().Length > 0) listBox1.Items.Add("== Files =="); //Show all the directories using the ListBox control foreach (FileInfo file in selectedPath.GetFiles()) { listBox1.Items.Add(file.Name); } } }

Please note that we also need to import the System.IO namespace above the code.
using System.IO;

First, we called the FolderBrowserDialog using the ShowDialog method. The user can now pick a folder and press OK. We need to test if the user pressed the OK button. This can be determined using the value returned by the ShowDialog method. If the user presses the OK button, we display the selected path in the text box.
DirectoryInfo selectedPath = new DirectoryInfo(textBox1.Text);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

This line creates a new DirectoryInfo object using the path selected by the user. A DirectoryInfo object is contained in the System.IO namespace. It contains properties that describes a directory such as the full path of the directory, and its contents. We clear the contents of the list box in case there are some previously added items exists.
//Check if there are directories then add a label if (selectedPath.GetDirectories().Length > 0) listBox1.Items.Add("== Directories =="); //Show all the directories using the ListBox control foreach (DirectoryInfo dir in selectedPath.GetDirectories()) { //Show only the name of the directory listBox1.Items.Add(dir.Name); }

We then check if there are subdirectories inside the current folder using the Length property of the DirectoryInfo[] value returned by calling the GetDirectories method. If so, we create a label and add it to our list box. We enumerate all the subdirectories inside the current folder using the GetDirectories method and a foreach loop. loop. We add the name of each subdirectory to the list box.
//Check if there are files then add a label if (selectedPath.GetFiles().Length > 0) listBox1.Items.Add("== Files =="); //Show all the directories using the ListBox control foreach (FileInfo file in selectedPath.GetFiles()) { listBox1.Items.Add(file.Name); }

We used the same technique for enlisting all the files inside the selected folder. But this time, we use the GetFiles method and FileInfo objects. The FileInfo object contains information about a specified file. Now execute the program and select a folder. Press OK and look as the program shows you the directories and folders contained inside the selected folder.

The OpenFileDialog Control


The OpenFileDialog control (System.Windows.Forms.OpenFileDialog) allows you to open and read file contents such as texts from text files. The dialog allows you to browse your file system and pick a directory. You can type the name of the file that exist in the current directory or you can type the whole path of a file or directory in the File Name text box located at the bottom of the dialog.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The following table shows some useful properties of the OpenFileDialog control. Description Specifies whether to automatically add an extention when the user omits the AddExtention extention of the file he or she chooses. Specifies whether to initiate a warning if the user types a file that does not CheckFileExists exist. Specifies whether to initiate a warning if the user types a path that does not CheckPathExists exist. DefaultExt The default extention to add when the user does not indicate a file extention. The file selected by the user. This can also be the default selected file when the FileName dialog shows up. FileNames A collection of files that the user picked. Allows you to add a filter which are a special string indicating which types or Filter files are only allowed to be openned by the user. If multiple filters are present, this indicates which filter shows as the default FilterIndex starting with index 1. InitialDirectory The initial directory that the OpenFileDialog will show. Multiselect Tells whether the user can select multiple files. Title The title of the dialog. Property

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The AddExtention property automatically adds an extention when the user does not indicate the file extention of the file name. The extension to add is specified by the DefaultExt property. The CheckFileExists and CheckPathExists methods are recommended to be set to true so the dialog will issue a warning message if it cannot find the specified file or directory. The InitialDirectory property specifies the initial directory that the dialog will show when you open it up. The Title property is the title of the dialog located at the title bar. The FileName property is the selected file selected or specified by the user. You can allow a user to select multiple files by setting the Multiselect property to true. You can then use the FileNames property to get the collection of selected file names.

Filtering Files
We can filter the files to be shown by their file types. We use the Filter property which accepts a string containing a special pattern. For example, we can set the dialog to only show text files by filtering the results to only files with .txt file extentions. The Filter property requires a special pattern.
Description1|FilterPattern1|Description2|FilterPattern2|...DescriptionN|Filte rPatternN

We first start with a description telling about the type of file. We then follow it with a vertical bar (|) followed by the filter pattern. For example, the following pattern only shows the text files.
Text Files|*.txt

The description here is Text Files and the pattern is *.txt. The * character is a wild card character which means any names. The .txt portion specifies the specific file extention. The filter pattern says any file with a file extention of .txt. You can also use the wildcard characters for many other purpose. For example, m*.txt is the pattern for all the text files that start with letter m. *r.txt is the pattern for all the text files that ends with letter r, *.* is the pattern for all kinds of files, *.t* is the pattern for all files that have a file extention that starts with letter t. You can specify multiple filters. For example, the following pattern adds multiple filters.
Text Files|*.txt|Bitmap Files|*.bmp|All Files|*.*

You can select a filter using a combo box next to the file name text box of the dialog.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can group a set of file extensions for a single description. For example, image files consist of different file extensions such as bmp, jpeg, or png. You simply separate the file extentions using semicolons.
Image Files|*.bmp;*.jpeg;*.png;*.gif

When you select this filter, then all of the files that matches one of the filter patterns will be shown.

OpenFileDialog Control Example


We will now create an example application that uses the basic capabilities of the OpenFileDialog control. The application will allow a user to browse for a text file and view its contents using a multiline text box. Please note that we need to import the System.IO namespace in our code.
using System.IO;

Create a form similar to the one below. Use a multiline text box by setting the Multiline property to true. Set the Scrollbars property of the text box to both and the WordWrap property to false (optional). Drag an OpenFileDialog control from the toolbox to the form.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Double click the button to create an event handler for its Click event. Again, import the System.IO namespace first at the top of the code. Use the following code for the event handler.
private void button1_Click(object sender, EventArgs e) { //Filter to only text files openFileDialog1.Filter = "Text Files|*.txt"; //No initial file selected openFileDialog1.FileName = String.Empty; //Open file dialog and store the returned value DialogResult result = openFileDialog1.ShowDialog(); //If Open Button was pressed if (result == DialogResult.OK) { //Create a stream which points to the file Stream fs = openFileDialog1.OpenFile(); //Create a reader using the stream StreamReader reader = new StreamReader(fs); //Read Contents textBox1.Text = reader.ReadToEnd(); //Close the reader and the stream reader.Close(); } }

The first line adds a filter using the Filter property. We specified in the pattern to only allow the user to open text files. The second one assigns an empty string to the FileName so there is no file selected by default. We then open the OpenFileDialog using its ShowMethod property which returns a DialogResult value. The user can now choose a text file by browsing the system. When the user presses the Open button while a valid file is selected, then the method ShowDialog will return DialogResult.OK. We tested this using an if statement. We used the OpenFile method of
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

the OpenFileDialog control and store it in a Stream object. The Stream object points to the selected file and we use this object to create a StreamReader object which is used to read the stream(the file). We used the ReadToEnd method of the StreamReader object to read all the contents of the file and return the result as tring. We then place the result inside the text box. Execute the application and click the button. Browse for a text file and click Open. If the file the user types cannot be found, then an error will show up if the CheckFileExists and CheckPathExists properties are set to true. If the file is valid and you press Open, then the contents of the file will be shown in the text box.

The SaveFileDialog Control


The SaveFileDialog control (System.Windows.Forms.SaveFileDialog) allows you to save or write data to a specified file. The dialog allows you to browse your file system and pick a directory, then type a filename you want to be the name of the file that will contain the data to be written. You can type the name of the file that exist in the current directory and the dialog can prompt you if you want to overwrite it. You can also type the whole path of a file or directory in the File Name text box located at the bottom of the dialog.

The following table shows some useful properties of the SaveFileDialog control. Property AddExtention Description Specifies whether to automatically add an extention when the user does not specify a file extension.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Description Specifies whether to initiate a warning if the user types a file that does not CheckFileExists exist. Specifies whether to initiate a warning if the user types a path that does not CheckPathExists exist. DefaultExt The default extention to add when the user does not indicate a file extention. The file selected by the user. This can also be the default selected file when the FileName dialog shows up. Allows you to add a filter which are a special string indicating which types or Filter files are only allowed to be openned by the user. If multiple filters are present, this indicates which filter shows as the default FilterIndex starting with index 1. InitialDirectory The initial directory that the OpenFileDialog will show. Specifies whether the dialog will prompt you to overwrite a file when an OverwritePrompt existing file is already found. RestoreDirectory Specifies whether to restore to default directory when the dialog closes. Title The title of the dialog. The AddExtention property automatically adds an extention when the user does not indicate the file extention of the file name. The extension to add is specified by the DefaultExt property. The CheckFileExists and CheckPathExists methods are recommended to be set to true so the dialog will issue a warning message if it cannot find the specified file or directory. The InitialDirectory property specifies the initial directory that the dialog will show when you open it up. The Title property is the title of the dialog located at the title bar. The FileName property is the Filename specified by the user.

Property

Specifying File Types


We can specify the file types that the file will have. We use the Filter property which accepts a string containing a special pattern. For example, we can set the dialog to only allow our file to be save as a text file with .txt file extentions. The Filter property requires a special pattern.
Description1|Extension1|Description2|Extention2|...DescriptionN|ExtentionN

We first start with a description telling about the type of file. We then follow it with a vertical bar (|) followed by the extension. For example, the following pattern allows you to save files as text files.
Text Files|.txt

The description here is Text Files and the extention is .txt. You can specify multiple extensions. For example, the following pattern allows you to save a file as a .txt, or .png.
Text Files|*.txt|Image|*.png

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can select the type that the file will be saved as using the combo box below the File Name text box.

SaveFileDialog Control Example


We will now create an example application that uses the basic capabilities of the SaveFileDialog control. The application will allow a user to type into a multiline text box and then save the text into a text file using a specified file name and path. Please note that we need to import the System.IO namespace in our code.
using System.IO;

Create a form similar to the one below. Use a multiline text box by setting the Multiline property to true. Drag a SaveFileDialog control from the Dialogs category of the Toolbox to the form.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Double click the button to create an event handler for its Click event. Again, import the System.IO namespace first at the top of the code. Use the following code for the event handler.
private void button1_Click(object sender, EventArgs e) { //Specify the extensions allowed saveFileDialog1.Filter = "Text File|.txt"; //Empty the FileName text box of the dialog saveFileDialog1.FileName = String.Empty; //Set default extension as .txt saveFileDialog1.DefaultExt = ".txt"; //Open the dialog and determine which button was pressed DialogResult result = saveFileDialog1.ShowDialog(); //If the user presses the Save button if (result == DialogResult.OK) { //Create a file stream using the file name FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.Create); //Create a writer that will write to the stream StreamWriter writer = new StreamWriter(fs); //Write the contents of the text box to the stream writer.Write(textBox1.Text); //Close the writer and the stream writer.Close(); } }

The first line specifies that we can only save our file as a text file with .txt extension. The second one assigns an empty string to the FileName so the File Name text box of the dialog will be

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

initially empty (you can indicate a default filename though). We set the default extention to be .txt so if the user only types the name and forgot or do not include the extention, the dialog will automatically add the extention name in case no file type is selected. We then open the SaveFileDialog using its ShowMethod property which returns a DialogResult value. The user can now browse the directory where he/she wants to save the file. When the user presses the Save button, then the method ShowDialog will return DialogResult.OK. We tested this using an if statement. We created a FileStream object and set the file name and file mode. We then create a StreamWriter object and pass the FileStream object. We use the Write method of the writer to write the contents of the text box to the stream and save it to the file. Finally, we close the writer which also closes the file stream. Execute the application and type anything inside the text box. Click the button and choose a directory. Then type a file name and hit Save. If a similar file exist, you may be prompted if the program should overwrite the file. Setting OverwritePrompt to false will automatically overwrite the file without prompting.

Dynamically Adding Controls


Visual Studio offers you ways to design forms visually thanks to its Designer. You can simply drag and drop controls, drag them to specified locations, change their properties, and attach events. But how can you add controls during runtime where the tools from Visual Studio are not accessible? You can do so by adding them programmatically. Whenever you place a control to the form, Visual Studio generates a code that creates the object representing the control, initialize the properties specified and attach event handlers specified in the Properties Window. You can see all the generated code using the generated Designer file of every form class you create as discussed in the Separating Design and Functionality lesson. This time, you will do the same technique that Visual Studio do to create controls. You will be adding a control dynamically during runtime. To demonstrate how we can do this, let's create an application that adds all the numbers typed by the user. The program will dynamically add labels and text boxes that will hold the numeric input. The number of inputs will be given by the user. Create a new Windows Forms Application. Add a label, text box and a button as seen below. Change the name of text box to textBoxInput, and the button to buttonGenerate.

Go to Code Editor by pressing F7. Use the highlighted code below and put it inside the Form's constructor right below the InitializeComponent method.
public Form1() {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

InitializeComponent(); this.AutoSizeMode = AutoSizeMode.GrowAndShrink; this.AutoSize = true; this.Padding = new Padding(0, 0, 20, 20); this.StartPosition = FormStartPosition.CenterScreen; }

What we have done here is to demonstrate how we can manually specify values for the properties of a control, in this case, the form. The this keyword specifies the form because the code is inside the Form class. You can now see that these properties (which is normally set using Properties Window) can also be done in code. The first line of code specifies the AutoSizeMode property of the form to grow and shrink whenever neccessary to accomodate the controls that will be dynamically added. We then set the AutoSize property to true. We have done this so that the form will automatically resize when new controls are added or removed. We also added padding to the right and bottom of the form as specified by the third line. This is to add some space to the right and bottom of the form since autosize is activated. The StartPosition property of the form allows the form to initially show up in the center of the screen of your monitor. Before we continue, add a private member for our form class that will accept a collection of TextBoxes.
private List<TextBox> inputTextBoxes;

This will hold all of our input boxes so we can reference each of them and get their individual values for addition. Go to the Designer by pressing Shift + F7. Double click buttonGenerate to create an event handler for its Click event. Use the following code for the event handler.
private void buttonGenerate_Click(object sender, EventArgs e) { //Get the number of input text boxes to generate int inputNumber = Int32.Parse(textBoxInput.Text); //Initialize list of input text boxes inputTextBoxes = new List<TextBox>(); //Generate labels and text boxes for (int i = 1; i <= inputNumber; i++) { //Create a new label and text box Label labelInput = new Label(); TextBox textBoxNewInput = new TextBox(); //Initialize label's property labelInput.Text = "Input " + i; labelInput.Location = new Point(30, textBoxInput.Bottom + (i * 30)); labelInput.AutoSize = true; //Initialize textBoxes Property textBoxNewInput.Location = new Point(labelInput.Width , labelInput.Top - 3);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

//Add the newly created text box to the list of input text boxes inputTextBoxes.Add(textBoxNewInput); //Add the labels and text box to the form this.Controls.Add(labelInput); this.Controls.Add(textBoxNewInput); } //Create an Add button Button buttonAdd = new Button(); //Initialize Properties buttonAdd.Text = "Add"; //Make the button show up in the middle of the form and right below the last input box buttonAdd.Location = new Point(this.Width / 2 - buttonAdd.Width / 2, inputTextBoxes[inputTextBoxes.Count - 1].Bottom + 20); //Add an event handler to the button's click event buttonAdd.Click += new EventHandler(buttonAdd_Click); //Add the button to the form this.Controls.Add(buttonAdd); //Center the form to the screen this.CenterToScreen(); }

Don't worry if Visual Studio highlights an error in this code as it will be fixed later. The first thing we did is retrieve the value which indicates how many input boxes and labels to generate. We then initialize the inputTextBoxes variable to preparet it to hold the input boxes. We now enter a for loop which will repeat on generating new labels and text boxes depending on the number specified by the user. Inside the for loop, we created a new Label and TextBox instances. The following codes initializes/modifies the properties of the created controls.
labelInput.Text = "Input " + i; labelInput.Location = new Point(30, textBoxInput.Bottom + (i * 30)); labelInput.AutoSize = true;

The first line assigns the new label with a text depending on the position of the index in the loop. The second line relocates the position of the new label. If we failed to do this, the label will show up in its default location which is the top left portion of its container. If you are coding the Location and not using the Designer, you might find it hard to estimate the exact location you want your label to show. The Location property accepts a Point value so we created a new Point object using a constructor that accepts the X coordinate and the Y coordinate of the control. The first argument which is the X coordinate, was just an estimate location. The Y coordinate uses some simple math so that each control will added will have a distance relative to the bottom of the top text box (the text box that was used to determine the number of inputs). The expression simply says that the first generated text box will be 30 pixels from the bottom of textBoxInput, the next generated text box will be 60 pixels, the third will be 90 pixels and so on. The AutoSize property is then set to true because the default is false. As you can see, we did not set all the available properties of the Label control because each property has a default value so we can

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

only concentrate on properties that we really want to change. Let's proceed to the next code which determines the location of the generated input text box.
textBoxNewInput.Location = new Point(labelInput.Width , labelInput.Top - 3);

The Location property of the new text box was assigned with a Point object with an X coordinate equal to the width of its label pair. This makes the text box position right next to the label. The Y coordinate is the same with its label pair but we subtract 3 pixels so the center of the text box is aligned to the center of its label pair.
inputTextBoxes.Add(textBoxNewInput);

The above code adds the newley created text box to the TextBox collection that will be used later on. The following method shows how we can add the created controls to the form.
this.Controls.Add(labelInput); this.Controls.Add(textBoxNewInput);

Controls which serves as containers such as forms has a Controls property which contains all the controls that are inside it. We use its Add method and pass the individual controls to be added. Once they are added to the form, they will now be drawn to the screen once the form is initialized and is finished loading.
this.CenterToScreen();

This code recenters the form in the screen. Since the form's size was changed when we added controls, this code is neccessary. After all the input boxes are generated, we need to add the button that will add the values that the user will provide.
Button buttonAdd = new Button();; buttonAdd.Text = "Add"; buttonAdd.Location = new Point(this.Width / 2 - buttonAdd.Width / 2, inputTextBoxes[inputTextBoxes.Count - 1].Bottom + 20); buttonAdd.Click += new EventHandler(buttonAdd_Click); this.Controls.Add(buttonAdd);

The first line creates the button. Then we specified the text of the button. The third line positions the button to the center of the form and right below the last added input text box. The expression for computing the X coordinate gets the location of the center of the form. Since the left side of the control is positioned to the center, we need to subtract half the width of the button to the calculated center to position it in the middle of the form's center. We got the Y coordinate by getting the bottom of the last input text box in the inputTextBoxes collection. The last input text box was detemined by the index equal to the count of items in the collection subtracted by one. The next line adds an event handler to its click event. If you did'nt copy the code and type this, right after type += , Visual Studio will allow you to press Tab twice to automatically generate an

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

event handler for this event. The event handler for this event will be shown later. Right now, we can see that the event handlers name is buttonAdd_Click. The last code simply adds the button to the form. Type this method which is the event handler for the Click event of the buttonAdd. If this was automatically generated by Visual Studio described by the technique above, then you will find a NotImplementedException inside it which you can simply delete and replace with the following code.
void buttonAdd_Click(object sender, EventArgs e) { int sum = 0; foreach (TextBox inputBox in inputTextBoxes) { if (inputBox.Text == String.Empty) { MessageBox.Show("Plaese fill in all the text boxes.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else { sum += Int32.Parse(inputBox.Text); } } MessageBox.Show("The Sum is " + sum); }

This is the code that executes when the button for adding is clicked. You have seen how this code was added as an event handler of the buttonAdd's click event. We created a variable that will hold the sum of all the values in each text box. Using a foreach loop, we retrieve each text box and access its content. There is a simple validation inside the loop which test if the text box is filled with a value or is empty. If it is empty, an error is shown and the method is terminated. If there is a valid number inside the text box, it is added to the value of sum. After looping through all the text boxes and adding each of their values to the sum, the result is then displayed. Run the program and type 5 in the text box. Click generate and the program will create 5 text boxes.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Watch as the the form is recentered in the screen. Type some values in the text boxes and click the add button to show the sum. You have now experienced the tedious process of manually creating controls without the help of the Designing tools of Visual Studio. This is not recommended when designing the initial layout of the form. You can use this technique when you wan to dynamically create controls depending on factors that changes such as an input from the user.

Mouse Events
You can use several special events to react to certain mouse interactions to the control. You have seen the Click event which occurs when the a control is clicked by the mouse (although pressing Enter while the control is selected also generates the Click event). As you will see, there are more advanced events that are specifically used for handling mouse interactions. Some of these events have a type MouseEventHandler delegate which has a parameter MouseEventArgs that contains details about the mouse operation. The following the Mouse events that you can use. Event Description MouseCaptureChanged Occurs when the control loses or gains mouse capture. MouseClick Occurs when the control is clicked by the mouse. MouseDoubleClick Occurs when the control is double clicked by the mouse. Occurs when the mouse pointer is over the control and a mouse button is MouseDown pressed. MouseEnter Occurs when the mouse pointer enters the control. MouseHover Occurs when the mouse pointer rests on the control. MouseLeave Occurs when the mouse pointer leaves the control.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Event MouseMove MouseUp MouseWheel

Description Occurs when the mouse pointer is moved over the control. Occurs when the mouse pointer is over the control and a mouse button is released. Occurs when the mouse wheel moves while the control has focus.

Figure 1 - Mouse Events Let's now take a look at the capabilities of some of these events. Create a new Windows Forms Application and add a button in the middle of the form.

Let's add an event handler for the button's MouseEnter and MouseLeave events. What we would like to do is whenever the mouse enters the client area of the button, the button will be grow bigger, and when the mouse leaves, it will return to its original size. Go to the Properties Window and click the Events button represented by a thunder icon. Then find the MouseEnter event and double click it to create an event handler for that event.
private void button1_MouseEnter(object sender, EventArgs e) { button1.Height += 30; button1.Width += 30; button1.Top -= 15; button1.Left -= 15; }

When the mouse enters the control, its height and width is increased by 30 pixels. When the button is resized, it stays in the same position so the button will not appear in the center. We moved the button 15 pixels to the top and left (half of 30) so when the button is resized, it will
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

still be centered. We now need to reset the size and location of the button when the mouse leaves the control. Go again to the properties window and find the MouseLeave event and double click it.
private void button1_MouseLeave(object sender, EventArgs e) { button1.Height -= 30; button1.Width -= 30; button1.Top += 15; button1.Left += 15; }

The event handler simply reverts the operation done by the MouseEnter event handler. The MouseClick event is an enchanced version of the Click event. It allows you to determine some details about the click such as the location in the control where the mouse is clicked. Let's add an event handler for the button's MouseClick event. Again, go to the Properties Window and find the MouseClick in the events section and double click it. Use the following code to show the location of the click with respect to the top left corner of the control.
private void button1_MouseClick(object sender, MouseEventArgs e) { MessageBox.Show(String.Format("Clicked at point ({0}, {1})", e.X, e.Y)); }

The event handler uses the MouseEventArgs object to access the X and Y properties which represents the X and Y coordinates of the point where the mouse was clicked. Now, when you click the button, a message box will appear showing the location of the click. The MouseDown event is triggered when a button is pressed down while the mouse is over the control. The MouseUp event is the reversed and occurs when the pressed button is released. Let' demonstrate this event. Add an event handler to the MouseDown event. Just so the MouseClick event handler will not interfere with this event, comment out or delete its content. Now use the following code for the MouseDown event handler.
private void button1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) MessageBox.Show("Left Click"); else if (e.Button == MouseButtons.Right) MessageBox.Show("Right Click"); else MessageBox.Show("Middle Click"); }

The event handler uses the MouseEventArgs object to access the Button property which contains the details of which mouse button was clicked. The MouseButton enumeration contains values Left, Right, and Middle to refer to the three mouse buttons.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can handle the MouseWheel event to detect if the mouse wheel has been moved. The mouse wheel event is not available in the Properties Window so we need to access it in code. In the form's constructor, right below the InitializeComponent method, type the following code. The moment you type +=, press the tab key twice to generate an event handler for the MouseWheel event.
public Form1() { InitializeComponent(); button1.MouseWheel += new MouseEventHandler(button1_MouseWheel); }

Use the following event handler for the MouseWheel event.


void button1_MouseWheel(object sender, MouseEventArgs e) { button1.Height += e.Delta / 60; button1.Width += e.Delta / 60; button1.Top -= e.Delta / 120; button1.Left -= e.Delta / 120; }

We used the Delta property of the MouseEventArgs class. The Delta represents the number of notches that were moved forward or backward. Each notch is equal to the WHEEL_DATA constant which is 120. We divide Delta by 60 so each notch of the mouse wheel moved will only increase the width and height by 2 pixels instead of 120. Moving the wheel forward yields a positive Delta value and moving it backwards yields a negative value. The last two lines are used to adjust the position of the button so it will always be centered. Instead of dividing by 60, we divide the Delta by 120 so every moved notch, the top and left of the button will move by 1 pixel. Run the program and while the button has the focus, move the wheel forward to increase the size of the button, and backwards to decrease its size.

Keyboard Events
When you want to handle events when pressing keys in the keyboard, you can handle the KeyPress, KeyDown, and KeyUp events. The KeyDown event occurs when a keyboard key is pressed down and the KeyUp event occurs after you release the pressed key. The KeyPress event triggers when a complete keypress is made(pressing then releasing the key). The following example adds a KeyPress event to the form and whenever a key is pressed in the keyboard, it is added to the text of a label. Create a new Windows Forms Application and name it KeyBoardEvents then add a Label control.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Remove the text of the Label. Select the form and in the Properties Window, find the KeyPress event and double click it to create an event handler. Use the code inside the Form1_KeyPress event handler of the code below.
1 using System; 2 using System.Windows.Forms; 3 4 namespace KeyBoardEvents 5 { 6 public partial class Form1 : Form 7 { 8 //Variable to count letters for simple word wrap 9 private int charCount = 0; 10 11 public Form1() 12 { 13 InitializeComponent(); 14 } 15 16 private void Form1_KeyPress(object sender, KeyPressEventArgs e) 17 { 18 charCount++; 19 20 //Go to next line after the line's 30th character 21 if (charCount > 30) 22 { 23 label1.Text += "\r\n"; 24 charCount = 0; 25 } 26 else 27 { 28 //Append the pressed keyboard key to the label using 29KeyChar property 30 label1.Text += e.KeyChar;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

31 32 33 34}

} } }

The KeyPress event will trigger whenever a button in your keyboard is pressed. Line 9 declares and initialize a counter variable named charCount that will be used to detect the number of characters of the current line This will be used for our simple word wrapping mechanism. The event handler monitors the number of characters typed by incrementing the charCount at Line 18. The condition at Line 21 tests whether the value of charCount doesn't exceed 30. If so, it goes to the next line by adding the "\r\n" (carriage return-line feed) which is Windows' way of proceeding to the next line. We then reset the charCount to 0 (Line 24) since we reached the beginning of the next line. If the charCount is still below or equal to 30, then we simply append the character typed by the user by using the KeyPressEventArgs.KeyChar property. When you execute the program, you can type letters using your keyboard and watch as the text inside the label is updated and the key you have just entered was appended to it's text. When you handle the KeyDown and KeyUp events, you get a different event argument named KeyEventArgs and it contains more properties about the pressed key. It contains the following properties. Description Alt Determines if the Alt button is pressed. Control Determines if the Control button is pressed. Gets the Keys value of the key that was pressed. It is used to detect a specific KeyCode key that is pressed. Similar to the KeyCode property but also records the modifier flags (SHIFT, KeyData CTRL, ALT) that are pressed. KeyValue Returns the numeric representation of the key that was pressed. Determines which combination of modifiers flags (SHIFT, CTRL, ALT) is Modifier pressed. Shift Tells whether the Shift key is pressed. SuppressKeyPress Allows you to prevent the user from giving an input from the keyboard. As an example, the following code snippet uses the SupressKeyPress property of the KeyEventArgs to only allow numeric input and disallow any other characters such as alphabet or symbols. Add a text box to your form and add an event handler to its KeyDown event.
private void textBox1_KeyDown(object sender, KeyEventArgs e) { if (!(e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9 && !e.Shift)) { e.SuppressKeyPress = true; } }

Property

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The condition inside the if statement says that if the key typed by the user is not a number key, or if the shift key is pressed, then it will be ignored by setting the SuppressKeyPress property. We used the KeyCode property in the condition which contains values from the Keys enumeration. The numeric keys are represented by values D0 to D9. The need to check if the Shift key is not pressed is needed since pressing Shift key and a numeric key will actually result in a symbol associated to the number key (@ to 2 for example). Therefore, we used the Shift property of the KeyEventArgs class. Download Project: KeyBoardEvents

User Controls
You can create your own controls if you don't find what you want from the list of predefined controls available in .NET. You may need to create your own control because the controls that are already available for you are very general and you might need a control which will have a specific feature. These custom controls can then be placed in the toolbar together with other controls. There are two types of user defined controls, user controls and custom controls. User control is composed of preexisting controls and are very easy to create. Custom controls are created from scratch, therefore, you need to define a lot of functionality and how the custom control will render. We will focus on user controls because custom controls requires advanced concepts not fit for an introductory topic. User controls inherit from the UserControl class which is a derive class of the Control class that other control uses. You wont have access to the properties and methods of the components that you will include in a user control because only properties and methods of the UserControl class is exposed to you. But you can define properties and methods that will communicate to the components of the user control. We will be creating an EditableLabel control. It will exactly look at a lable but when the user double clicks it, it will transform into an editable textbox containing the current text of the label. You can then edit its contents and when the user presses enter, it will transform back into a label containing the edited text. Open Visual Studio and create a new project. From the list of templates, choose Windows Forms Control Library and name it EditableLabel. (If you are using Visual Studio Express, choose Class Library instead if you don't find Windows Forms Control template. You can then add a user control from the Project menu).

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 You will be presented with a blank canvas as seen below:

Figure 2 It looks just like a Windows Forms but it has no frame. This is because you are designing a user control. Any control you place inside it will be part of the user control. Click the canvas and change its Name property to EditableLabel and its AutoSize property to True. Drag a label to the canvas and change its Text property to Label and its Name property to labelDisplay. Resize the canvas so that it fits the label inside it.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 3

Adding Properties
Since we are creating a user control, then it will only contain properties and events that the UserControl class offers. It means there is no way for the user to access the properties of the Label control we have added to the form. Although the UserControl class has a Text propety which it inherits from Control, we need a more taylored funtionality involving the text inside our label. To add a property to a user control, we simply need to add a property to the class of our user control. While in Design View, press F7 to go to the Code Editor. Inside the EditableLabel class, add the following property:
[Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public override string Text { get { return labelDisplay.Text; } set { labelDisplay.Text = value; } }

You might notice two attributes at the top of the property. The Browsable attribute allows a property to be shown in the Properties Window of Visual Studio. If you don't add this attribute (and set it to true), then you can only access the property in code and not in design time. The second attribute allows us to change the property of the user control by using the propety found inside the Property Window. Note that we also used the override keyword because the Text property already exist in the User Control.

Adding Event Handlers


Now its time to add an event handler to our user control. Recall that our EditableLabel control should transform into a textbox once the user double clicks it. Therefore, we need to add an event handler to its DoubleClick event. Since we only have one control inside the canvas, then select the label. Then go to the Event section of the Properties Window and find the DoubleClick property and double click it. That will create a new event handler for the DoubleClick property.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 4 We need to add a TextBox control to our user control. Add the following field inside the EditableLabel class.
private TextBox editableTextBox;

Now inside the constructor of the EditableLabel and after the call to InitializeComponent method, add the highlighted code:
public EditableLabel() { InitializeComponent(); editableTextBox = new TextBox(); this.Controls.Add(editableTextBox); editableTextBox.Hide(); }

We instantiate our text box and added it to the Controls collection of the user control. Since we want the label to be shown first and not the text box, we hide it using the Hide method of the text box. Now let's go back to the event handler for the DoubleClick event of the label.
private void labelDisplay_DoubleClick(object sender, EventArgs e) { editableTextBox.Size = this.Size; editableTextBox.Text = labelDisplay.Text; labelDisplay.Hide(); editableTextBox.Show(); editableTextBox.Focus(); }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The above code is the event handler for the DoubleClick event of the label inside our user control. We set the size of the text box to the size of our user control. We then set its text to whatever the text of the label is. Next, we hide the label using the Hide method. Finally, we show the text box and put the focus to it so the user can start editing it. Now we need to add another event handler that will allow a user to commit the changes to the text of the label after editing. Inside the constructor of EditableLabel class, insert the following highligted code:
public EditableLabel() { InitializeComponent(); editableTextBox = new TextBox(); this.Controls.Add(editableTextBox); editableTextBox.KeyDown += new KeyEventHandler(editableTextBox_KeyDown); editableTextBox.Hide(); }

We added an event handler for the textbox's KeyDown event. When the user is finish editing the text, he or she can simply press the Enter or Return key. Here is the definition for the event handler of the KeyDown event:
void editableTextBox_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { labelDisplay.Text = editableTextBox.Text; editableTextBox.Hide(); labelDisplay.Show(); } }

First we checked if the key pressed by the user is the Enter key. Next, we set the Text of the currently hidden label into the new text entered by the user. We then hide the editableTextBox and reshow the labelDisplay containing the updated text. Finally, when the label is resized depending on the length of text, we also need to resize the actual user control. Click labelDisplay in the Designer and in the Properties WIndow's Events section, find the Resize event and double click it. Use the following event handler for it.
private void labelDisplay_Resize(object sender, EventArgs e) { this.Size = labelDisplay.Size; }

The event handler simply sets the Size of the user control to the new Size of the labelDisplay.

Compiling the User Control

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We are now ready to compile our EditableLabel user control. To do that simply go to the menu and choose Build and then Build Solution. The compiling will create a file with a .dll extension which contains your user control.

Testdriving Our User Control


To test our brand new user control, we need to create another project. Right click the solution inside the Solution Explorer and then choose New > Project.

Figure 5 In the Add New Project Window, choose Windows Forms Application and name it EditableLabelDemo. We need to import our control to the Toolbox so we can easily drag it to the form. Once you are presented with a blank windows forms, go to the Toolbox and right click (You can right click on the Generals tab to add our control there). Select the option "Choose Items...".

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 6 In the Choose Toolbox Items Window, click the Browse button. We need to browse for the .dll file containing our user control. Browse for the directory where your project was saved. Go inside the folder of our Windows Control Library project (named EditorLabel) and inside it, enter the bin folder. The dll file could either be in the Debug or Release folder. Once you found the EditorLabel.dll, select it and click Open. EditorLabel will now show up in the list of selectable controls inside the Choose Toolbox Item Window. Be sure its checked and then click OK. Now you will be able to see our user control inside the Toolbox.

Figure 7

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Drag an EditableLabel to the form. You can also find the Text property in the Properties Window since we added the Browsable attribute to that property.

Figure 8 Before we hit F5 to run the project, we must first make EditableLabelDemo project as startup project. Right click EditableLabelDemo project in the Solution Explorer and choose Set as StartUp Project. It will make the name of the startup project bold. Run the project and double click the label. Change the text to whatever you want and press Enter. Watch as the text of the label updated to whatever you typed in the editable textbox.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

END OF C# WINDOWS FORM

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

ASP.NET Introduction to ASP.NET


Welcome to the world of web development. It is yet another one large sector of application development involving web pages, servers, databases, networking and a lot of more new terminologies and concepts. If you have read the Language Fundamentals and Windows Forms section, then you have already started developing applications for the desktop. These applications can be run locally in your computer and does not require connection to the internet. But this section will not be for applications that can only be run on your computer, but web applications that can be shared and used by multiple networked computers or even by the whole world. Welcome to the internet, a gigantic space of networked servers and computers making the whole world connected. And through internet, millions of websites can be accessed. These websites contain one or more web pages. These web pages can either be static or dynamic. Static web pages simply show information and no sort of user input is needed. Back in the early days of the internet, static web pages are everywhere. But today, people want to see some interactivity to web pages. Dynamic pages are pages that are generated using some data from the server or the user. Web sites can now be called web applications because they don't just show information anymore, they now provide useful functionality and services that can be compared to desktop applications. Web applications become so popular because you don't need to install them in your computer and you can access them anywhere provided that you have an internet connection. A web application framework allows you to easily create these web applications. Microsoft developed its own web application framework, and after several versions, this is now called ASP.NET. ASP.NET is a web application framework used to create dynamic and data-driven web sites. ASP stands for "Active Server Pages". Before the arrival of ASP.NET, Microsoft developed ASP which is now called classic ASP. When .NET Framework was developed, Microsoft upgraded ASP to use the power of .NET hence the name ASP.NET. ASP.NET is also a server-side scripting language because using code, you can communicate to the actual server. An example of this is showing the server time to the user. There are two methodologies that you can use in ASP.NET. These are ASP.NET Webforms and ASP.NET MVC. ASP.NET Webforms allows you to create web pages as if it is a windows form. You drag ASP.NET controls such as a button to the web form. The web form can then handle events such as Page Load or the click of a button. These events and logic can be defined in a code-behind or in an embedded C# or VB.NET code. We will be using Webforms in the next lessons because it is simpler and you will be familliar to it if you have already learned windows forms. ASP.NET MVC or Model-View-Controller is a newer way of creating ASP.NET sites. As the name suggests, it allows you to separate the Model, the View and the Controller. The Model represents the data sources that your site will be using. The View represents the page that will be presented to the user, and the Controller contains tha logic and connects the Model and the View.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The world of ASP.NET is a very large topic to master, but the following lessons will teach you the fundamentals to create basic dynamic and data-driven websites. You will enjoy learning and creating ASP.NET applications.

Visual Web Developer 2010 Express


To create ASP.NET websites, you need an excellent tool that will make it easy for you to develop them. Although you can use a simple text editor to develop a website, it will be difficult, confusing, time consuming, and hard to test. Fortunately, Microsoft developed a free web development environment that you can use to start developing ASP.NET web applications.

Visual Web Developer 2011 Visual Web Developer 2010 Express or simple VWD is a free web development environment which is mainly used to create ASP.NET websites. It has been made available free of charge by Microsoft allowing you to get started web development with ASP.NET. It has lots of useful tools that you can use to make it easy for you to develop your websites. Some of these tools include: 1. WYSIWYG Editor - A "What You See Is What You Get" editor allowing you to preview how your site will look like while you are developing it. You will be able to see the design and how everything will look like making it easier for you to adjust the design and test them without previewing them on a real browser. 2. IntelliSense - IntelliSense is a feature that aids you when you are typing codes. It will show you a list of possible entries as you type removing the need to memorize thousands of types, methods, and variable names. 3. ASP.NET Development Server - Visual Web Developer 2010 comes with an integrated ASP.NET Development Server. This is a very important feature. Without this, you need to actually upload your site to a live server, or locally using IIS just to test your site. 4. Debugging Tools - Visual Web Developer offers debugging tools to make it easy for you to trace errors and fix them.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

There are many other features Visual Web Developer offers. Every single feature is aimed to help make a certain task easier for you. There is also a paid version of Visual Web Developer and that is Visual Studio. It offers way more features. Visual Studio is not only a tool for web development. It is the Big Daddy of all Microsoft development environments. You can create almost any kind of windows, web, and mobile applications with it. But for the rest of the lesson, the free Visual Web Developer will be more than enough for our needs.

Downloading and Installing Visual Web Developer


Visual Web Developer 2010 Express can be downloaded for free from the Microsoft's site. Below is the direct download link for the web installer of VWD. Download Visual Web Developer 2010 Figure 1 shows you the system requirements for Visual Web Developer 2010 Express. Before downloading and installing VWD, make sure that your machine has met these requirements. Operating System Processor RAM Hard Disk Space Video Windows XP SP3 (All editions except Starter), Windows Vista SP2 (All editions except Starter), Windows 7 Computer with 1.6GHz or faster processor. At least 1GB (32 bit) or 2GB(64 bit) At least 3GB of hard disk space. DirectX 9 capable video card. 1024x768 resolution or higher.

The installer is small and download will be finished in seconds. After the download open vwd_web.exe to start the installation. Please take not that you are using a web installer so you need to be connected to the internet while the installer is running because it will be downloading the necessary files for the installation. Wait for the installer to initialize.

You will be greated with a welcome window. You can leave the checkbox checked then click the "Next" button.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

In the Licence Terms window, simply select the first option then click the "Next" button.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The next window shows some optional programs that you can install. There might be more that will show here depending on whether you have already installed them. You can leave them uncheck if you want the download and installation to be faster. Click the "Next" button to proceed to the next step.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

This window will show you the list of programs that will be installed and the directory where they will be installed. It will also show you the disk space required by the installation so make sure you have enough disk space remaining. Click the "Install" button to start the download and installation.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The installation will begin downloading the necessary files. This may take several minutes depending on your internet connection speed.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

After the download is finished, then the actual installation will commence.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Just wait for the installation to finish. Congratulations, you have successfully installed Visual Web Developer.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Visual Web Developer can be accessed in Start > Microsoft Visual Studio 2010 Express. Click the icon to open our freshly installed VWD.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 2 - Welcome to Visual Web Developer 2010 Express

Your First ASP.NET Website


What are we waiting for? Let's create our first ASP.NET web site. We will present here how we can create a simple example of ASP.NET. Don't worry if you can't get concept right now, they will be discussed in detail in the following tutorials. If you haven't open up VWD right now, then do it. You will be welcomed with the Start Page.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 - Visual Web Developer Start Page If you are reading the tutorials from the Fundamentals section, then you may already know the parts of Visual C# Express IDE. Visual Web Developer has similar parts so I don't need to explain each of them again here. If you want to have a review of them, you proceed to the following links: Start Page, Menu Bar, and Toolbar Solution Explorer Properties Window Right now, our priority is to create our first web site. Before everything else, I recommend to change your settings to Expert Settings. The default is Basic which hides some useful menu entries in the menu. To change to Expert Settings, go to Tools > Settings then click Expert then wait for VWD to refresh.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Creating an ASP.NET Website


To start creating our website, you can click the New Website link in the start page or go to File Menu and choose New Website.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

After doing either of the two, the New Website Window will pop up. Choose the C# category because we will be using the C# language for our web site. Choose the ASP.NET Empty Website template. Choosing the ASP.NET Website instead will create a fully functioning site but you might get confuse of the files that it will generate so its better to use an empty template. Name the website MyFirstWebSite.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Click OK to create an empty website. A folder will be created to the path you have specified with the name of the site. It will contain the files that you will create and include in you web site. If you will look at the Solution Explorer to the right of the environment, you will see that only one file is present, web.config. This is an XML file containing the configuration and settings needed by your site to run.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Creating an ASP.NET Web Form


An ASP.NET website is composed of one or more web forms. A web form is a web page where you can add server controls just like a windows form. I will use the term "web form" for the web pages of an ASP.NET website. To create a new web form, right click the Top node of Solution Explorer and choose Add New Item.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Alternatively, you can also click the Add New Item button in the toolbar.

The Add New Item Window will show up. Choose the Web Form template and leave the current name as Default.aspx. Make sure that "Place code in separate file" checkbox is checked. This will create a separate code file for the page. Click the Add button.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Your first ASP.NET web form is created. Note that an ASP.NET page ends with .aspx file extension. You will be presented with an HTML markup which is the code of the page. If you are not familiar with HTML, don't worry, we will have a separate lesson that will teach you the basics of HTML.

You have learned that VWD has a WSIWYG editor. Currently your are seeing the HTML that will tell how your page will look. To get to the WSIWYG editor, click the Design button at the bottom of the editor.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You will then be bought to the WSIWYG which is called the Designer inside VWD.

Adding Server Controls


Currently, the Designer is almost empty because we haven't added some contents yet. You can see a div tag which will hold the contents we will put. It is now time to add some ASP.NET server controls from the Toolbox. You will see the Toolbox as a tab to the left of VWD. Click that tab to expose the Toolbox.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can pin the Toolbox by clicking the pin icon at the upper right of it. Once it is pinned, it will no longer auto hide. The Toolbox contains controls that you can use for your web forms. You can see that there are a bunch of them inside the Toolbox. To add a control from the toolbox to the form, simply drag a control to the designer. Drag a Label control and drop it inside the div tag. Go inside the Div tag and press enter to go to the next line then drag a Button control and drop it to where the cursor is. Your web form should now look like the one below:

Changing the Properties of Server Controls


The server controls have a set of properties that we can change. Click the Label control and go to the Properties Window located at the lower right of the page.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Delete the value of the Text property. The text of the Label control will now be change to its name enclosed with closed brackets because it currently has no default text to show. Click the Button control and change its Text property to "Click Me". Like in Windows Forms, we need to name our controls to be able to interact with them in code. The controls has an Id property which can also be found inside the Properties window. To make it easier to find, click the Alphabetical button of the Properties Window. The Id property will be then become the second entry from above. Change the Id property of the Label to labelMessage and change the Name property of the Button to buttonClickMe.

Ataching an Event Handler to a Control


We want to make the button show a message when we click it. Like Windows Forms, you can attach event handler to a control that will respond to an event. As an example, we will add a Click event handler to the Click event of the button. The simplest way to do that is to double

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

click the button in the designer. You will be then be taken to the code behind of the page (remember that a separate code file was created when you created the web form). The code file contains the C# code that will perform some operations inside a web form. This is also a perfect place to add your event handler. You will notice that the event handler is autmatically created and you have to do is type the code that will be performed when you click the button. Use the code presented below for the Click event handler.
protected void buttonClickMe_Click(object sender, EventArgs e) { labelMessage.Text = "Welcome to ASP.NET!"; }

The code simply sets the Text of labelMessage to "Welcome to ASP.NET".

Runing Your Web Site


We can now see our first web site in action. There are several ways to run your website. The first one is by clicking the Play icon in the toolbar.

Another way is by going to the Debug menu and choosing Start Debugging.

Finally, you can use the shortcut key F5. After doing any of the three ways above. A window will show up telling whether if you want to edit Web.config to enable debugging.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Simply click the OK button and your website will be run using your default browser. You will see the button that we added during the desiging of the page. The Label is not visible because we removed its text. Click the button and it will execute the event handler we created. The message will then be shown to you.

You have seen a basic example of an ASP.NET web site. But real world websites don't have just a label and a button, you will need to learn a lot more concepts in order to create a descent website. But don't worry, I will guide you as you learn the different parts of ASP.NET.

How ASP.NET Works


Before we actually start on creating websites using ASP.NET, you must first know what's happening behind the scenes. In the real world, when you wan't your website to be accessible by the world, you need to host it to a server. When someone with a browser request for a page in your website, they will type the domain name of your website. The domain name is what identifies your site. Every domain name has a mapped IP address. Consider the IP address as the adress of your house. It determines where the server is located. When you are accessing the page, you are typing a URL (Unified Resource Locator). The URL is composed of the protocol to use for communicating to the server, the domain name, and the path in the server's file system where the web page or file to be requested resides. When the user types a URL, he or she expects a web page to be displayed. Web pages are created using the Hypertext Markup Language (HTML). An ASP.NET web page uses HTML but the components it uses such as server controls are not recognizable by a web browser. Therefore, an ASP.NET web page must be compiled first to an HTML page. When the user request a file from the server, the server will choose necessery actions to respond to the request. For static files such as an HTML file, a text file or an image, the server simply

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

sends those file to the browser and then the browser displays it. The case is different for dynamic pages. Dynamic pages are thos which contents are not predetermined and the server needs some sort of processing to generate the output that will be sent to the requester. ASP.NET pages are dynamic pages. An example of this is the page that we created on the previous lesson. When the page is initially sent to us, the message is not visible. When we clicked the button, the code we wrote for that page is executed in the server and it creates a new version of the page which includes the message. ASP.NET pages ends with .aspx extension. Using the concept called Application Mapping or Handler Mapping, an application can be mapped to the .aspx extension. This mapped application is the one that will process the mapped file extension. For .aspx pages, the ASP.NET runtime is used. The ASP.NET runtime is part of the .NET Framework. Based on the details of of an .aspx page such as server controls and programming logic, the ASP.NET runtime can generate the valid HTML that will be sent to and finally viewed by the user that requests it. The server cannot simply just send an unprocessed or raw .aspx page because the browsers cannot recognize the code and server controls of it and they will not be displayed to the user.

Figure 1 As you can see in Figure 1, when the user requests a URL from the browser used by your computer, it locates the server based on the domain name (example.com) which is mapped to an IP address. The IP address is the actual location of the server. Once it finds the server, it searches its files for the file being requested by the user, in the case of Figure 1, welcome.aspx. The server will then check the file extention of the file being requested and through Application Mapping, hands it over to the ASP.NET Runtime. The ASP.NET Runtime executes the C# or .NET code for that page and converts the ASP.NET server controls into valid HTML codes. Once the

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

HTML page has been generated, the server will send the converted page back to the user that requests for that page. Visual Web Developer comes with ASP.NET Development Server which allows you to run websites in your computer without uploading them to a real server. So basically, it makes you local computer the server that the browser will communicate. This is a great tool because deploying your website to a real web server is not free. When you are developing, you can simply just use the development server for testing purposes and then deploy it to a real server once you are ready.

TO BE CONTINUED

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

.NET FRAMEWORK The System.DateTime Class


The System.DateTime class of the .NET Framework allows you to use, store, and manipulate data of time and date. It has methods for manipulating date such as adding or subtracting days, months, or years to the current date and then returning the resulting date. It has some methods to show your date in various formats. The following code demonstrates how you can use the DateTime class to use time and date in your program.
1 using System; 2 3 public class Program 4 { 5 public static void Main() 6 { 7 DateTime newyear = new DateTime(2010, 12, 25); 8 9 Console.WriteLine(newyear.ToString()); 10 } 11} 12/25/2010 12:00:00 AM

We used the constructor which accepts the year, the month, and the date to initialize our DateTime object. We used the ToString () method of the DateTime class to display the date and time. The default ToString() method displays your DateTime object in this format: MM/DD/YYYY HH:MM:SS AM/PM. You will see that you have different methods to modify the formatting of the output. The DateTime method has multiple constructors that you can use. The table below lists some of the most basic ones.
Constructors DateTime() DateTime(int year, int month, int day) DateTime(int year, int month, int day, int hour, int minute, int second) DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond)

Using the default parameterless constructor initializes the date to 01/01/0001 12:00:00 AM. To obtain the current date and time, you can use the Now static property of the DateTime class. To just get the current date, you can use the Today property.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

DateTime now = DateTime.Now; DateTime today = DateTime.Today;

To modify how your DateTime object will be presented, you can use several formatting methods available.
Method Sample Output

ToLongDateString() Saturday, Octoboer 2, 2010 ToLongTimeString() 4:14:18 PM ToShortDateString() 10/2/2010 ToShortTimeString() 4:14 PM

You can even use the String.Format method to have a customized formatting.
Specifier dd ddd dddd f, ff, ... gg, ... hh HH mm MM MMM Day Day name Full Day Name Second Fractions Era 2 digit hour 2 digit hour, 24hr format Minute 00-59 Month 01-12 Type Example {0:dd} {0:ddd} {0:ddd} {0:fff} {0:gg} {0:hh} {0:HH} {0:mm} {0:MM} Output 10 Tue Tuesday 932 A.D. 10 22 38 12 Dec December

Month abbreviation {0:MMM} {0:MMMM}

MMMM Full month name

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Specifier ss tt yy yyyy zz

Type Seconds 00-59 AM or PM Year, 2 digits Year Timezone offset, 2 digits Full timezone offset Seperator Seperator

Example {0:ss} {0:tt} {0:yy} {0:yyyy} {0:zz}

Output 46 PM 02 2002 -05

zzz : /

{0:zzz} {0:hh:mm:ss}

-05:00 10:43:20

{0:dd/MM/yyyy} 10/2/2010

For example:
Console.WriteLine("The current date is {0:dd/MM/yyy}", DateTime.Now); The current date is 10/2/2010

DateTime Methods

The DateTime class provides some methods that deals with date and time data. Some of these methods are listed in the table below.
Method AddDays AddHours AddMilliseconds AddMinutes AddMonths AddSeconds Adds an amount of time to the value of the DateTime object. Accepts a double argument which indicates the amount of time to add. Use negative value to subtract time instead. Description

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Method AddTicks AddYears Equals

Description

Checks whether that DateTime object is equal to the DateTime argument passed to the method. Check whether the instance of the DateTime is within the Daylight Saving Time range for the current time zone. Converts the value of the DateTime instance to Coordinated Universal Time (UTC) Static. Returns the number of days of the specified month and year. Static. Tells whether the specified year is a leap year.

IsDaylightSavingTime

ToUniversalTime

DaysInMonth

IsLeapYear

Some of the properties of the DateTime class is listed below.


Property Date Day DayOfWeek DayOfYear Hour Millisecond Minute Description Returns the date component. Returns the day of the month. Returns the day of the week. Returns the day of the year. Returns the hour component. Returns the milliseconds component. Returns the minute component.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Property Month Second TimeOfDay Year Now Today UtcNow

Description Returns the month component. Returns the second component. Returns the current time of the day. Returns the year component. Static. Returns the current date and time. Static. Returns the current date only. Static. Returns the current date and time in UTC.

Let's take a look at another examples that demonstrate the use of certain methods and properties of the DateTime class.
using System; 1 2 public class Program 3 { 4 public static void Main() 5 { 6 DateTime myDate = DateTime.Now; 7 8 Console.WriteLine("Year: " + myDate.Year); 9 Console.WriteLine("Month: " + myDate.Month); 10 Console.WriteLine("Day: " + myDate.Day); 11 Console.WriteLine("Today is {0}.", myDate.DayOfWeek.ToString()); 12 13 //Assign newDate with the current date added by 3 days 14 DateTime newDate = myDate.AddDays(3); 15 Console.WriteLine("The date 3 days from now is {0}.", 16 newDate.ToShortDateString()); 17 18 //Assign newdate with the current date subtracted by 3 days 19 newDate = myDate.AddDays(-3); 20 Console.WriteLine("The date 3 days ago is {0}.", 21 newDate.ToShortDateString()); 22 } 23 } Year: 2010 Month: 10 Day: 3 Today is Sunday. The date 3 days from now is 10/6/2010. The date 3 days ago is 9/30/2010.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We used the properties of the DateTime class to display the seperate components of the date. We then demonstrate how we can modify a date by adding and subtracting days to the value of our DateTime object. Notice that we used a negative number when we subtracted 3 days. We also used the ToShortDateString() method to display a short form of the date.

Date Difference Calculator


This tutorial guides you through the creation of a Time Difference Calculator which determines the difference of two given dates and returns the result in days. The program uses the System.DateTime and System.TimeSpan methods. This tutorial will also practice your skills on using events and the ComboBox control. Create a new Windows Forms application and name it TimeDifferenceCalculator. Then add and arrange controls until it looks like the one seen below:

Optionally change the Text property of the form and the FormBorderStyle to FixedSingle to disable resizing. Change the Name property of the following numbered controls.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Number Name 1 comboBeginDateMonth 2 comboBeginDateDay 3 comboBeginDateYear 4 comboEndDateMonth 5 comboEndDateDay 6 comboEndDateYear 7 labelResult 8 buttonCalculate Empty the Text property of labelResult as it will be filled by the result once the calculation has been completed. Double click the Form (not the controls) to create an event handler for the Load event of the form. Add the code show below.
private void Form1_Load(object sender, EventArgs e) { //Define the months string[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; //Fill up the month combo boxes for (int i = 0; i < 12; i++) { comboBeginDateMonth.Items.Add(months[i]); comboEndDateMonth.Items.Add(months[i]); } //Set January as default month

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

comboBeginDateMonth.SelectedIndex = 0; comboEndDateMonth.SelectedIndex = 0; //Fill up the year combo boxes for (int i = 1; i <= DateTime.Now.Year; i++) { comboBeginDateYear.Items.Add(String.Format("{0:0000}", i)); comboEndDateYear.Items.Add(String.Format("{0:0000}", i)); } //Set default year to 2000 comboBeginDateYear.SelectedIndex = 1999; comboEndDateYear.SelectedIndex = 1999; //Fill up the day combo boxes FillDays(comboBeginDateDay, "Begin"); FillDays(comboEndDateDay, "End"); //Attach event handlers comboBeginDateMonth.SelectedIndexChanged += new EventHandler(RecalculateDays); comboBeginDateYear.SelectedIndexChanged += new EventHandler(RecalculateDays); comboEndDateMonth.SelectedIndexChanged += new EventHandler(RecalculateDays); comboEndDateYear.SelectedIndexChanged += new EventHandler(RecalculateDays); }

Figure 1 The first thing we did is create a string array containing the 12 months. We then used a for loop to add the months to the two combo boxes that represents the month. We used the Add method of the Item property of the ComboBox class to do just that. We then set the SelectedIndex property of the two combo boxes to 0 so that it will point to the first item which is January. It is important to note that the indexes in a combo box is base 0 so the counting will start at 0. We then fill up the year combo boxes with years ranging from 1 to the current year. We retrieve the current year through the Year property of the Now property of the DateTime class. The Now property represents the current date and time. We added each year to the two combo boxes representing the year. We also formatted each year to have leading zeros so each year will always have 4 digits. We set the default year to 2000 by giving the value 1999 to the SelectedIndex property of each year combo box. Remember that the SelectedIndex is 0-based so index 1999 represents 2000. Note that we can use the String Collection Editor by switching to the Designer View, clicking the desired combo box, and searching for the Items property. Click the button with three dots and you will arrive at the editor where you can just type each item for the combo box. But doing this would be tedious as you need to type all 2000(or more) values. That's why it is more efficient to add the values using code if there are too many items.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The FillDays method that we will create later, fills the combo boxes that represent the day, with the right number of days because not all months have the same number of days and we also need to consider leap years. The last 4 lines of code attaches an event handler to the SelectedIndexChanged event of each combo box. This event will trigger if the selected index or item is changed. We will create this one event handler that will be shared by the four controls. We need to add this event handler to the month combo boxes and the year combo boxes so that once the user changes the year or the month, then the items inside the day combo boxes will be automatically upated. I decided to add the event handlers in the last part because we change the SelectedIndex property of the comboBoxes so doing that will trigger the event and execute the event handler which will process the previously empty combo boxes. That will produce an error. Let's now create the FillDays method. This method fills the right number of days to the specified combo box. This method will accept a ComboBox as an argument and a second parameter that accepts a string indicating whether to update the comboBeginDateDay or the comboEndDataDay combo box.
private void FillDays(ComboBox comboBox, string tag) { int selectedMonth; int selectedYear; if (tag == "Begin") { selectedMonth = comboBeginDateMonth.SelectedIndex + 1; selectedYear = comboBeginDateYear.SelectedIndex + 1; } else { selectedMonth = comboEndDateMonth.SelectedIndex + 1; selectedYear = comboEndDateYear.SelectedIndex + 1; } int maxDay = DateTime.DaysInMonth(selectedYear, selectedMonth); comboBox.Items.Clear(); for (int i = 1; i <= maxDay; i++) { comboBox.Items.Add(i); } comboBox.SelectedIndex = 0; }

Figure 2 First, we identify which month and year combo boxes to get values from by testing it to the tag parameter. We then assigned the selected indexes plus 1 to variables that will be used by the

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

DaysInMonth method. We then use the DaysInMonth static method of the DateTime class to check the number of days of the specified month of the specified year. We cleared the items of the combo box to update. We update the number of days be readding the days using a for loop. Finally, we set the SelectedIndex of the referenced combo box to 0 so it will have a default value of 1. Find the Form1 constructor and add the highlighted code.
public Form1() { InitializeComponent(); comboBeginDateMonth.Tag = "Begin"; comboBeginDateYear.Tag = "Begin"; comboEndDateMonth.Tag = "End"; comboEndDateYear.Tag = "End"; }

We added those values to the Tag properties so that the following method, RecalculateDays, can determine the right combo box to update.
private void RecalculateDays(object sender, EventArgs e) { if ((sender as ComboBox).Tag.ToString() == "Begin") FillDays(comboBeginDateDay, "Begin"); else FillDays(comboEndDateDay, "End"); }

Note that this method serves as event handler to the SelectedIndex event which expects a method that matches it's delegate, EventHandler, that accepts an object and an EventArgs object. The method contains an if statement. We first convert the sender which is the control that triggered the event, to a ComboBox then use the Tag property and converted it to string. We then compare the result to the string "Begin" so that the program will determine which combo box to update. Go back to Designer View and double click buttonCalculate to create a Click event handler. Add the following code.
private void buttonCalculate_Click(object sender, EventArgs e) { DateTime beginDate = new DateTime( comboBeginDateYear.SelectedIndex + 1, comboBeginDateMonth.SelectedIndex + 1, comboBeginDateDay.SelectedIndex + 1); DateTime endDate = new DateTime( comboEndDateYear.SelectedIndex + 1, comboEndDateMonth.SelectedIndex + 1, comboEndDateDay.SelectedIndex + 1); TimeSpan difference = endDate.Subtract(beginDate);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

labelResult.Text = String.Format("{0} Days", difference.Days); }

Once the button is clicked, the begin and end dates are created based on their respective set of combo boxes. We then calculate the difference by using the Subtract method. This method returns a TimeSpan object. Finally, we show the difference of the two dates in days to labelResult. More upgrades can be done to this program. For example, you can add more combo boxes for the hours, minutes, and seconds. You can also show the difference in years and months (although you need to take into account leap years). You can use the IsLeapYear method to determine if the specified year is a leap year. Download the source code here.

The System.Math Class


You can use the System.Math class to perform certain mathematical calculations. You can use its method to round numbers, get the square root of a certain number, or determine the result of x raised to a certain number. The System.Math class is a static class so you don't have to make an instance of it to use its methods. Let's demonstrate some of the methods of System.Math class.

Rounding Numbers
You can round a floating point number to a certain precision using the Math.Ceiling and Math.Floor methods. The Math.Ceiling method returns a double value and accepts a double argument which is the value to be rounded. The result will be the smallest whole value that is greater than or equal to the specified argument given. The Math.Floor rounds a double number to the smallest whole number whose value is less than or equal the given argument. The two methods are demonstrated below:
double number = 34.567; double ceil = Math.Ceiling(number); double floor = Math.Floor(number); Console.WriteLine("Math.Ceiling({0}) = {1}", number, ceil); Console.WriteLine("Math.Floor({0}) = {1}", number, floor); Math.Ceiling(34.567) = 35 Math.Floor(34.567) = 34

If you want to round a number to a number with a specific number of decimal places, you can use the Math.Round method.
//Round 3.31674 into 2 decimal places double number = 3.31674 Console.WriteLine(Math.Round(number, 2)); 3.32

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Raising a Number to a Certain Power


You can raise a number to a specified power using the Math.Pow method. The Math.Pow is a simple method that accepts two double arguments, the first one is the base, and the other one is the exponent. It returns the answer as a double. The code below demonstrates how to use this method.
for (int i = 0; i < 10; i++) { Console.WriteLine("2^{0} = {1}", i, Math.Pow(2, i)); } 2^0 = 1 2^1 = 2 2^2 = 4 2^3 = 8 2^4 = 16 2^5 = 32 2^6 = 64 2^7 = 128 2^8 = 256 2^9 = 512

Getting the Square Root of a Number


If you want to get the square root of a number, you can use the Math.Sqrt method. The method accepts one argument which is the value the we want to find the square root of. The method returns a double value.
Console.WriteLine(Math.Sqrt(25)); 5

Finding the Minimum and Maximum Numbers


The System.Math class provides you with Math.Min and Math.Max to find the smallest and largest value. Both methods can accept two arguments of any numerical data type. So by default, you can only give 2 numbers that will be used by comparison.
Console.WriteLine(Math.Min(1,2)); Console.WriteLine(Math.Max(1,2)); 1 2

As a work around for those methods limiting you to 2 numbers, you can nest the call for the methods like this:
//Get the maximum and minimum of 3 numbers int max = Math.Max(Math.Max(1, 2), 3); int min = Math.Min(Math.Min(1, 2), 3); Console.WriteLine("Max = {0}", max); Console.WriteLine("Min = {0}", min);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Max = 3 Min = 1

We can even create a function that will get the maximum and minimum numbers of any number of values.
static int GetMax(int[] numbers) { int maximum = numbers[0]; for (int i = 1; i < numbers.Length; i++) { maximum = Math.Max(maximum, numbers[i]); } return maximum; } static int GetMin(int[] numbers) { int minimum = numbers[0]; for (int i = 1; i < numbers.Length; i++) { minimum = Math.Min(minimum, numbers[i]); } return minimum; } static void Main() { int[] numbers = { 32, 17, 45, 10, 5 }; int max = GetMax(numbers); int min = GetMin(numbers); Console.WriteLine(max); Console.WriteLine(min); } 45 5

The GetMax and GetMin functions accepts an integer array. It can accept any number of integer values. Inside the functions, we assumed that the first value in the array are the maximum and minimum values. We then enter a for loop which starts at index 1. It uses the Math.Min and Math.Max methods to determine if the current element in the loop is larger than the current value of maximum or is smaller than the current value of minimum. If so, the current value replaces the value of the maximum or minimum variable. We then return the resulting values.

Math.PI
System.Math provides a constant value PI which you can use when in certain cases such as finding the area of a circle. The area of the circle is defined as r2 where is the pi, and r is the radius of the circle. To calculate the area, use the following code.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

double area = Math.PI * Math.Pow(radius, 2);

There are more methods available inside System.Math. For a complete reference of those methods, you can proceed the following link: http://msdn.microsoft.com/en-us/library/system.math.aspx

Random Number Generation


We use the System.Random class to generate random numbers. The Random class provides method for generating random numbers. Each number has an equal chance of getting picked. We use the Next method to generate a non-negative random number as seen in the following code:
Random generator = new Random(); //Generate 10 random numbers for (int i = 1; i <= 10; i++) { Console.WriteLine(generator.Next()); } 673131583 2075827769 530790962 853400196 1181061071 1657679493 1459501829 452543008 1814178911 1933670708

Your output will surely be different because each numbers are random. Another version of the Next method allows you to specify the maximum number that can be generated. For example, what if you want to only generate numbers not greater than 10.
Random generator = new Random(); //Generate 10 random numbers for (int i = 1; i <= 10; i++) { Console.WriteLine(generator.Next(11)); } 2 3 4 4 10 4 1 1 0 8

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Next method accepts an argument which is the exclusive maximum number. Meaning, that the method will return a random value which is less than (but not equal) to the given argument. The possible values are from 0 to 10. We can also specify the range of numbers that the Next method can return. For example, if you want to generate numbers from 1 to 6 such as the faces of dice, you can modify the code like this:
Console.WriteLine(generator.Next(1, 7)); //Returns random value from 1 to 6

The first argument is the inclusive minimum number and the second argument specifies the exclusive maximum number that the method can return. You can also use a seed value so that the program will generate the exact sequence of random number. You can use any numerical seed value. To specify a seed, use the other constructor of Random that accepts a seed as an argument.
Random generator = new Random(0); //Generate 10 random numbers for (int i = 1; i <= 10; i++) { Console.WriteLine(generator.Next(11)); } 7 8 8 6 2 6 9 4 10 3

Run the program multiple times and you will obtain the same sequence of random numbers. Let's now apply what we have learn to a simple program. This program shows you a different message everytime you run it.
using System; namespace RandomMessage { class Program { static void Main() { Random generator = new Random(); int messageNumber = generator.Next(1, 4);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

switch (messageNumber) { case 1: Console.WriteLine("Hello to you my friend."); break; case 2: Console.WriteLine("Good day to you sir/mam."); break; case 3: Console.WriteLine("Have a happy day."); break; } } } }

The program generates a value from 1 to 3. We then use a switch statement to show a message for each of the possible values. Try running the program several times and you will notice that the welcome message changes.

Strings and Regular Expressions


String is the most common data type found in almost any programming languages. A string is a group of characters such as letters, numbers or symbols. It is declared using the string keyword. Strings are very important if we want to store different kinds of information such as our name, address, gender, or email. We use strings to prompt user with information or alert them with error messages. Also, with the help of regular expression in C#, we can create patterns that much specific strings. Regular expressions are typically used in validation of information. The upcoming lessons shows you different characteritics of a string and the methods you can use to manipulate it.

System.String Class
The string in C# is handled by the System.String class. Before you can create and use strings, you must import the System namespace. There are multiple ways to create a string.
String str1; str1 = "An example of a string.";

Notice that a string is enclosed in double quotation marks ("). This indicates to the compiler that the data you are storing to the variable is a string. The System.String class is mapped to the string keyword thanks to CTS. This allows you to use the keyword string, instead of the class System.String when creating a string.
string myString; myString = "An example of a string.";

You can declare a string and assign it a value in one statement, like this:
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

string myString = "This is another string";

You can also use the new keyword and the System.String constructor to assign value to the string.
String myString = new String("This is a string."); string myString = new string("This is a string");

In .NET, a string is a reference type but behaves very much like a value type. Consider the following example of a typical reference type:
Button btn1 = new Button(); btn1.Text = "Button 1 "; Button btn2 = btn1; // Assign address of btn1 to btn2 btn2.Text += " and Button 2"; Console.WriteLine(btn1.Text); Console.WriteLine(btn2.Text); Button 1 and Button 2 Button 1 and Button 2

We created a Button named btn1 and assign the Text property with a string. Next, we assigned the reference of btn1 to another Button named btn2. They are now referring to the same button. We now modify the Text property of btn2 by concatenating (combining) another string. Note that btn2.Text contains the Text from btn1 because they are referring to the same button. After the modification, we output the contains of the Text for each button. The result is the same. The moment that we modified the Text of btn2, the Text of btn1 was modified as well. (It is evident in the output of the WriteLine() statements). If strings are indeed reference types, then the same behavior can be expected with the following code:
string str1 = "String 1"; string str2 = str1;

Now, str1 and str2 should now be pointing to the same instance. If we modify the the value of str2, then str1 should be modified as well.
str2 += " and String 2";

Let's print the values of the strings.


Console.WriteLine(str1); Console.WriteLine(str2); String 1 String 1 and String 2.

You can see that the values are different. The value of str1 was coppied to str2. They do not point on the same instance. Therefore, changes you make with str2 will not reflect to str1. A string can't be a value type because it can handle a value an unpredictable length of characters.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

A string is basically a collection of unicode characters. The following code shows this by splitting each character using a foreach loop.
string str1 = "This is a string"; foreach (char c in str1) { Console.WriteLine(c); } T h i s i s a s t r i n g

In fact, another version of the System.String's constructor accepts a character array.


char[] charArray = { 'H', 'e', 'l', 'l', 'o' }; String myString = new String(charArray);

The next lesson shows you how to compare strings and demonstrates a simple example of sorting strings.

Comparing Strings
We can compare two strings for equality using several ways. For example, we can use the == operator to test if the two strings are equal. The == operator doesn't compare their references, but their values even though strings are reference types.
string str1 = "Hello"; string str2 = "Hello"; string str3 = "Goodbye"; Console.WriteLine("str1 == str2 : {0}", str1 == str2); Console.WriteLine("str1 == str3 : {0}", str1 == str3); str1 == str2 : True str1 == str3 : False

Alternatively, you can use the String.Compare static method to compare two strings. The following code demonstrates this.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

if (String.Compare(str1, str2) == 0) { Console.WriteLine("str1 is equal to str2"); }

The String.Compare method accepts two strings and returns 0 if the strings are the same, returns 1 if the value of the first string is greater than the second, and -1 if the value of the first string is less than the second string. So to determine if the strings are equal using the Compare method, you must test if the value returend is equal to 0 as seen in the code above. How do you determine if a string is greater or less than the other. Each character of the strings are converted into their unicode equivalent. The first character of the first string is compared to the first character of the second string. If they are equal, it will compare the second characters and so on . Another overloaded version of String.Compare accepts a third boolean argument which determines if the comparison will ignore case sensitivity. By default, String.Compare respects casing and treats two strings with different casings as different strings. The following shows how you can compare strings while ignoring case sensitivity.
string str1 = "Microsoft"; string str2 = "microsoft"; if (String.Compare(str1, str2, true)) { Console.WriteLine("The strings are equal."); } The strings are equal.

There are more overloads for the String.Compare method as listed below. Method Compare(String, String) Compare(String, String, Boolean) Compare(String, String, StringComparison) Compare(String, String, Boolean, CultureInfo) Compare(String, Int32, String, Int32, Int32) Compare(String, Int32, String, Int32, Int32, Boolean) Compare(String, Int32, String, Int32, Int32, StringComparison)
COMPILED BY:

Description Compares two specified String objects. Compares two specified String objects, ignoring or respecting their case. Compares two specified String objects. Also specifies whether the comparison uses the current or invariant culture, honors or respects case, and uses word or ordinal sort values. Compares two specified String objects, ignoring or respecting their case, and using culture-specific information for the comparision. Compares substrings of two specified String objects. Compares substrings of two specified String objects, ignoring or respecting their case. Compares substrings of two specified String objects.

Bsc ABDULRAHIM ALI ATHUMAN

Method Compare(String, Int32, String, Int32, Int32, Boolean, CultureInfo) Figure 1

Description Compares substrings of two specified String objects, ignoring or respecting their case, and using culture-specific information for the comparision.

Alternatively, you can use the CompareTo instance method. The following shows you how to use this method.
string str1 = "Hello"; string str2 = "Hello"; if (str1.CompareTo(str2) == 0) { Console.WriteLine("The strings are equal."); } The strings are equal.

The CompareTo method returns an integer. Like the Compare method, If the strings are equal, it will return 0, if the string being compared is greater than the string, it will return 1, and if it is less than the comparison string, it will return -1.

Concatenating Strings
There are several ways of concatenating strings. Concatenating simply means combining multiple strings into one. In C#, the simplest way to concatenate strings is by using the + operator as shown below.
string str1 = "Happy "; string str2 = "New Year"; string result = str1 + str2; Console.WriteLine(result); Happy New Year

You can see that the effect of using the + operator on two string operands combines them. Also note that if you are using the + operator when combining a string into another data type such as int, the int is automatically converted into string.
Console.WriteLine("Number of Guests: " + 100); Number of Guests: 100

Another way of concatenating strings is by using the String.Concat static method. You can pass an infinite number of string or object arguments to this method. The program below shows you how to use this method.
string result = String.Concat("We have ", 100, " guests ", " this evening.");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Console.WriteLine(result); We have 100 guests this evening.

You can also use the String.Join static method. It is used to combine strings stored inside a string array.
string[] words = { "Welcome", "to", "my", "site." }; string result = String.Join(" ", words); Console.WriteLine(result);

The String.Join method accepts two arguments, the first is the string that will be inserted between each of the strings being combined. We passed a " " to put space between the words. The second argument is the string array itself. Another overload of String.Join allows you to pass a list of strings instead of a string array.
string result = String.Join(" ", "Welcome", "to", "my", "site."); Console.WriteLine(result);

Combining large strings using System.String could affect performance. In .NET, all string objects are immutable. This means that once a string variable is initialized, its value cannot be changed. When you modify the value of a string, a new copy of the string is created and the old copy is discarded. Hence, all methods that process strings return a copy of the modified string the original string remains intact. .NET provides the StringBuilder class that you can use when combining large strings. It will discussed in another lesson.

Inserting Strings
.NET provides you with the Insert instance method that allows you to insert strings into existing strings. For example, If you have a string "Hello World!", you can insert the string "Happy " in the middle to make it "Hello Happy World!". The following code demonstrates how to use the Insert method.
string str1 = "Hello World!"; string str2 = "Happy "; string result = str1.Insert(6, str2); Console.WriteLine(result); Hello Happy World!

The Insert method accepts two arguments, the first one is the position to where the string will be inserted, and the second one will be the string to be inserted. The position of the string starts with 0 and ends with length - 1. In the string "Hello World!", we want to insert our new string right after the first space and that would be the position of W as demonstrated below.
H 0 e 1 l 2 l 3 o 4 5 W 6 o 7 r 8 l 9 d 10 ! 11

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The string "Happy " will now be inserted in that position. Everything after that will be pushed forward. The string "Hello Happy World!" is then produced.

Adding Padding to Strings


We can also use the PadLeft and PadRight methods to add padding to the left and right of the string. For example, let say you want to add a series of space to the left of a string for alignment purposes, you can use the PadLeft method.
string str1 = "Example"; str1 = str1.PadLeft(10); Console.WriteLine(str1); Example

The PadLeft and PadRight methods accept an argument which will determine the padding to be inserted. As you may have notice, we passed 10 but the padding doesn't seem to be that long. It only added 3 spaces to the left. To determine the amount of padding, we use the formula (length - padding). The length is the length of the string and the padding is the argument passed to the method. Since the string "Example" has a length of 7 and we passed 10 as the padding, then 10 7 = 3 which explains why only have 3 spaces inserted. If we use a padding value which is less than the length, then no padding will be added. We can also see that PadRight also follows the same formula.
string str1 = "Example"; str1 = str1.PadRight(10); Console.WriteLine(str1 + "|"); Example |

Note that we added the "|" character to demonstrate the padding that was added to the right of the string. Another version of PadLeft and PadRight accepts a second argument which is the character that will be used as padding. Consider the following example.
string str1 = "Example"; str1 = str1.PadLeft(10, '*'); Console.WriteLine(str1); ***Example

Adding paddings are useful when you want to output data in tabular format. Consider the following example.
string[,] data = { { { { { "Name", "John", "Mark", "Jean", "Gender", "Age" }, "Male", "21" }, "Male", "18" }, "Female", "18" } };

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

for (int i = 0; i < data.GetLength(0); i++) { for (int j = 0; j < data.GetLength(1); j++) { Console.Write(data[i, j].PadRight(10)); } Console.WriteLine(); } Name John Mark Jean Gender Male Male Female Age 21 18 18

We used a multidimensional string array to store our data. The first row of data is the headers. We then used nested for loops to print the data.

Trimming Strings
Sometimes, a user types unnecessary spaces that my cause certain errors. When accepting strings from a user, especially if the input came from a text box or similar controls, have a habit of trimming them first. .NET provides the Trim, TrimStart, and TrimEnd instance methods. TrimStart simply trims unnecessary whitespaces in the beginning, TrimEnd at the end, and Trim on both sides of the string.
string str1 = " Example str1 = str1.Trim(); Console.WriteLine(str1); Example ";

The Trim methods has an overloaded version that accepts an array of characters that you want to remove in a string. The example below demonstrates this.
string str1 = "&&&&Hello***"; str1 = str1.Trim("&*".ToCharArray()); Console.WriteLine(str1); Hello

Our string has "garbage" characters in the beginning and end of the string. We passed the these garbage characters in our Trim method to remove them. Notice also that we use the ToCharArray method. The Trim method accepts a char array, and we passed a string, so to fulfill the requirements, we convert the string to character array by using the said method.

Splitting Strings
If you want to split a string into multiples strings, you can use the Split method. Let's take a look at the different overloads of the Split method. The Split method returns a string array that

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

contains the substrings inside each of its elements. The first one accepts an array of character which are the delimiters that will determine where to split each substring.
string message = "The quick brown fox jumps over the lazy dog."; string[] substrings = message.Split(' '); foreach (string s in substrings) { Console.WriteLine(s); } The quick brown fox jumps over the lazy dog.

We used the ' ' character to seperate each words in the sentence since each words are seperated by spaces. The words were stored in the substrings array. We then printed each word in seperate lines by using a foreach statement. You can limit the number of substrings to return by using another overload of Split.
string message = "The quick brown fox jumps over the lazy dog."; string[] substrings = message.Split(" ".ToCharArray(), 3); foreach (string s in substrings) { Console.WriteLine(s); } The quick brown fox jumps over the lazy dog.

The second argument determines the maximum number of substrings. The output shows that it properly seperated the first two words, and the remaining of the string was stored in the final element of the array. Another overload uses the enumeration StringSplitOptions. This enumeration contains 2 values, None and RemoveEmptyEntries. By passing StringSplitOptions.None, you can have an empty substring in the result array. Using StringSplitOptions.RemoveEmptyEntries removes substrings that are empty. This is demonstrated by the following codes.
string message = "string1#string2##string4#string5"; string[] results = message.Split("#".ToCharArray(), StringSplitOptions.None); foreach (string s in results) { Console.WriteLine(s);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

} string1 string2 string4 string5

The overloaded Split method accepts a character array as the first argument that's why we used the ToCharArray() method. We used the "#" as the delimeter for the substrings.The second argument is the StringSplitOption value. We passed None, so even if the substring is empty, as demonstrated by the third substring, it will still be included in the results. Let's try using the RemoveEmptyEntries value.
string message = "string1#string2##string4#string5"; string[] results = message.Split("#".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); foreach (string s in results) { Console.WriteLine(s); } string1 string2 string44string5

As you can see, the final results didn't include the empty third substring. This technique is often used when storing data in a textfile. Often, data in stored in a text file seperates each field by using a delimeter such as "#". .NET can extract the string in a textfile, store it in a string and then use the Split method to process the each of the data.

Searching Strings
Searching strings have been made easy thanks to the different methods provided by .NET. Let's take a look at the different methods to find the occurrence of a praticular string. The IndexOf and LastIndexOf methods find the the index or position of a particular string if it exists in another string. If the given string is not found, the methods will return -1. The example below shows how to use the IndexOf method.
string str = "The quick brown fox jumps over the lazy dog."; int index = str.IndexOf("quick"); Console.WriteLine(str); Console.WriteLine("quick was found at position " + index); The quick brown fox jumps over the lazy dog. quick was found at position 4

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

IndexOf accepts a string which is what you are trying to find. In the example above, the method returns 4 becuase the first occurrence of the word "quick" starts at index 4. Remember that indexes/positions starts with 0 to length - 1 so the fifth character is at position 4. Let's look at the difference of LastIndexOf by looking at an example.
string str = "A very very very good day."; int index = str.LastIndexOf("very"); Console.WriteLine(str); Console.WriteLine("Last occurrence of very was found at position " + index); A very very very good day. Last occurrence of very was found at position 12

LastIndexOf is similar the IndexOf except that it finds that index of the last occurrence of the string. In the example above, the last occurrence of the word "very" was found at index 12. Let's demonstrate that if a particular search string is not found, the methods will return -1.
string str1 = "This is a sample string."; Console.WriteLine(str1); if (str1.IndexOf("Whatever") == -1) { Console.WriteLine("\"Whatever\" was not found in the string."); } This is a sample string. "Whatever" was not found in the string.

Another overloaded version of the methods accepts a second argument that detemines where to start searching the search string. This is demonstrated by the code below.
string str1 = "This is a sample string."; Console.WriteLine(str1); if (str1.IndexOf("This", 5) == -1) { Console.WriteLine("\"This\" was not found in the string."); }

You can see that the word "This" is actually in the sentence but we indicated to start at index 5 when searching the word therefore, the word was not found. If you want to find all the index for every occurrences of a word you can create a loop like this:
int position = 0; string str1 = "This is a long long long string..."; do { position = str1.IndexOf("long", position);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

if (position != -1) Console.WriteLine(position); position++; } while (position > 0); 10 15 20

The Contains method can also be used to check if the string exists in another string.
string str1 = "This is a sample string."; Console.WriteLine(str1); if (str1.Contains("sample")) { Console.WriteLine("\"sample\" exists in the string."); } This is a sample string. "sample" exist in the string.

The Contains method returns true if the search string does exist, and false if it does not. Another pair of methods, StartsWith() and EndsWith() are used to find if a string begins or ends with a particular string.
string str1 = "Apple"; Console.WriteLine(str1); if (str1.StartsWith("A")) { Console.WriteLine("The word starts with A."); } if (str1.EndsWith("e")) { Console.WriteLine("The word ends with e."); } Apple The word starts with A. The word ends with e.

Extracting, Removing and Replacing Strings


If you want to extract a part of a string, you can use the Substring() method. The Substring() method accepts two arguments, the start index and the length of the string to extract. The following program shows you this.
string str1 = "This is a sample string."; //Extract sample

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

string str2 = str1.Substring(10, 6); Console.WriteLine("str1 = {0}", str1); Console.WriteLine("str2 = {0}", str2); str1 = This is a sample string. str2 = sample

We started the extraction at index 10. You can see that "sample" starts at index 10 (11th character). The length will determine how many characters will be extracted. Since we provided six as the length, 6 characters was extracted including the character at the start index. If you don't want to count manually the position of the "sample", you can use the IndexOf method.
string str2 = str1.Substring(str1.IndexOf("sample"), 6);

Another overload of the Substirng method accepts only one argument which is the start index. It starts the extraction from the start index until the end of the string.

Removing Strings
To remove strings, you can use the Remove method. It's parameters are the same as the Substring method.
string str1 = "This is a sample string."; Console.WriteLine(str1); Console.WriteLine("Removing \"sample\"..."); str1 = str1.Remove(10, 7); Console.WriteLine(str1); This is a sample string. Removing "sample "... This is a string.

Another overload of the Remove method accepts one argument which is the start index. Everything will be removed from the start index to the end of the string.

Replacing Strings
You can use the Replace method to replace all occurrences of a string with another string. For example, you can change all occurrences of "dog" with "cat".
string str1 = "That dog is a lovely dog."; Console.WriteLine(str1); Console.WriteLine("Replacing all dogs with cats..."); str1 = str1.Replace("dog", "cat"); Console.WriteLine(str1); That dog is a lovely dog. Replacing all dogs with cats... That cat is a lovely cat.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Replace method accepts two arguments. The first one is the string to be replaced and the second one is the replacement string. The Replace method searches for all occurences of the word "dog" then replaced it with the word "cat". You can also use the Replace method to remove all occurances of a string.
string str1 = "That dog is a lovely dog."; Console.WriteLine(str1); Console.WriteLine("Removing all dogs..."); str1 = str1.Replace("dog", String.Empty); Console.WriteLine(str1); That dog is a lovely dog. Removing the dogs... That is a lovely .

The code above uses String.Empty as the replacement string. String.Empty is equal to "" which means empty string. So every occurances of the string being replace was emptied thus removing them from the actual string.

Changing the Casing of Strings


You can change the casing of a string. For example, a string composing of lowercase letters can be transformed into all caps. We use the ToUpper() and ToLower() instance methods which returns an uppercase or lowercase version of the string.
string lowercase = "abc"; string uppercase = "ABC"; Console.WriteLine("lowercase.ToUpper() = " + lowercase.ToUpper()); Console.WriteLine("uppercase.ToLower() = " + uppercase.ToLower()); lowercase.ToUpper() = ABC uppercase.ToLower() = abc

Note that if a string has different cases, such as a sentence where the first character is in uppercase and the rest is in lowercase, then using ToUpper() only changes the case of the characters in lowercase and does not affect the ones which are already in uppercase. Same goes with the ToLower() method. Let's apply what we have learned by creating a function that converts a sentence into Title Case, that is, every word starts with a capital letter. The following program uses some of the string manipulation methods we have learned so far.
class Program { static string ToTitleCase(string str) { string[] words = str.Split(' '); for(int i = 0; i < words.Length; i++) {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

string firstLetter = words[i].Substring(0, 1); string rest = words[i].Substring(1); string result = firstLetter.ToUpper() + rest.ToLower(); words[i] = result; } return String.Join(" ", words); } static void Main() { string input; Console.WriteLine("Enter a string: "); input = Console.ReadLine(); Console.WriteLine("Converting to Title Case..."); input = ToTitleCase(input); Console.WriteLine(input); } } Enter a string: tHe quICK bROwN fOx Converting to Title Case... The Quick Brown Fox

We created a function named ToTitleCase which accepts one string argument which is the string that will be modified.
string[] words = str.Split(' ');

We first split the strings into multiple words so we can manipulate each word. We then enter a for loop to loop through all the words.
string firstLetter = words[i].Substring(0, 1); string rest = words[i].Substring(1);

We then extract the first letter of the word and put it in a variable for later use. We also extract the rest of the letters of the word.
string result = firstLetter.ToUpper() + rest.ToLower();

We combine the extracted strings but we used the ToUpper for the first letter and ToLower for the rest of the word. After that, we replaced the content of the current element of the array with the modified word.
return String.Join(" ", words);

Now, we combine the modified words and put spaces between the words. We then return it to the caller.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

String Formatting
.NET provides you with ways to format the output of strings. You can use the String.Format to format your strings using different format specifiers.
string str1 = "This"; string str2 = "That"; string str3 = String.Format("{0} and {1}", "This", "That"); Console.WriteLine(str3); This and That

The String.Format method accepts the string containing the format specifiers ({0},{1} and so on), and the following arguments are the strings that will be formatted by those format specifiers. The compier looks at the numbers in the format specifier, takes the argument with the same index in the argument list, and makes the substitution. The format specifiers automatically converts the data into string. Right now, there is no formatting that took place. We will save that for later. You might notice that String.Format is quite like the Console.WriteLine method. In fact, Console.WriteLine uses the same technique described above. Since { and } indicates the start and end of a format specifier, what if you want to print these characters?
Console.WriteLine("{{{0}}}", 7); {7}

To print a { or }, you simply put two of each. In the code above, between the pairs of those braces lies the format specifier {0} that's why it was replaced by 7 in the output. It is important to understand that the argument associated with a format specifier is determined by the argument number, not the argument's position in the argument list. This means the same argument can be output more than once within the same call to WriteLine(). It also means that arguments can be displayed in a sequence differently than they are specified in the argument list. For example, consider the following program:
Console.WriteLine("{0} {0} {0} {1} {1}", "hello", "world"); hello hello hello world world

Numeric Format Specifiers


You can use a list of numeric format specifiers to format numbers to format numerical data:
Console.WriteLine("{0:C}", 500); $500.00

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can see that the integer 500 was formatted into a currency using the C: and then the numeric format specifier af the for specifier index ("{0:C}";). You can also use precision specifiers which are numbers that modify the result of the formatting. For example, if you want 3 decimal places for a number, you do the following:
Console.WriteLine("{0:F3}", 100); // 500.000

A list of numeric format specifiers is listed below. Specifier C c D d E e F f G g N n P p R r X Currency Same as C Whole number numeric data. (Use with integers only.) Same as D. Scientific notation (uses uppercase E) Scientific notation (uses lowercase e) Fixed point notation. Same as F. Use either E or F format, whichever is shorter. Use either e or f format, whichever is shorter. Fixed-point notation, with comma seperators. Same as N. Percentage Same as P. Numeric value that can be parsed, using Parse(), back into its equivalent internal form. (This is called the "round-trip" format.) Same as R. Specifies the number of decimal places. Specifies the number of decimal places. The deafult is six. Same as E Specifies the number of decimal places. See E and F. See e and f. Specifies the number of decimal places. Minimum number of digits. Leading zeros will be used to pad the result, if necessary. Format Meaning of Precision Specifier Specifies the number of decimal places.

Not used.

Minimum number of digits. Hexadecimal (uses uppercase letters A through F) Leading zeros will be used to pad the result, if necessary. Minimum number of digits. Hexadecimal (uses lowercase letters a through f) Leading zeros will be used to pad the result, if necessary.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The precise effect of certain format specifiers depends upon the cultural settings. For example, the currency specifier, C, automatically displays a value in the monetary format of the selected culture. For most users, the default cultural information matches their locale and language. Thus, the same format specifier can be used without concern about the cultural context in which the program is executed. Here is a program that demonstrates several of the numeric format specifiers:
double v = 17688.65849; double v2 = 0.15; int x = 21; Console.WriteLine("{0:F2}", v); // 17688.66 Console.WriteLine("{0:N5}", v); // 17, 688.65849 Console.WriteLine("{0:e}", v); // 1.768866e+004 Console.WriteLine("{0:r}", v); // 17688.65849 Console.WriteLine("{0:p}", v2); // 15.00 % Console.WriteLine("{0:X}", x); // 15 Console.WriteLine("{0:D12}", x); // 000000000021 Console.WriteLine("{0:C}", 189.99); // $189.99

Notice the effect of the precision specifier in several of the formats. Also note that you can use the ToString() method and pass the numeric format specifier.
int x = 500; Console.WriteLine(x.ToString("C")); // $500.00

Padding with Format Specifiers


You can also used the format specifiers to add padding to the string. The following demonstrates just that:
Console.WriteLine("{0,10}", "hello"); Console.WriteLine("{0,-10}{1}", "hello", "world"); hello hello world

You use the following syntax {x:y} where x is the argument number, and y is the length of the padding. A positive length adds the padding to the left while a negative length adds the padding to the right. The amount of padding is determined by the length of the string which will be substituted. For example, if the length of the string is 5 and the length of the padding is 10, then the actual padding that will be displayed is 5 spaces. If the length of the padding is less that the length of the string, then nothing will happen. You can even combine them with numeric format specifiers such as the following:
Console.WriteLine("{0,10:C}", 500); $500.00

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Note that the padding depends on the length of the formatted so even though 500 has a length of 3 and the final padding is supposed to be 7, the padding was reduced to 4 because of the $ sign the decimal point the the two zeroes that has been added by the numeric format specifier.

Custom Numeric Format


Custom numeric format specifiers allows you to indicate an example of how you will represent your output. You will be using different special characters which function as placeholders. The following table presents the available custom format placeholder characters. Placeholder Meaning # Digit . Decimal point , Thousands seperator % Percentage, which is the value being formatted multiplied by 100. 0 Pads with leading and trailing zeros ; Seperates sections that describe the format for positive, negative, and zero value. E0 E+0 E-0 Scientific notation. e0 e+0 e-0 The period specifies the position of the decimal point. The # placeholder can hold a digit and can occur on the left or right side of the decimal point, or even by itself. If the # appears in the right side of the decimal point, it specifies the precission of the number of decimal digits. The value will be rounded if it is neccessary. If the # is found in the left of the decimal point, it specifies the digit positions for the whole-number part of the value and leading zeroes will be added if deemed neccessary. If the actual number has more digits the the number of #'s to the left of the decimal point, all the digits will be displayed. For example, if the number is 12345 and you only use ### which can only hold 3 digits, then all the five digits will still be displayed. If the original value has a decimal part and you use no decimal portion in your custom numeric format specifier, the value will be rounded to a whole number. For example, if the original value is 123.45 and you used ###, then it will be rounded down to 123. Zeroes are not siginificant such as a trailing zero, therefore, they will not be displayed. This causes a somewhat odd effect because a format such as ##.## displays nothing at all if the value being formatted is 0. To display a zero, you use the 0 placeholder instead as seen in the table above. You use the 0 placeholder to add leading or trailing zeroes. It can be placed on both left or right of the decimal point.
Console.WriteLine("{0:00##.#00}", 21.3); // 0021.300

You can place commas into large numbers to indicate the thousands position. For example:
Console.WriteLine("{0:#,###.#}", 3421.3); // 3,421.3

You don't need to specify a comma for each position. Commas will automatically inserted for every third digit from the left of the decimal point. For example:

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Console.WriteLine("{0:#,###.#}", 8763421.3); // 8,763,421.3

Commas have another meaning. When they occur on the immediate left of the decimal point, they act as a scaling factor. Each comma causes the value to be divided by 1,000. For example:
Console.WriteLine("{0:#,###,.#}", 8763421.3); // 8,763.4

As the output shows, the value is scaled in terms of thousands. In addition to the placed holders, a custom format specifier can contain other characters. Any other characters are simply passed through, appearing in the formatted string exactly as they appear in the format specifier. For example, this WriteLine() statement:
Console.WriteLine("Fuel efficiency is {0:##.# mpg}", 21.3); // 21.3 mpg

You can also use the escape sequences, such as \t or \n, if necessary. The E and e placeholders cause a value to be displayed in scientific notation. At least one 0, but possibly more, must follow E or e. The 0's indicate the number of decimal digits that will be displayed. The decimal component will be rounded to fit the format. Using an uppercase E causes an uppercase E to be displayed; using a lowercase e causes a lowercase e to be displayed. To ensure that a sign character precedes the exponent, use the E+ or e+ forms. To display a sign character for negative values only, use E,e,E-,e-. The ";" is a seperator which enables you to indicate different formats for positive, negative, and zero values. Here is the general form of a custom specifier that uses the ";": positivefmt;negative-fmt;zero-fmt. For example:
Console.WriteLine("{0:#.##;(#.##);0.00}", num);

If num is positive, the value that will be displayed has two decimal places otherwise, if it is negative, the value is displayed with two decimal places and is inside a set of perentheses. If num is zero, 0.00 will be displayed. When you use seperators, there is no need to supply all parts. If you just want to specify how positive and negative values will look, omit the zero format. To use the default for negative values, omit the negative format. In this case, the positive format and the zero format will be seperated by two semicolons. The following example demonstrates just a few of the many possible custom formats that you can create:
double num = 64354.2345; Console.WriteLine("{0:#.##}", num); // 64354.23 Console.WriteLine("{0:#,###.##}", num); // 64,354.23 Console.WriteLine("{0:#.###e+00}", num); // 6.435e+04 Console.WriteLine("{0:#0,}", num); // 64 Console.Writeline("{0:#.#;(#.##);0.00}", num); // 64354.2 num = -num; Console.WriteLine("{0:#.#;(#.##);0.00}", num); // (64354.23) num = 0.0;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Console.WriteLine("{0:#.#;(#.##);0.00}", num); // 0.00 num = 0.95; Console.WriteLine("{0:#%}", num); // 17%

StringBuilder class
The System.String class can use the + operator to concatenate two strings. But this is inefficient when concatenating two different strings. The reason is that String objects in .NET are immutable, that is, the value cannot be changed once it is assigned to the string variable. When you concatenate another string to an existing one, you discard its old value and create a brand new string object which contains the result of the concatenation. Repeating this process several times leads to a performance penalty as new temporary objects will be created and old objects will be discarded. Consider the following example, where you concatenate all the numbers from 0 to 9999;
int counter = 9999; string s = string.Empty; for (int i = 0; i <= counter; i++) { s += i.ToString(); } Console.WriteLine(s);

You might see no problem just by looking at the code but if we use the Stopwatch object to time the operation, you can see how long it takes to do the operations. Modify the code as shown here:
int counter = 9999; System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); string s = string.Empty; for (int i = 0; i <= counter; i++) { s += i.ToString(); } sw.Stop(); Console.WriteLine(s); Console.WriteLine("Took {0} ms", sw.ElapsedMilliseconds);

We used the Stopwatch class' Start() method to start the timer, and then proceed to the loop. After finishing the loop, we call the Stop() method of the Stopwatch class. On average, it took about 374 ms to run this application. Let's now use the StringBuilder class in .NET to perform the string concatenation, using its Append() method and demonstrate the performance improvement:
int counter = 9999; System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

sw.Start(); StringBuilder sb = new StringBuilder(); for (int i = 0; i <= counter; i++) { sb.Append(i.ToString()); } sw.Stop(); Console.WriteLine(sb.ToString()); Console.WriteLine("Took {0} ms", sw.ElapsedMilliseconds);

This time, it took about 3 ms to perform this operation. As you can see, the performance has improved dramatically. Performance can still be greater if the loop variant is increased. The StringBuilder is great if your concatenating strings with large amount of text, such as the content of a document. The StringBuilder class contains some important methods, which are shown in the following table. Method Append Description Appends the string representation of a specified object to the end of this instance. Appends a formatted string, which contains zero or more format specifiers, to AppendFormat this instance. Each format specification is replaced by the string representation of corresponding object argument. Appends the default line terminator, or a copy of a specified string and the AppendLine default line terminator, to the end of this instance. Copies the characters from a specified segment of this instance to a specified CopyTo segment of a destination Char array. Inserts the string representation of a specified object into this instance at a Insert specified character position. Remove Removes the specified range of characters from this instance. Replaces all occurances of a specified character or string in this instance with Replace another specified character or string. ToString Converts the value of a StringBuilder to a String.

Regular Expressions
Sometimes when getting input from the user, you need to check if it follows a certain pattern. For example. consider a textbox that expects to get an email from the user, it must check if the given text is actually an email and not anything else such as a name or a phone number. The .NET Framework offers this amazing pattern checking using regular expressions which is a special language for manipulating texts. The namespace used in handling regular expressions is the System.Text.RegularExpressions which contains the RegEx class that will do all the magic. The following shows the simplest use of the Regex class.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Regex myRegEx = new Regex("sample"); string s1 = "This is a sample."; if (myRegEx.IsMatch(s1)) Console.WriteLine("Match found!");

The Regex's constructor takes a string parameter which is the pattern you are searching for. We use the IsMatch() method to find a match. Since we passed "sample" as the pattern and the word sample can be found in s1, the IsMatch() method returns true. You might want to find the exact position of the text "string" in the variable. You can use the method Match() which returns a Match object which has the Index property containing the index of the matched word.
Regex re = new Regex("string"); string s1 = "This is a string"; Match match = re.Match(s1); if (match.Success) { Console.WriteLine("Match found at " + match.Index); } Match found at 10

When you have multiple matches in a string, you can use the Matches() method instead. It returns a MatchCollection object which you can iteratively loop through to obtain the index positions of all matches.
Regex re = new Regex("happy"); string s1 = "This is a happy happy happy day."; MatchCollection matches = re.Matches(s1); foreach(Match match in matches) { Console.WriteLine("Match found at index {0}.", match.Index); } Match found at index 10. Match found at index 16. Match found at index 22.

The Regex class also has a static Match() method which returns a Match object and accepts two parameters: the first one is the search pattern, and the second one is the string to search.
Match match = Regex.Match("sample", "This is a sample."); if (match.Success) Console.WriteLine("Match found!");

You can perform complex searches by using regular expression operators. Suppose you want to know if a specified string has either "Mr" or "Mrs", you can use the | operator.
string name = "Mr. John Smith";

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Regex r = new Regex("Mr|Mrs"); if (r.IsMatch(name)) { Console.WriteLine("Match found!"); }

Here, Regex will find "Mr" or "Mrs" in a string. If at least one of them is found in the string, then IsMatch() will yield true. The table that follows shows the regular expression operators commonly used in searching patterns: Operator Description . Match any one character [] Match any one character listed between the brackets [^ ] Match any one character not listed between the brackets ? Matches 0 or 1 occurrence of the preceding pattern. * Matches 0 or more occurrences of the preceding pattern. + Matches 1 or more occurrences of the preceding pattern. {n} Match declared element exactly n times {n, } Match declared element at least n times {n,N} Match declared element at least n times, but not more than N times ^ Match at the beginning of a line $ Match at the end of a line \< Match at the beginning of a word \> Match at the end of a word \b Match at the beginning or end of a word \B Match in the middle of the word \d Shorthand for digits (0-9) \w Shorthand for word characters (letters and digits) \s Shorthand for whitespace Let's take a look at more examples: Sample Matches ^[A-Z][a-zA-Z]*$ John, Raymond, Allen 123 Some Street ^[0-9]+\s+([a-zA-Z]+|[a-zA-Z]+\s[a-zA-Z]+)$ 567 Unknown \d{5} 12345 The ^ indicates the start of the string and $ represents the end of the string. [A-Z] means a character should be from A to Z. Using the ^ character negates the effect. For example, if you Pattern

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

use [^A-Z] then only characters which are does not fall from A-Z is matched. [a-zA-Z] simple means match every alphabet whether it is lower case or uppercase. The * operator is used if you want to match 0 or more of the preceding pattern. There for [0-9]* willl much nothing, 1, 12, 123 and so on. The ? character matches the the preceding pattern 0 or 1 time there for \d? will much nothing or the numbers 1-9 since \d represents a numerical digit. The + matches 1 or more times therefore [0-9A-Z]+ matches 9, A8, 87G, 9AT2 and so on. The {n} is used to repeat a pattern a number of times. So A{5} matches AAAAA. {n, } matches at least n times of the preceding pattern. Therefore, B{2, } matches BB, BBB, BBBB but not B. {n, N} matches at least n times but not more than N times of the preceding pattern. There for C{3, 5} matches CCC, CCCC, CCCCC, but not C or CCCCCC. There are many premade regular expressions in the internet. You can visit http://regexlib.com/ for some premade regular expression patterns. All you need to do is find the regular expression of your choice, feed it in the Regex constructor (or use as an argument in the Match() method). Then you can use the Match() and IsMatch() methods to find a match.

Replacing Strings with Regular Expressions


You can use the Regex class to replace all the matching strings within another string. Regex offers two versions of Replace method. An instance method and a static method. Let's take a look at the static version first.
string contact = "My contact is mail@example.com"; Console.WriteLine(contact); contact = Regex.Replace(contact, @"[\w]+@[\w]+\.[\w]+", "123-4567"); Console.WriteLine(contact); My contact is mail@example.com My contact is 123-4567

The code above provides you with a simple email regular expression pattern. We will use this to seek any matching string and replace it with the replacement string. The static Replace method accepts three arguments, the input string, the pattern and the replacement string. When the email was found, it was replace with the replacement string. Notice we don't put ^ and & in the beginning and end of the pattern because the matching string could be found anywhere in the input string. The instance version of the Replace method is quite similar except that it only has two parameters, the pattern and the replacement string.

Validation Using Regular Expressions


Regular expressions are great way to validate data provided by a user to the fields of a form. Suppose that a user should input an age rather than a name, or an address rather than a gender, you can use power of regular expressions to validate them. The following example creates a simple windows forms application that demonstrates the use of regular expression in validating each fields of a form. Create a new windows forms application and name it RegexValidation.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 Label Type Name Property Values 1 Label firstNameTextBox 2 Label lastNameTextBox 3 Label ageTextBox 4 Label genderTextBox 5 Label addressTextBox 6 Label zipCodeTextBox 7 Button submitButton Text Submit Although we can use radio buttons for the Gender field, we will be using a text box to demonstrate validation of text using regular expressions. Double click the submitButton to generate an event handler for its Click event. Be sure to import System.Text for the StringBuilder class that we will use and System.Text.RegularExpressions for the Regex class.
using System.Text; using System.Text.RegularExpressions;

We should also declare a StringBuilder and Regex members in our Program class.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

private StringBuilder errors; private Regex validator;

Use the following code for the Click event handler of submitButton.
private void submitButton_Click(object sender, EventArgs e) { if (AreFieldsValid()) { //Do task here } }

Notice that the event handler calls the AreFieldsValid() which is a method that we will create that will check each field for validation errors. The method will return a true if no errors has been detected and false if at least one validation error is detected. If it returns true, then you can insert the code to do if all the fields are valid. The following is the code for AreFieldsValid() method.
1 private bool AreFieldsValid() 2 { 3 errors = new StringBuilder(); 4 5 //Validate First Name and Last Name 6 validator = new Regex(@"^([A-Z][a-z]+)(\s[A-Z][a-z]+)*$"); 7 8 if (!validator.Match(firstNameTextBox.Text).Success) 9 errors.AppendLine("First name is not in the proper format."); 10 11 if (!validator.Match(lastNameTextBox.Text).Success) 12 errors.AppendLine("Last name is not in the proper format."); 13 14 //Validate Age 15 validator = new Regex(@"^\d{1,2}$"); 16 17 if (!validator.IsMatch(ageTextBox.Text)) 18 errors.AppendLine("Invalid Age."); 19 20 //Validate Gender 21 validator = new Regex(@"^([M|m]ale|[F|f]emale)$"); 22 23 if (!validator.IsMatch(genderTextBox.Text)) 24 errors.AppendLine("Invalid Gender."); 25 26 //Validate Address 27 validator = new Regex(@"^[0-9]+(\s[a-zA-Z]+)+$"); 28 29 if (!validator.IsMatch(addressTextBox.Text)) 30 errors.AppendLine("Address is not in the proper format."); 31 32 //Validate ZipCode 33 validator = new Regex(@"^\d{4}$"); 34 35 if (!validator.IsMatch(zipCodeTextBox.Text)) 36 errors.AppendLine("Invalid zip code"); 37

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

38 39 40 41 42 43 44 45 46 47 48 49}

if (errors.ToString() == String.Empty) { return true; } else { MessageBox.Show(errors.ToString(), "Validation Failed", MessageBoxButtons.OK, MessageBoxIcon.Error); return false; }

Figure 2 Line 3 creates a new instance of the StringBuilder class. Using its parameterless constructor instantializes it with an empty string. Line 6 creates the regular expression pattern for the first and last names. Since first and last names has the same pattern, they can simply share with the same regular expression. Lines 8 and 11 tests if the first and last names provided by the user is valid by using the Match() method of the Regex class and passing the text inside the text boxes. The Match() method returns a Match object where you can access the Success property indicating if whether the given text matches the pattern. If the matching is not successful, then we used the AppendLine() method of the StringBuilder class to add a message to the errors that will be presented to the user at the end of the validation. Lines 15 creates another Regex object with a new regular expression pattern that will be used for the age. In line 17, we used the IsMatch() method of the Regex class instead of the Match() method which is much simpler but only has one purpose, to tell whether a specified string matches the given pattern. If it does, IsMatch() will return true, otherwise false. For each field to validate, we simply create a correponding Regex object with the proper string pattern. If a field does not match a pattern, then an error message is appended to the content of errors. After we have tested every field for validity, line 38 tests if the content of errors is empty. Empty means that no errors has been added to its content, therefore, all the fields are valid and true was returned to the caller. If the errors has contents, then we print in in a message box to notify the user of the validation errors and return false to the caller.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We have seen one technique of validation using regular expressions. There are more ways to do validation such as using an ErrorProvider control or the Validating and Validated events.

File System
Most of the time, you will need to be able to write your data to files for permanent storage. You will also need to be able to access the file system or the directory of the computer so that you can locate the files and load them, indicate the location where you want to save the file, view the files stored in that directory, or simply check the detail about that particular directory. You can even check how big the file is or if it is read-only. Although using a database is much preffered these days, using a text file is sufficient for simple and small programs. Also, some legacy programs still store their data in a text file so you need to incorporate writing and reading from a file. The .NET Framework offers classes that you can use to read, write, and check the attributes of files and directories. You can use the instance versions, or the static versions of the class which offers the same capabilities with minimal differences. The following lessons will also teach you how to write a binary data and compressing files to make their size smaller.

Absolute and Relative Paths


Files and directories can be uniquely identified using their path names. Path names specify where files and directories are located. When specifying path names, you can can either use a absolute or relative path. An absolute path is the complete path name of a file or a directory. It starts with the root directory up to the parent directory where another directory of file is contained. An example of an absolute path is C:\Program Files\Tutorials\Sample.txt. In case of websites, an example of an absolute path specifies the domain name such as http://visualcsharptutorials/tutorials/sample.html. Relative path doesn't require you to specify the root directory. You can simply specify a name of another directory or file to search for it on the same directory where the program that calls it resides. For example, if you are in the C:\ directory and you specify "Sample.txt" as a relative path, then you are actually calling C:\Sample.txt. If for example you give "Program Files/Sample.txt" while the program calling it is in the C:\ directory, then you will be calling C:\. In the following lessons, we will be using string verbatims when specifying a path. This is to avoid using double backslash which could make our paths less natural to look at. For example, for specifying C:\Program Files\Tutorials\Sample.txt, the string should look like this:
@"C:\Program Files\Tutorials\Sample.txt"

If string verbatim is not used, it should look like this:


"C:\\Program Files\\Tutorials\\Sample.txt"

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The next lessons discusses the different classes of the System.IO namespace that can be used to create, delete, copy, and move files and directories and many more.

The System.IO.File Class


The System.IO.File class is a static class that exposes methods to manipulate an existing file in a directory. Such methods allow you to create, delete, open, move, or copy a file. As you can see, we need to import the System.IO namespace to be able to use the File class. The following are the some of the useful methods of the File class. Method Description Copy Copies a file to a specified destination. Create Creates a file in the specified path. Delete Deletes the file. Open Returns a FileStream object that you can use to read and write to the file. Move Moves a file to a specified destination. Exists Checks whether the specified file path exists in the file system. Figure 1

Creating a File
We can use the Create method to create a new file. The method accepts a string argument which is the path where you want the file to be stored.
File.Create(@"C:\Files\sample.txt");

Note that if the file already exists, then it will be overwritten. You can use the Exists() method to test whether a certain path already exist It returns true if it finds the file path or directory path in the file system. If not, then false will be returned.
if (File.Exists(@"C:\Files\sample.txt")) Console.WriteLine("Path already exist."); else Console.WriteLine("Path does not exist.");

Deleting a File
To delete a file, simple use the Delete method and indicate the path of the file to be deleted.
File.Delete(@"C:\Files\sample.txt");

Copying a File
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

We can use the Copy method that has two parameters. The first one is the source file path, and the second parameter is the destination file path.
File.Copy(@"C:\Source\sample.txt", @"C:\Dest\sample.txt");

Another overload of the Copy method provides a third boolean parameter that indicates whether to overwrite the file with the same file name in the destination path.
File.Copy(@"C:\Source\sample.txt", @"C:\Dest\sample.txt", true);

Moving a File
If you wan't to move a file to another destination, you can use the Move method which also accepts two arguments which is the source and destination path.
File.Move(@"C:\Source\sample.txt", @"C:\Dest\sample.txt");

Openning a File
You can use the Open method to open a file. The term open here doesn't mean execute the file. Calling the Open method returns a FileStream object which you can then use to read and write using the other classes.
FileStream fs = File.Open(@"C:\Files\sample.txt", FileMode.Open);

We will see how to use the created file stream in a later lesson. The first overload of the Open method accepts the path of the file to open, and a value from the System.IO.FileMode enumeration. The file mode affects the behavior of the openned file. Indicating FileMode.Open means we are simply opening the file. We will see more about this enumeration in a later lesson. Another overload accepts a third argument which is a value from the System.FileAccess enumeration. This parameter tells whether we want to read, write, or do both to the file we are opening. Again, this topic is best discussed when we reached the lesson on how to read and write files.

The System.IO.FileInfo Class


The System.IO.FileInfo class is quite simillar to the System.IO.File class in that, they are used for the same purpose of manipulating a file. The difference is that, FileInfo does not have static methods so you need to create an instance of it first. The created FileInfo object represents a file in the disk.
FileInfo file = new FileInfo(@"C:\Files\sample.txt");

The constructor accepts the file path of the file that the object will represent. Because we indicated the path in our constructor, calling the methods such as Create, Delete, Move, and

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Copy is simpler because we don't have to repeat indicating the file path or source path in the method calls. For example, the following shows the difference of the System.IO.File and System.IO.FileInfo classes when calling the Create method.
FileInfo file = new FileInfo(@"C:\Files\sample.txt"); file.Create(); File.Create(@"C:\Files\sample.txt");

And the following shows the difference of moving and copying files.
file.CopyTo(@"C:\Dest\sample.txt"); file.MoveTo(@"C:\Dest\sample.txt"); File.Copy(@"C:\Source\sample.txt", @"C:\Dest\sample.txt"); File.Move(@"C:\Source\sample.txt", @"C:\Dest\sample.txt");

Note that we used CopyTo and MoveTo for the FileInfo object instead of Copy and Move and we only indicated the destination since the source path was indicated when we created the object. The following are some of the basic methods of the FileInfo class. Method Description Create Creates a new file. Delete Deletes the file associated with the FileInfo object. Copies the file to the indicated destination path. An overload accepts a second boolean CopyTo argument indicating whether to overwrite any existing file in the destination path. MoveTo Moves the file to the indicated destination path. Open Creats a FileStream that can be used to read or write to the file. Figure 1 - FileInfo Methods The following are some of the properties of the FileInfo class. Property CreationTime Description Get's the time the file was created. Returns the result as a DateTime object. Returns the DirectoryInfo which contains the information of the directory Directory where the file is located. Exists Tells whether the specified path in the constructor exists in the file system. Extention Returns the extension name of the file as string. (".txt") IsReadOnly Tells whether the file is read-only. Gets the last time the file was accessed. Returns the result as a DateTime LastAccessTime object. Gets the last time the file's content was modified. Returns the result as a LastWriteTime DateTime object. Length Gets the size in bytes of the current file.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Property Name FullName

Description Gets the file name of the file. ("sample.txt") Gets the full name of the file. ("C:\Files\sample.txt")

Figure 2 - FileInfo Properties More properties and methods are present in the FileInfo object and we will discuss them as we progress further to the next lessons.

The System.IO.Directory Class


The System.IO.Directory class offers methods form creating, deleting, moving, retrieving file lists, and many more. These methods are static so you don't need to create an instance of that class. The following table shows you some usefull methods of the Directory class that you can use. Methods CreateDirectory Delete Exists GetCurrentDirectory GetDirectories GetFiles Description

Creates a new directory. Deletes an existing directory. Tells whether a given directory exists in the file system. Gets the current working directory of the application. Gets the name of the subdirectories of the specified directory. Returns the names of the files contained in the specified directory. Returns an array of strings which are the names of the files and GetSystemFileEntries subdirectories in the specified directory. GetParent Get the root directory of a specified path. Move Moves the directory including its contents into another location. Figure 1

Creating a New Directory


We use the CreateDirectory method to create a new directory. The following code snippet shows how to do that.
Directory.CreateDirectory(@"C:\Directory\Subdirectory");

The CreateDirectory method accepts one string argument which is the path. The CreateDirectory method will create all the directories and subdirectories specified by the path.

Deleting a Directory

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Use the Delete method if you want to delete a directory. The Delete method accepts a string argument which is the path of the directory.
Directory.Delete(@"C:\Directory\Subdirectory");

By default, the Delete method will produce an exception if the directory to be deleted is not empty. If you want to include all the files and subdirectory of the directory that you will be deleting, then you can use an overloaded version of the Delete method that has a second boolean parameter. When this is set to true, then everything that the specified directory contains will be deleted as well.
Directory.Delete(@"C:\Directory\Subdirectory", true);

Testing if the Directory Exists


Like the System.IO.File class, the Directory class also has an Exists method which tells whether a specified path of the directory exists inside the file system.
if (Directory.Exists(@"C:\Directory\Subdirectory")) Console.WriteLine("The directory exists.");

Getting the List of Subdirectories and Files


The GetDirectories method gets all the subdirectories of the specified path. For demonstration, let's create a directory C:\Directory and inside it, create directories named Subdirectory1, Subdirectory2, and Subdirectory3. The following code will list the directories inside C:\Directory.
string[] directories = Directory.GetDirectories(@"C:\"); foreach (string directory in directories) { Console.WriteLine(directory); } C:\Directory\Subdirectory1 C:\Directory\Subdirectory2 C:\Directory\Subdirectory3

If you only want to display the subdirectory name, then we do some string manipulation.
Console.WriteLine(directory.Substring(directory.LastIndexOf(@"\") + 1));

Alternatively, you can use the methods by System.IO.Path which will be discussed in a later lesson. The GetFiles and GetSystemFileEntries is similar to the GetDirectory class. The GetFiles method returns a string array containing the list of files inside the directory. The GetSystemFileEntries is the combined list of files and directories.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Moving a Directory
To move a directory to another location, simply use the Move method which accepts two arguments, the directory to move and the path the directory will be moved to.
Directory.Move(@"C:\Directory", @"C:\AnotherDirectory\Directory");

The System.IO.DirectoryInfo Class


The System.IO.DirectoryInfo class represents a directory in your file system. Its capabilities is similar to the System.IO.Directory class. You need to create an instance of DirectoryInfo class to make use of its properties and methods.
DirectoryInfo directory = new DirectoryInfo(@"C:\Directory");

The constructor of the DirectoryInfo class accepts a string argument which is the path of the directory that it will represent. You can then execute different methods such as creating, deleting, moving, and checking the details about the directory. You can also use some of the useful properties of this class as shown in the table below. Properties Description Attributes Gets the attributes of the directory. CreationTime The date and time the directory was created. Exists Returns true if the directory exists in the file system. LastAccessTime The date and time the directory was last accessed. LastWriteTime The date and time the directory was last modified. Name Returns the name of the directory. FullName Gets the full path of the directory or file. Parent Gets the parent of the specified subdirectory. Root Gets the root portion of the path. FIgure 1 - System.IO.DirectoryInfo Properties The Parent property returns the name of the parent directory of the DirectoryInfo intance. For example, the parent directory of C:\Directory\Subdirectory is Directory. The Root property returns the root directory of the DirectoryInfo. For example, the root directory of C:\Directory is C:\. The following are some of the methods of the The following are some of the methods of the DirectoryInfo class. Properties Description

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Properties Create

Description

Creates a directory. Creates a subdirectory or subdirectories in the specified path. The path can CreateSubdirectory be relative to the instance of System.IO.DirectoryInfo class. Delete Deletes the directory. Returns a list of DirectoryInfo objects which are the subdirectories of the EnumerateDirectories DirectoryInfo instance. Returns a list of FileInfo objects which are the files located in the EnumerateFiles DirectoryInfo instance. GetDirectories Same as EnumerateDirectories but returns the result as an array. GetFiles Same as EnumerateFiles but returns the result as an array. MoveTo Moves the directory to another directory. Figure 2 - System.IO.DirectoryInfo Properties

Creating Subdirectories
The CreateSubdirectory method is used to create subdirectories. Consider the following example.
DirectoryInfo directory = new DirectoryInfo(@"C:\Directory"); directory.Create(); //Creates C:\Directory directory.CreateSubdirectory("Subdirectory"); //Creates C:\Directory\Subdirectory

The path you give as the argument to the CreateSubdirectory method is a relative path. Which means, you don't need to write the full path of the subdirectory. It will be relative to the path contained by the DirectoryInfo object.

Enumerating Directories and Files


You can use EnumerateDirectories, EnumerateFiles, GetDirectories, or GetFiles to retrieve a list of the directories and files contained by the directory of the DirectoryInfo instance. The difference of the two pairs is EnumereateDirectories and EnumerateFiles returns the result as a System.Collections.Generic.IEnumerable<T> where T is DirectoryInfo or FileInfo. GetDirectories and GetFiles returns the result as a simple DirectoryInfo or FileInfo array. The following code shows the list of files in a directory.
DirectoryInfo directory = new DirectoryInfo(@"C:\"); IEnumerable<FileInfo> files = directory.EnumerateFiles(); foreach (FileInfo file in files) { Console.WriteLine(file.Name); }

Output is not shown because the results will depend on the files contained in your C:\ directory.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can use an overloaded of the four methods which accepts a string argument that will serve as a search pattern or a filter to the results. For example, you can only list all the files with the extention .txt.
IEnumerable<FileInfo> textFiles = directory.EnumerateFiles("*.txt");

The * is a wildcard character that represents the name of the file. The textFiles will now contain a list of FileInfo objects that has a .txt extention.

The System.IO.Path Class


The System.IO.Path class is a utility class that has methods for constructing paths of files and directories. Although you can simply use simple string concatenation and methods, using the Path class makes it easier for you when dealing with paths. The following table shows some methods of the Path class. Methods Description ChangeExtention Changes the extention of a particular path. Combine Combines an array of paths. GetDirectoryName Returns the directory information for the specified path string. GetExtension Returns the extension of the specified path string. GetFileName Returns the file name and extention of the specified path string. GetFullPath Returns the absolute path for the specified path string. HasExtension Determines whether a path includes a file name extension. Figure 1 - System.IO.Path Methods

ChangeExtension()
The ChangeExtension method is used to change the extention of a specified path. Supposed we have given a path C:\path.txt, the extention name here is .txt. The code below demonstrates how to change the extension of a path.
string path = Path.ChangeExtension(@"C:\path.txt", "bmp"); Console.WriteLine(path); C:\path.bmp

The ChangeExtension method accepts two string arguments and returns the modified path as a string. The first parameter is the path containing the extension that we will modify. The second parameter is the replacement extension.

Combine()

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Combine method is used to combine multiple paths. For example, suppose you have a path C:\Documents and you have another path named sample.txt, then using the Combine method will combine these two paths to produce C:\Documents\sample.txt. Note that a backslash was automatically inserted between the two paths.
string path1 = @"C:\Document"; string path2 = @"sample.txt"; string newPath = Path.Combine(path1, path2); Console.WriteLine(newPath); C:\Document\sample.txt

You might just use some string concatenation but using the Combine method is easier and automated.

GetDirectoryName()
The method GetDirectoryName gets the path of the parent directory of a given directory or file path. Consider the following example.
string path1 = @"C:\Parent\sample.txt"; string path2 = @"C:\Parent\Child"; string parent1 = Path.GetDirectoryName(path1); string parent2 = Path.GetDirectoryName(path2); Console.WriteLine(parent1); Console.WriteLine(parent2); C:\Parent C:\Parent

GetExtension()
The GetExtension method returns the extension part of the path. The extension identifies the type of file and the program that will open it.
string path1 = @"C:\Parent\sample.txt"; Console.WriteLine(Path.GetExtension(path)); .txt

GetFileName()
This method returns the full name including the extention of the file in a path.
string path1 = @"C:\Parent\sample.txt"; Console.WriteLine(Path.GetFileName(path)); sample.txt

GetFullPath()
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

This method returns the absolute path of a given relative path. Consider the following example code.
string path = "sample.txt"; Console.WriteLine(Path.GetFullPath(path)); C:\Users\VS\Documents\Visual Studio 2010\Projects\SimpleProgram\SimpleProgram\ bin\Release\sample.txt

The absolute path returned is based on the absolute path of the the current program. Changing the location of the program also changes the output of this method.

HasExtension()
This method simply returns true if the given path has a file extension, and false if it has does not contain an extension. Therefore, you an also use this method to determine if the path is a file path or a directory path since directories contain no extension.

Writing to a Text File


Writing to text files are useful when you want a way of permanent storage of your data. Although databases and XML files are more popular choices, text files are still used by legacy softwares. And if you are writing small amout of simple data, writing to text file is an acceptable choice. Before we write to a data, we need a stream, specifically a FileStream. A stream represents a file in your disk or you can even use streams that point to a remote destination. The FileStream class will be used to point to a file. The FileStream object is then past as a parameter to the constructore of the StreamWriter class. The StreamWriter class is the one responsible for writing to the stream, that is, the file indicated by the stream. Note that both FileStream and StreamWriter classes are contained inside the System.IO namespace. The following program asks user to enter firstnames, lastnames, and ages of people.
1 using System; 2 using System.IO; 3 using System.Text; 4 5 namespace WritingToFile 6 { 7 class Program 8 { 9 static void Main() 10 { 11 try 12 { 13 FileStream fs = new FileStream("sample.txt", 14FileMode.Create); 15 StreamWriter writer = new StreamWriter(fs);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 }

StringBuilder output = new StringBuilder(); int repeat = 0; do { Console.WriteLine("Please enter first name: "); output.Append(Console.ReadLine() + "#"); Console.WriteLine("Please enter last name: "); output.Append(Console.ReadLine() + "#"); Console.WriteLine("Please enter age: "); output.Append(Console.ReadLine()); writer.WriteLine(output.ToString()); output.Clear(); Console.WriteLine("Repeat? 1-Yes, 0-No : "); repeat = Convert.ToInt32(Console.ReadLine()); } while (repeat != 0); writer.Close(); } catch (IOException ex) { Console.WriteLine(ex.Message); } } }

Figure 1
Please enter first name: John Please enter last name: Smith Please enter age: 21 Repeat? 1-Yes, 0-No: 1 Please enter first name: Mike Please enter last name: Roberts Please enter age: 31 Repeat? 1-Yes, 0-No: 1 Please enter first name: Garry Please enter last name: Mathews Please enter age: 27 Repeat? 1-Yes, 0-No: 0

The output shows that we input three persons and they will be stored in a text file located in the path given when we created the FileStream object. Line 13 creates a FileStream object. The path we provided is a relative path and has no parent directories so the text file will be found in the directory where the program executable is also located. The constructor of the FileStream class as shown above accepts the path of file, and a FileMode enumeration value. The FileMode enumeration specifies how the operating system will open the file. The values available are shown below: Value Append
COMPILED BY:

Description Seeks the end of the file and starts the writing there. If the file does not exist, it is
Bsc ABDULRAHIM ALI ATHUMAN

Value

Description

created. Create Creates a file. If the file already exist, it will be overwritten. CreateNew Creates a new file. If the file already exists, a System.IO.IOException is thrown. Opens an existing file. A value from System.IO.FileAccess enumeration Open determines the behavior of this value. System.IO.FileNotFoundException is thrown if the file is not found. OpenOrCreate Same as Open but creates a new file if the file does not exist. Specifies that the operating system should open an existing file. Once opened, the Truncate file should be truncated so that its size is zero bytes. Figure 2 Passing FileMode.Create simply means create the file and if the file already exists, it will be overwritten. If we want to append new persons to the file, then we can use FileMode.Append instead. Another enumeartion, System.IO.FileAccess, determines the capabilities you can do with the file. The values are listed below. Value Description Read Only grants read access to a file. Write Only grants write access to a file. ReadWrite Grants read/write access to a file. Figure 3 To use this enumeration, you need to use a different constructor of the FileStream class which accepts a third argument which is a value from the FileAccess enumeration.
FileStream fs = new FileStream("sample.txt", FileMode.Create, FileAccess.ReadWrite);

After we successfuly created the FileStream object, we need to pass it to the StreamWriter class' constructor.
StreamWriter writer = new StreamWriter(fs);

The StreamWriter class contains the actual methods for writing data to the file. Such methods are shown below. Value Description Write Writes the data to the file. WriteLine Writes the data to the file and adds a new line character at the end. Close Closes the StreamWriter and the underlying stream.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 4 We used an instance of StringBuilder to build the output (lines 20-25). Note that we added a "#" character between at the end of firstname and lastname. It is used as a delimiter so that it will be easy for us to seperate each component when we will be reading the data in the next lesson. You can use any special character as a delimiter but # or $ is the most widely used. Lastly, we need to close the StreamWriter using the Close() method(line 32).This releases the resources in the memory and also closes the stream associated to it. We enclosed everything in a try block because these operations can throw a System.IO.IOException. For example, if the file cannot be found, then this exception will be thrown. Lines 34-37 catches this exception. Let's now look at the created file.
John#Smith#21 Mike#Roberts#31 Garry#Matthews#27

Each line represents a person, and each person is composed of three fields seperated by a delimiter. The next lesson will retrieve each person from this file.

Reading from a Text File


Reading data from a text file is almost similar to writing data to it. You create a FileStream pointing to the file to be read. But instead of passing the stream to a StreamWriter class, we used the StreamReader class which contains method to read data from a file. The following program demonstrates reading of file. The program will use the text file created in the previous lesson as the source file.
1 using System; 2 using System.IO; 3 using System.Text; 4 using System.Collections.Generic; 5 6 namespace ReadingFromFile 7 { 8 class Person 9 { 10 public string FirstName { get; set; } 11 public string LastName { get; set; } 12 public int Age { get; set; } 13 } 14 15 class Program 16 { 17 static void Main() 18 { 19 List<Person> persons = new List<Person>();

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

20 21 try 22 { 23 FileStream fs = 24 new FileStream("sample.txt", FileMode.Open, 25FileAccess.Read); 26 StreamReader reader = new StreamReader(fs); 27 28 while (!reader.EndOfStream) 29 { 30 string line = reader.ReadLine(); 31 string[] fields = line.Split('#'); 32 Person newPerson = new Person(); 33 newPerson.FirstName = fields[0]; 34 newPerson.LastName = fields[1]; 35 newPerson.Age = Convert.ToInt32(fields[2]); 36 persons.Add(newPerson); 37 } 38 } 39 catch (IOException ex) 40 { 41 Console.WriteLine(ex.Message); 42 } 43 44 //Show each person's details 45 foreach (Person p in persons) 46 { 47 Console.WriteLine("Name: {0} {1}\nAge: {2}", 48 p.FirstName, p.LastName, p.Age); 49 } 50 } 51 } }

Figure 1
Name: John Smith Age: 21 Name: Mike Roberts Age: 31 Name: Garry Mathews Age: 27

We created a class called Person(line 8-13) to store each person's data that is retrieved from the file. We also created a List of Person objects(line 19) the will hold all the person's data and makes it easier for us to output them. We will be openning and reading a text file so in lines 2324, we created a FileStream object with the location of the file to be read, a FileMode value of Open (which means to open the file), and a FileAccess value of Read (which only allows reading of the file). We created a StreamReader object(line 25) and passed the created stream to its constructor. The StreamReader object will be responsible for reading data to the file. We then enter a while loop in line 27 and we test if the stream position has not yet reached the end by using the

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

EndOfStream property of the StreamReader class. Inside the loop, we used the ReadLine() method of the StreamReader class which reads the whole line starting from where the stream position is located. The position is then moved to the next line. The whole line is then stored in a string (line 29). We used the Split() method in line 30 and passed the character '#' to seperate the fields and distribute them to seperate elements of the string array. Remember last lesson that we added the '#' character as the delimiter, now you see the reason why we did that. A new Person object was created and each element of the fields array was assigned to the respective properties of the created Person object. The Person object is then added to the persons List. When the end of file is reached, the loop exits and proceeds to the displaying of each person.

Compressing and Decompressing a Text File


When the size of files become large, it's a good idea to compress them. Compression is a process of reducing the overall size of a file. The process involves finding the redundant or repeating entries in a file and making them refer to a single entry. File compression is useful for web pages. You can reduce the size of a webpage which makes loading your site much faster. You can also consider file compression when you are archiving or backing up your files, or when sharing large files in the internet to be available for download. You can use different compression utilities such as WinRar or WinZip. If you have seen files with .zip or .rar extensions, then those files are compressed and have a smaller size compared to their uncompressed version.

Compressing Files with GZipStream and DeflateStream Classes


The .NET Framework Class Library offers the System.IO.Compression namespace which contains classes and methods used to easily compress or decompress files. These class can either use the GZIP or Deflate algorithm. In this lesson, we will simply create a compressed text file. You can either use the GZipStream or the DeflateStream classes when compressing or decompressing files. They work pretty much the same. These classes require an existing stream which in our case, a FileStream object that points to a file. Let's take a look at how to properly use this classes. There will be two set's of code which corresponds to the two classes. Create a new Console Application project and name it TextFileCompression. Import the two required namespaces for our program.
using System.IO; using System.IO.Compression;

We will first make a comparison of not compressing and compressing a file. Write the following code which simply creates a text file without using any compression mechanism.
1 static void Main(string[] args)

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

2 { 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26}

StringBuilder data = new StringBuilder(); for (int i = 0; i < 1000; i++) { data.AppendLine("The quick brown fox jumps over the lazy dog."); } Console.WriteLine("A compressed file was created!"); try { FileStream stream = new FileStream(@"C:\compressedFile.txt", FileMode.Create, FileAccess.Write); StreamWriter writer = new StreamWriter(stream); writer.Write(data.ToString()); writer.Close(); } catch (IOException ex) { Console.WriteLine(ex.Message); }

Example 1 Lines 3-8 creates 1000 lines of dummy text. Lines 12 to 25 creates a text file using the technques we learned in the previous lessons. Note that we are not using any compression at this time. The created file as seen in line 14 is located in C:\compressedFile.txt. If you will look at this file in this directory and check it's file size, you can see that it is about 45KB. Now let's use the compression classes from the System.IO.Compression namespace. Example 2 uses the GZipStream which uses GZIP compression and Example 3 uses DeflateStream for Deflate compression.
1 static void Main(string[] args) 2 { 3 StringBuilder data = new StringBuilder(); 4 5 for (int i = 0; i < 1000; i++) 6 { 7 data.AppendLine("The quick brown fox jumps over the lazy dog."); 8 } 9 10 Console.WriteLine("A compressed file was created!"); 11 12 try 13 { 14 FileStream stream = new FileStream(@"C:\compressedFile.txt", 15 FileMode.Create, FileAccess.Write); 16 17 GZipStream gzip = new GZipStream(stream, CompressionMode.Compress); 18

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

19 20 21 22 23 24 25 26 27 28}

StreamWriter writer = new StreamWriter(gzip); writer.Write(data.ToString()); writer.Close(); } catch (IOException ex) { Console.WriteLine(ex.Message); }

Example 2 The code is almost the same as Example 1, except for lines 17 and 19. Line 17 creates a GZipStream object which is used for GZIP compression. In the constructor, we provided the FileStream object in line 14. The second parameter of the constructor is a value from the CompressionMode enumeration which contains two values, Compress and Decompress. When writing compressed files, we used the CompressionMode.Compress value. In line 19, instead of passing the FileStream to the StreamWriter, we pass the created GZipStream object. When we called the Write() method in Line 21, the data being written is automatically compressed using GZIP compression algorithm. Remember that the uncompressed file is about 45KB. Let's look at the new size of the compressed file. You will see that the file is now 660 bytes or about 1KB. That's 44KB lower than the uncompressed text file we created earlier. The amount of reduced size depends on the amount of redundancy in the file and its overall size. Since the file actually contains a single sentence repeated 1000 times, the algorithm simply makes the other 999 entries to refer to a single sentence. If you will open the compressed text file, you won't be able to understand it. As you will see in Example 3, using the DeflateStream is very simillar to using the GZipStream class.
1 static void Main(string[] args) 2 { 3 StringBuilder data = new StringBuilder(); 4 5 for (int i = 0; i < 1000; i++) 6 { 7 data.AppendLine("The quick brown fox jumps over the lazy dog."); 8 } 9 10 Console.WriteLine("A compressed file was created!"); 11 12 try 13 { 14 FileStream stream = new FileStream(@"C:\compressedFile.txt", 15 FileMode.Create, FileAccess.Write); 16 17 DeflateStream deflate = new DeflateStream(stream, 18CompressionMode.Compress); 19 20 StreamWriter writer = new StreamWriter(deflate); 21

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

22 23 24 25 26 27 28 }

writer.Write(data.ToString()); writer.Close(); } catch (IOException ex) { Console.WriteLine(ex.Message); }

Example 3 The file size of the created compressed text file is 640bytes with is just a little lower that the GZip compressed file.

Decompressing Compressed File


You need to decompress the compressed files if you plan to read them. This is also an easy task thanks to the GZipStream and DeflateStream classes. Let's first take a look at using the GZipStream class for decompression. Note that you need the right class to decmpress a compressed file. For example, if the file is compressed using Deflate, then you must use the DeflateStream instead or an error will occur.
static void Main(string[] args) 1 { 2 try 3 { 4 FileStream stream = new FileStream(@"C:\compressedFile.txt", 5 FileMode.Open, FileAccess.Read); 6 7 GZipStream gzip = new GZipStream(stream, 8 CompressionMode.Decompress); 9 10 StreamReader reader = new StreamReader(gzip); 11 string contents = reader.ReadToEnd(); 12 reader.Close(); 13 14 Console.WriteLine(contents); 15 16 } 17 catch (IOException ex) 18 { 19 Console.WriteLine(ex.Message); 20 } 21 }

Example 4 Be sure the the file you are decompressing was compressed using the GZipStream or else this code will fail. Lines 5-6 creates a FileStream object which points to the compressed text file. We provide FileMode.Open and FileAccess.Read values in the constructor because we are simply reading the contents of the file. Line 8 creates a GZipStream object. The only difference here as you can see is the second argument which specifies the compression mode. We provide the
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

CompressionMode.Decompress value. This value is used to decompress the compressed data of the stream. We passed the created GZipStream object to the StreamReader object in line 10 which is the one who will read the contents of the file. Line 11 uses the ReadToEnd() method which decompresses the content of the compressed file and returns the content as a string. The uncompressed content is then displayed in line 14. If you compressed your file using the DeflateStream class, then you must use the same class for decompressing it. Example 5 shows you how to use the DeflateStream class to decompress a file. It is just simillar to using the GZipStream class.
static void Main(string[] args) 1 { 2 try 3 { 4 FileStream stream = new FileStream(@"C:\compressedFile.txt", 5 FileMode.Open, FileAccess.Read); 6 7 DeflateStream deflate = new DeflateStream(stream, 8 CompressionMode.Decompress); 9 10 StreamReader reader = new StreamReader(deflate); 11 string contents = reader.ReadToEnd(); 12 reader.Close(); 13 14 Console.WriteLine(contents); 15 16 } 17 catch (IOException ex) 18 { 19 Console.WriteLine(ex.Message); 20 } 21 }

Example 5 This lesson only shows you how to compress a simple text file. You can use the classes we discussed here on various types of files.

Extensible Markup Language


Extensible Markup Language (XML) allows you to store data in a text and structured format. It is widely used as a database alternative and for storing application configuration informations. XML has a similar syntax with HTML so if you know some HTML, then its easy to understand XML. XML documents may refer to an XML file in your disk or a string containing XML text. The following is an example of an XML document.
<Persons> <Person> <Name>John Smith</Name> <Age>30</Age>

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

<Gender>Male</Gender> </Person> <Person> <Name>Mike Folly</Name> <Age>25</Age> <Gender>Male</Gender> </Person> <Person> <Name>Lisa Carter</Name> <Age>22</Age> <Gender>Female</Gender> </Person> </Persons>

Figure 1 The XML document is composed of XML elements. An XML element consists of an opening tag, a closing tag, and the data or child elements between the opening and closing tags. You can provide any name for the elements as long as its describes the data that it will hold. Please note that elements are case-sensitive so persons and Persons are two different things. Also note that XML ignores white spaces so you can write an xml file in one line although formating XML properly makes it easier to read.
<open>data</close>

Elements may contain child elements which may also contain another child element.
<parent> <child1>data</child1> <child2> <grandchild1>data</grandchild1> </child2> </parent>

The XML document shown in Figure 1 contains data for three persons. Every XML document must have a root element which serves as the top level element. In Figure 1, the element named Persons is the root element and every element inside it are its child elements. Each person's details is enclosed inside a Person element. Inside a Person element, you can find child elements for the name, age, and gender of a person. XML Attributes which is another way of adding a data to an element. For example, the following is an element with an XML attribute inside it.
<Person name="John Smith">some data</Person>

The element above has one attribute named "name" and a value of "John Smith". Values must be enclosed in quotation marks(") or single quotation marks('). The following is the syntax of adding attributes.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

<element att1="value1" att2="value2" ... attN="valueN">data</element>

As you can see, we can add multiple attributes to an element.


<Person name="John Smith" age="30" gender="Male">some data</Person>

Let's update our XML document in Figure 1 to add attributes to each element.
<Persons> <Person name="John Smith"> <Age>30</Age> <Gender>Male</Gender> </Person> <Person name="Mike Folly"> <Age>25</Age> <Gender>Male</Gender> </Person> <Person name="Lisa Carter"> <Age>22</Age> <Gender>Female</Gender> </Person> </Persons>

Figure 2 We removed the Name element for each person and instead, we provided an equivalent attribute for each element. XML documents can also have an XML declaration. The XML declaration contains information about the XML document such as the version of XML used (1.0 is always recommended) and the text encoding used. An optional attribute, standalone,
<?xml version="1.0" encoding="UTF-8" ?>

The XML declaration is placed in the top most part of the document just before the root element. You can also write comments in an XML file. The following is an example of an XML comment.
<!-- This is an XML comment -->

We can create an XML file using a text editor but Visual Studio has a great XML editor that automatically formats and uses IntelliSense as you type. It wil also help you prevent badly structured XML as Visual Studio will highlight them with red or green squiggly lines. When you create a new project, you can click the Add New Item button in the toolbar and when the Window shows up, choose XML file. Visual Studio will automatically create an xml file with an XML declaration.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

XML Document Object Model


The .NET framework offers classes that can read and manipulate XML documents. These classes are located in the System.Xml namespace. .NET uses the XML Document Object Model which is a set of classes that represents different parts of an XML document (and the document itself). The following are some of the classes offered by XML DOM. Description Represents a node in the XML document tree. Nodes are anything you see in an XmlNode xml file such as elements attributes, comments, and even white spaces. These class is the base class of the other XML DOM classes. Represents the actual XML document. Can be used to load an existing XML file XmlDocument or save a constructed XML file. XmlElement Represents a single XML element. XmlAttribute Represents a single XML attribute. XmlText Represents that text inside an XML element. XmlComment Represents an XML comment. Figure 1 - XML DOM Classes An Xml Document is represented by the XmlDocument class. It contains the actual XML markup that you will be reading or manipulating. An XML Document should start with a root element which is also called the document element. This can be represented as an XmlElement. Everything inside it are its child nodes. You must also understand the concept of parent and child nodes. A parent node is a node that contains child nodes. As an example, consider this element that contains multiple elements:
<Product> <ProductID>001</ProductID> <ProductName>Shampoo</ProductName> <Price>10</Price> </Product>

Class

Here, the parent node is the Product Element. It contains two child nodes which are the ProductID, ProductName, and Price elements. If for example the ProductName still has more elements inside it, then it will be considered as a parent node of those elements it contains. Let's take a look at some properties and methods of each of these classes.

XmlNode
The XmlNode represents any part of the XML and is the base class of other classes in the XML DOM. For example, the XmlElement class is derived from the XmlNode so it shares XmlNode's properties and methods. The following are some useful properties of the XmlNode base class.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Description A collection of XmlAttribute objects which represents the attributes that this Attributes node contain. ChildNodes A collection of XmlNodes that serves as child nodes of this node. FirstChild Gets the first child node of this node. HasChildNodes Tells whether this node has child nodes. Gets all the inner text of all the child nodes of these nodes. If multiple inner InnerText texts are present, then they are combined into a single string. InnerXml Gets the XML string between the opening and closing tags of this node. LastChild Get the last child node of this node. Name Gets the name of the node. NextSibling Get the node immediately following this node. NodeType Gets the type of this node. OuterXml Gets the markup representing this node and all its child nodes. OwnerDocument Gets the XmlDocument to which this node belongs. ParentNode Gets the parent node of this node. PreviousSibling Get the node immediately preceding this node. Value Gets or sets the value of this node. Figure 2 - XmlNode Properties The Attributes property of a node contains a list of attributes that a node or element contains. Each attribute is represented by the XmlAttribute class. Consider this example:
<Person name="John Smith" age="30"></Person>

Property

This element's Attributes property contains two XmlAttribute objects that holds data for the name and age attribute. The ChildNodes property is a collection of child nodes of the current node. Each child node is also an XmlNode object. You can test if the node has child nodes by checking the value of the HasChildNodes property. This will return true if it has at least one or more child nodes, and false if it has none. The FirstChild and LastChild properties simply gets the first and last child nodes of the current node. PreviousSibling and NextSibling properties gets the previous and next nodes of the current node.
<PreviousNode></PreviousNode> <CurrentNode></CurrentNode> <NextNode></NextNode>

The Parent node gets the reference the parent of a child node. If no parent exists, then this property contains null.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Name property indicates the name of the element.


<Person>Example</Person>

The Name of the above element is Person. The InnerText retrieves the text located between the opening and closing tages of a control. If you are working with a comment, then this property returns the text of the comment. If the element has multiple nodes inside it, the InnerText property gets all the inner texts of all the child nodes and combine them into a single string. Consider the following XML markup.
<Example> <Sample1>Text1</Sample1> <Sample2>Text2</Sample2> <Sample3> <Sample4>Text3</Sample4> </Sample3> </Example>

The InnerText property will product the output Text1Text2Text3. Notice that the third child element has another child node and the InnerText property still successfully retrieve the text inside that child node. The InnerXml is similar to InnerText property, but this property returns the actual XML markup inside an element. The OuterXml property is similar to InnerXml but includes the current node in the results. The OwnerDocument property returns the reference to an XmlDocument that owns the current node. The NodeType contains a value from System.Xml.XmlNodeType enumeration. You can tell the type of a node by using this property. The table below lists the values of the XmlNodeType enumeration. Value Description Element The node is an element. Attribute The node is an attribute. Text The node is a text. Comment The node is a comment. Document The root element of a document. Whitespace A whitespace such as space, new lines or tab. XmlDeclaration An XML Declaration element. Figure 3 - XmlNodeType Enumeration Values

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Finally, the Value property specifies the value of the node. The Value property varies on each type of node. For example, calling the Value property a comment returns the text of the comment. The Value property of an attribute is the value of the attribute. Note that you must use InnerText or InnerXml to access contents of an XmlElement instead of using the Value property. The following are some useful methods of the XmlNode class. Method Description AppendChild Adds a new child node for this node. InsertAfter Insert a node immediately after the end of this node. InsertBefore Insert a node immediately before the beginning of this node. PrependChild Adds a node to the beginning of the list of the child nodes of this node. RemoveAll Removes the child nodes and attributes of this node. RemoveChild Removes a specified child node. ReplaceChild Replaces an old child node with a new one. SelectNodes Selects a list of node matching an XPath expression. SelectSingleNode Selects the first node that matches the XPath expression. WriteContentTo Writes all the child nodes of a node to an XmlWriter. WriteTo Writes the current node to a specified XmlWriter. Figure 4 - XmlNode Methods Some of this methods will be demonstrated in later lessons about writing and reading XML documents.

XmlDocument
The XmlDocument class represents the actual XML document and all its contents. The following are some properties exclusive to this class. Property Description DocumentElement The root element of the document. PreserveWhitespace Tells whether to preserve white spaces in the content of the document. The following are some methods exclusive to XmlDocument class. Method CreateAttribute CreateComment CreateElement CreateTextNode Description Creates an XmlAttribute object. Creates an XmlComment object. Creates an XmlElement object. Creates a XmlText object with the specified text.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Method Description CreateXmlDeclaration Creates an XmlDeclaration with the specified values. GetElementById Gets the XmlElement with the specified ID. GetElementsByTagName Returns a list of descendant elements that matches the specified name. Load Loads an XML document from a file. LoadXml Loads an XML from a string. Save Saves the content of this XmlDocument into a specified file. Notice the methods which starts with Create. This methods are used to create XML DOM objects. For example, if you want to create an element for the current document, then you use the CreateElement method. These is because using the DOM classes' constructors are prohibited due to its protection level. Most of these methods will be demonstrated in later lessons.

XmlElement
The XmlElement class represents a single XML element. The following are some useful properties of the XmlElement class. Property Description Attributes Contains all the attributes of an element. HasAttributes Tells whether the element contains at least one or more attributes. Specifies whether this element, when empty, should be written in short tag format IsEmpty (<element />) or long tag format (<element></element>). A value of true uses short tag format and false for long tag format. The text between the opening tag and closing tag of this element. If it contains Value child elements, then this property will be empty. The following are some methods exclusive to XmlElement. Method Description GetAttribute Returns the value of the attribute with the specified name. GetAttributeNode Returns the XmlAttribute with the specified name. GetElementsByTagName Returns a list of child elements that matches the specified name. The XmlText and XmlComment classes represents a text inside an element and a comment respectively. They are too simple to have their own sections in this lesson so I decided not to discuss them in detail.

Writing to an XML File


Using the classes and methods of the XML Document Object Model, we can easilly construct an XML document and save it to a file. We will create an application to demonstrate how we can

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

write an XML file by using the DOM classes. The application that we will create allows a user to specify his or her name, age, and gender. The details will then be added to an XML file. Create a new Windows Forms Application and create a form similar to Figure 1.

Figure 1 Change the name of the text boxes to textBoxName, textBoxAge, and textBoxGender. Change the name of the button to buttonAdd. We will now add the codes required to construct the XML document and write it to a file. Go to the Code View by hitting F7. Be sure to import System.Xml first at the top section of the code.
using System.Xml;

We need to add a private XmlDocument member and a string indicating the path of the XML file that we will use throughout the code. Write these right below the class declaration.
private XmlDocument doc; private const string PATH = @"C:\sample.xml";

Go back to the designer and double click the add button to generate an event handler for its Click event then use the following code.
private void buttonAdd_Click(object sender, EventArgs e) { //Create an xml document doc = new XmlDocument(); //If there is no current file, then create a new one if (!System.IO.File.Exists(PATH)) { //Create neccessary nodes XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8", "yes");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

XmlComment comment = doc.CreateComment("This is an XML Generated File"); XmlElement root = doc.CreateElement("Persons"); XmlElement person = doc.CreateElement("Person"); XmlAttribute name = doc.CreateAttribute("name"); XmlElement age = doc.CreateElement("Age"); XmlElement gender = doc.CreateElement("Gender"); //Add the values for each nodes name.Value = textBoxName.Text; age.InnerText = textBoxAge.Text; gender.InnerText = textBoxGender.Text; //Construct the document doc.AppendChild(declaration); doc.AppendChild(comment); doc.AppendChild(root); root.AppendChild(person); person.Attributes.Append(name); person.AppendChild(age); person.AppendChild(gender); doc.Save(PATH); } else //If there is already a file { //Load the XML File doc.Load(PATH); //Get the root element XmlElement root = doc.DocumentElement; XmlElement person = doc.CreateElement("Person"); XmlAttribute name = doc.CreateAttribute("name"); XmlElement age = doc.CreateElement("Age"); XmlElement gender = doc.CreateElement("Gender"); //Add the values for each nodes name.Value = textBoxName.Text; age.InnerText = textBoxAge.Text; gender.InnerText = textBoxGender.Text; //Construct the Person element person.Attributes.Append(name); person.AppendChild(age); person.AppendChild(gender); //Add the New person element to the end of the root element root.AppendChild(person); //Save the document doc.Save(PATH); } //Show confirmation message MessageBox.Show("Details have been added to the XML File.");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

//Reset text fields for new input textBoxName.Text = String.Empty; textBoxAge.Text = String.Empty; textBoxGender.Text = String.Empty; }

Figure 2 When the Add button is clicked, a new XmlDocument is created. This will represent the XML document that will be written to the file specified by the PATH private field. We now test if the file was already created using the Exists method of the System.IO.File class. If it does not exists, then create a new file and add the first record. If the file already exists, then we load the file and append the new record. Let's discuss the codes when the file is first created.
//Create neccessary nodes XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8", "yes"); XmlComment comment = doc.CreateComment("This is an XML Generated File"); XmlElement root = doc.CreateElement("Persons"); XmlElement person = doc.CreateElement("Person"); XmlAttribute name = doc.CreateAttribute("name"); XmlElement age = doc.CreateElement("Age"); XmlElement gender = doc.CreateElement("Gender");

The above code creates the neccessary nodes that will be added to our XML document. We first created an Xml Declaration using the XmlDeclaration class and the XmlDocument's CreateXmlDeclaration method. This method accepts three parameters; the version, encoding, and if the file is standalone. We then create a comment using the XmlComment class and the CreateComment method and pass the text that the comment will use to the method. I add this to demonstrate how to create and add comments. We then created the root element using the CreateElement method and the XmlElement class. We use the CreateElement class to create the root element, parent, and child elements. The method accepts one string argument which will be the name of the element. Next, we create the Person element which will hold the data typed by the user. The Person element has one attribute which is the name and an Age and Gender child elements. The CreateAttribute method accepts one string argument which is the name of the attribute. The attribute details is stored in an XmlAttribute object. Since the Person, Age, and Gender are elements, we used the CreateElement method and the XmlElement class for them.
name.Value = textBoxName.Text; age.InnerText = textBoxAge.Text; gender.InnerText = textBoxGender.Text;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We now add the values for some nodes that needed them. The values are taken from the text boxes with the user's input in it. The XmlAttribute object uses the Value property to access and set its value. The XmlElement uses InnerText (or InnerXml) to add values inside it.
doc.AppendChild(declaration); doc.AppendChild(comment); doc.AppendChild(root); root.AppendChild(person); person.Attributes.Append(name); person.AppendChild(age); person.AppendChild(gender);

We will now assemble the pieces together to form the full Xml document. First, we append the declaration to the XmlDocument using the AppendChild method which accepts an XmlNode and adds it as the last child of the document. We then append the comment which places it right below the declaration. Next, we append the root element which places itself below the comment. Please note that the order of appending nodes is important. Once the root element is appended, we now add the neccessary nodes inside the root element. We add the first person element to the root element. Then we add the name attribute using the Append method of its Attributes property. Finally we add the age and gender elements to the person element. Please note that it is not important which element you construct first. For example, we can construct and complete the person element first before adding it to the root element. Then we can add the the declaration, comment and root element in the proper order.
doc.Save(PATH);

This method saves the constructed Xml document to the specified file path. Let's nLet's now discuss the codes inside the else block which executes if the XML file is already created. This part will load the XML file, get the root element, and attach the new person to the list of persons the root element already has.
//Load the XML File doc.Load(PATH); //Get the root element XmlElement root = doc.DocumentElement;

Once the file using the specified path is loaded using the Load method, the root element of that file is retrieved using the DocumentElement property. Now that we have the access to the root element, we can now add more person elements. We constructed the new person element using the details typed by the user. Then, we add the new person to the end of the list of child elements of the root element. We then update the XML file by calling the Save method again. The final lines of code simply shows a success message and then clears the text fields so it can accept new inputs. Execute the application and type at least two person details. The XML file will be located to the path specified by the PATH variable. You can change this path to a different location. You will see the created XML file and the generated contents.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!--This is an XML Generated File--> <Persons> <Person name="John Smith"> <Age>30</Age> <Gender>Male</Gender> </Person> <Person name="Lisa Carter"> <Age>22</Age> <Gender>Female</Gender> </Person> </Persons>

You have now successfully generated an XML file using the XML DOM classes and methods. You can play with more of its method and experiment their functionality.

Reading from an XML File


Reading XML files is a neccessary technique to retrieve information from an XML file. Say for example, you store your configuration settings in an XML file, you can retrieve the settings from the XML file when the application is loading. We will create an example application to demonstrate how we can read data from an XML file. The example application we will create retrieves individual records from an XML file. We will provide buttons to navigate and read other existing records. Create a new Windows Forms Application and create a form similar to the one in Figure 1.

Figure 1 Use the names buttonFirst, buttonPrevious, buttonNext, and buttonLast for the four button controls. Use the names textBoxName, textBoxAge, and textBoxGender for the three text boxes. In this tutorial, we will be needing a sample XML file that contains the records that will be read by our applicatoin. Create a new XML file by clicking the Add New Item button in the toolbar.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Then choose XML file from the list of templates. Name the file sample.xml. Visual Studio will create an XML file for you. Delete its contents and use the following XML markup.
<?xml version="1.0" encoding="utf-8" ?> <Persons> <Person name="John Smith"> <Age>30</Age> <Gender>Male</Gender> </Person> <Person name="Mike Folley"> <Age>25</Age> <Gender>Male</Gender> </Person> <Person name="Lisa Carter"> <Age>22</Age> <Gender>Female</Gender> </Person> <Person name="Jerry Frost"> <Age>27</Age> <Gender>Male</Gender> </Person> <Person name="Adam Wong"> <Age>35</Age> <Gender>Male</Gender> </Person> </Persons>

Figure 1 The XML file contains five records of persons. Our application will start reading the first record and the user is allowed to see the other records by pressing the navigation buttons. Switch to code view and import the required System.Xml namespace.
using System.Xml;

Then add the following members to the Form1 class.


private private private private private XmlDocument doc; XmlElement root; XmlElement currentPerson; const string PATH = @"..\..\sample.xml"; int current = 0;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

private int max;

The doc of type XmlDocument is used to load an XML file and manipulate its content. The root variable will be used to hold the root element of the document. The currentPerson variable is used to hold the currently selected person element. We used the path "..\..\sample.xml" because the XML file we created earlier is located two directories up the executable file (.. means go up one directory). Again, you change this to a different location where the XML file is located. The current variable is used to track which record to show using a 0-based index. It is initialized to 0 to indicate that the current record is the first record. The max variable will be used to store the maximum index which will be usefull later. We need to create a utility method that will be used by the event handlers to show the details of the selected record to the text box. Add this method inside the Form1 class.
private void ShowDetails(XmlElement currentPerson) { textBoxName.Text = currentPerson.Attributes["name"].Value; textBoxAge.Text = currentPerson.GetElementsByTagName("Age")[0].InnerText; textBoxGender.Text = currentPerson.GetElementsByTagName("Gender")[0].InnerText; }

This method accepts the currently selected person. First, the value of the attribute "name" is retrieved and displayed in textBoxName. We used the Attribute property of the XmlElement class and used a string indexer which represents the name of the attribute. We then use the Value property of that specified attribute. We retrieve the value of the Age element by using the XmlElement's GetElementByTagName method. We pass the name of the element and the method searches all the child elements which has the specified name and returns them as a XmlNodeList. Since XmlNodeList is a collection, and there is only one expected result, we can access the first matching element by using the index 0.
textBoxAge.Text = currentPerson.GetElementsByTagName("Age")[0].InnerText;

This line might be quite confusing to beginners because I did everything in one line. The line simply means get the first element [0] of the collection returned by GetElementByTagName and then access the InnerText property of that first element. We can rewrite this one line of code into a much readable code but it will require more code as seen below.
XmlNodeList results = currentPerson.GetElementsByTagName("Age"); XmlNode first = results[0]; textBoxAge.Text = first.InnerText;

The next line of code is similar to the one for retrieving the Age but this time, the Gender element is searched by the GetElementsByTagName method.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

With the required utility method completed, we can now create our event handlers. Switch to Design View by clicking the Design tab or by using the shortcut Shift+F7. Click a blank space on the form to create an event handler for its Load event. Use the following code for the event handler.
private void Form1_Load(object sender, EventArgs e) { doc = new XmlDocument(); doc.Load(PATH); //Get root element root = doc.DocumentElement; //Determine maximum possible index max = root.GetElementsByTagName("Person").Count - 1; //Get the record at the current index currentPerson = (XmlElement)root.ChildNodes[current]; //Show the record information ShowDetails(currentPerson); }

This code will execute when the form is finished loading. It will retrieve and display the first record in the XML file. We first create an XmlDocument object. Then we load the XML file specified by the PATH using the Load method of the XmlDocument class. We retrieve the root element by using the DocumentElement property. We calculated the max possible index by getting all the child elements with the name of Person and then count them. We subtract it by 1 because indexes are 0-based. We will be needing the value of max later. We then retrieve the first person by using the ChildNodes method and pasing the value of current (which is now 0) as the index. The ChildNodes property is a collection of all the child nodes of a node, and by passing 0 as the index, we can retrieve the first record. Since the ChildNodes consists of XmlNode objects, we need to convert the node to an XmlElement so we can store it in an XmlElement object. Of course we can also use the GetElementsByTagName method but I used ChildNodes method to demonstrate to you an alternative technique. We now pass the retrieved element to the method we created earlier. Passing it to that method extracts the details from the currently selected person element. Return to the Designer and double click buttonFirst. Use the following event handler code.
private void buttonFirst_Click(object sender, EventArgs e) { current = 0; currentPerson = (XmlElement)root.ChildNodes[current]; ShowDetails(currentPerson); }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The first line resets the current index to 0 and then retrieves the child node at index 0. We then used the ShowDetails method to show the details of the retrieved XmlElement. Let's now add the event handler for the buttonPrevious.
private void buttonPrevious_Click(object sender, EventArgs e) { current = (current - 1 < 0) ? 0 : current - 1; currentPerson = (XmlElement)root.ChildNodes[current]; ShowDetails(currentPerson); }

The code is similar the buttonFirst's event handler except for the first line. The previous record is simply represented by the expression (current - 1). The first line uses the conditional statement testing whether the previous element is less than zero. If it is, we simply assign zero and prevent the user from accessing negative indexes. This is to prevent IndexOutOfRangeException. If the user is at the beginning record, then clicking buttonPrevious will have no effect. If the previous index is equal or greater than zero, then the current index is assigned with its value decreased by 1 to indicate that we are now showing the previous record. The record with the new index is then retrieved and shown using the ShowDetails method. Let's now add the event handler for buttonNext which shows the next record.
private void buttonNext_Click(object sender, EventArgs e) { current = (current + 1 > max) ? max : current + 1; currentPerson = (XmlElement)root.ChildNodes[current]; ShowDetails(currentPerson); }

Again, the only difference here is calculating the new current index. The next record is represented by the expression (current + 1) and we test if it will exceed the maximum possible index which is stored in variable max. If it does exceed, then we simply assign the value of max as the current index. If the next index is equal to or less than the max, then the next index is assigned as the new current index. The element at the new index is retrieved and shown to the user. Finally, add an event handler to buttonLast by double clicking it in the Designer. Use the following code.
private void buttonLast_Click(object sender, EventArgs e) { current = max; currentPerson = (XmlElement)root.ChildNodes[current]; ShowDetails(currentPerson); }

Since we will be retrieving the last record, the current index is simply assigned with the final index indicated by the value of max. The element is then retrieved and shown to the user.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Execute the application and you will be presented with the data of the first record. Click the buttons to move to other records in the XML file. You have now successfully created an application that reads records from an XML file using the classes of the XML DOM.

Using XPath to Select Nodes


XPath is a special query language the is specifically used for selecting nodes in an XML document. With these language, you don't have to search for the entire tree of the XML nodes. You will learn the basics of these language and apply it to a program. The two methods used for selecting nodes using the XPath language are the XmlNode.SelectNodes() and the XmlNode.SelectSingleNode(). The SelectNodes() method returns a XmlNodeList which contains all the nodes that matches the XPath string. Consider the following XML document.
<?xml version="1.0" encoding="utf-8" ?> <Persons> <Person name="John Smith"> <Age>30</Age> <Gender>Male</Gender> </Person> <Person name="Mike Folley"> <Age>25</Age> <Gender>Male</Gender> </Person> <Person name="Lisa Carter"> <Age>22</Age> <Gender>Female</Gender> </Person> <Person name="Jerry Frost"> <Age>27</Age> <Gender>Male</Gender> </Person> <Person name="Adam Wong"> <Age>35</Age> <Gender>Male</Gender> </Person> </Persons>

Figure 1 Suppose you want to get the age of every person, the code for doing that is:
XmlDocument document = new XmlDocument(); document.Load("Persons.xml"); XmlNodeList nodes = document.DocumentElement.SelectNodes("/Persons/Person/Age"); foreach(XmlNode node in nodes) { textBoxResult.Text += node.InnerText + "\r\n"; }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

After loading the document, we used the DocumentElement property which is of type XmlNode. We used the SelectNodes() method which accepts a string argument that contains the XPath query. The XPath query /Persons/Person/Age tells that get Age element that is a child of a Person element which is a child of the Persons element. All the matching nodes will then be returned as an XmlNodeList. We used a foreach loop to print each age in a text box. Figure 2 shows you some XPath operations that you can use to query specific nodes. XPath Query . .. * nodename / Description

Selects the current node. Selects the parent of the current node. Selects all the child of the current node. Selects all child nodes specified by the name. Selects the root node. Selects nodes from the current node that match the selection // expression no matter where they are. //* Selects all elements in the document. Selects the root element named element. Staring a path /element with a / means you are using an absolute path to an element. /element/* Selects all the child of the root element. element/* Selects all the child nodes of a child element. Selects the child elements which are a child of a specified child element/child element of the current node. Selects all elements with the specified name regardless of //element where they are in the document. Selects all child elements of the parent regardless of element//child where they are inside the parent element. Selects an attribute of the current node where attribute @attribute is the name of the attribute. Selects all the attributes specified by its name regardless of //@attribute where they are in the document. @* Selects all attribute of the current node. Selects an element with the specified element name and the specified element[i] index. text() Selects the text of all the child nodes of the current element. //text() Selects text of every element in the document. //element/text() Selects the text of all the matching elements. //element[name='value'] Selects all elements with a child containing a specified value. Selects all elements with the specified attribute having the specified //element[@att='value'] value. Figure 2 - XPath Operations

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

For example, if you want to select the current node, then you will use the . operator.
XmlNode current = document.DocumentElement.SelectSingleNode(".");

Notice that we used the XmlNode.SelectSingleNode() method to only select 1 node. In case of multiple results, it will return the first matching node. The method accepted the XPath string as its argument. Passing "." will result on returning the actual node that calls it. Also notice that the returned value is an XmlNode and not an XmlNodeList. Suppose you want to select all the Person elements which are children of the Persons node. You can use the following XPath query.
XmlNodeList personNodes = document.DocumentElement.SelectNodes("/Persons/Person");

Notice that we started the query with a slash (/). This indicates that we are using an absolute path. We start fromt he Persons root node, then we look at all the Person nodes which is a direct child of the root node. If we are to get every age of each person, then we can use the following code.
XmlNodeList personNodes = document.DocumentElement.SelectNodes("/Persons/Person/Age");

You can also use a relative path where the searching starts from the current node. For example, you can query all the Person node from the DocumentElement root node using the following code:
XmlNodeList personNodes = document.DocumentElement.SelectNodes("Person");

or the age of every person usign the following code:


XmlNodeList personNodes = document.DocumentElement.SelectNodes("Person/Age");

Notice that we didn't precede the XPath query with a / to indicate that we are using a relative path. We can also query nodes regardless of where they are in the document. This is usefull when you wan't to search the whole document and return all matching nodes. For example, if you want to query all the Gender nodes, even if you are starting from the root node, then you can use the following query:
XmlNodeList personNodes = document.DocumentElement.SelectNodes("//Gender");

We precede the element name with // to indicate that the whole document should be searched. The query will now return all the matching nodes wherever they are in the document. If you want

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

to limit the area where the searching will be done, then you can specify the parent node or root node where the searching will start.
XmlNodeList personNodes = document.DocumentElement.SelectNodes("/Persons//Gender");

The above code will search for all Gender elements under the Persons node. If you want to query specific elements, then you can use their index. The following queries the third child of the Persons element.
XmlNode personNodes = document.DocumentElement.SelectSingleNode("/Persons/Person[3]");

Since we are querying a single node, we used the SelectSingleNode() method. The third Person element is represented by Person[3] where we used 3 as the index. Note that indices are base-1, so the counting starts with 1 and not 0 as opposed to arrays in C#. If you want to search for all the person who has a gender of male, then you can use the following code.
XmlNodeList personNodes = document.DocumentElement.SelectNodes("//Person[Gender='Male']");

Since we used a double slash (//), then the whole document will be searched. Inside the bracket, we specify the name of the child element and after that, we specified what the value should be. The value must be enclosed in single quotes if it represents a string. When dealign with attributes of elements, you can use the @ operator followed by the name of the attribute. For example, the following prints all the name of every person.
XmlNodeList list = document.DocumentElement.SelectNodes(@"//Person/@name"); foreach (XmlNode node in list) { textBox1.Text += node.Value + "\r\n"; }

XPath is a big topic and only some basic components was discussed here. If you want to study everything about XPath, then you can go to the following link: http://www.w3schools.com/xpath/default.asp

Using Fonts
What if you want to change or modify the font of a control in a windows application? The System.Drawing.Font class allows you to create fonts that you can use or assign to the Font properties of different controls or components. The following table shows some useful properties of the Font class.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Property Description Bold Specifies whether the font is bold. FontFamily Specifies the font family used by the font. Height Specifies the line spacing of the font. Italic Specifies whether the font is italicized. Name Specifies the face name of the font. Size Specifies the size of the font using the unit specified by the Unit property. Strikeout Specifies whether the font has a horizontal line in through the font. Style Specifies the style or styles applied to the font. Underline Specifies whether the font has a line underneath it. Unit Specifies the unit to be used when specifying the size of the font. Figure 1 - System.Drawing.Font Properties

Creating a Font Object


The following code calls the constructor of the Font class and uses the Times New Roman font family and size 12.
Font myFont = new Font("Times New Roman", 12);

The font family specifies the appearance of the font. Common font families include Arial, Verdana, Courier New, Times New Roman, and Sans Serif. Note that before using a font family for a Font object, the actual font must be installed in your system. The previously mentioned font families are already installed in a Windows system by default. You can also use the System.Drawing.FontFamily class to create a FontFamily object using a specified family name. You can then use an overloaded constructor of the Font class and pass the FontFamily object to it.
FontFamily family = new FontFamily("Arial"); Font myFont = new Font(family, 12);

Using the FontFamily object allows you to use some of its method such as GetCellAscent(), GetCellDescent(), GetEmHeight(), and GetLineSpacing(). Another constructor allows you to specify the style of the font. We can use values from the System.Drawing.FontStyle enumeration. The following creates a bold font.
Font myFont = new Font("Verdana", 14, FontStyle.Bold);

Another useful constructor of the Font class allows you to use the properties of another Font object and then specify a new style that will be applied to it. Suppose we have a label that we want to italicized. We can pass the Font of the label and then use the FontStyle.Italic value.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Font myFont = new Font(label1.Font, FontStyle.Italic);

You can also specify the unit to be used by the size. For example, size 12 can either be 12 inch, 12 pixels, or 12 millimeters. We can use the values of the System.Drawing.GraphicsUnit enumeration and another constructor of the Font object. The following code creates a font with size of 12 pixels.
Font myFont = new Font("Times New Roman", 12, GraphicsUnit.Pixel);

We can then assign our created font to the Font property of a control such as a label to change its font based on the values we have given when creating the Font object.
label1.Font = myFont;

Font Families
There are many font families you can use for your font depending on which fonts are installed in your system. To see which fonts are available, in Windows 7, go to Start > Control Panel > Appearance and Personalization > Fonts. The following screenshot shows you some example of font families and how they look.

Figure 2 - Different Font Families You can either pass the name of the font family as string or create a FontFamily object when creating the Font object.
Font myFont = new Font("Consolas", 14); //or Font myFont = new Font(new FontFamily("Consolas"), 14);

Font Sizes
When dealing with font sizes, there are two things to consider, the actual size and the units to use. We can use the Size property of the font to specify the font size.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

myFont.Size = 12;

We can determine what unit to use by using the values from the System.Drawing.GraphicsUnit enumeration which contains the following. Description Specifies the unit of measure of the display device. Typically pixels for video Display displays, and 1/100 inch for printers. Pixel Specifies a device pixel as the unit of measure. Point Specifies a printer's point (1/72 inch) as the unit of measure. Inch Specifies the inch as the unit of measure. Document Specifies the document unit (1/300 inch) as the unit of measure. Millimeter Specifies the millimeter as the unit of measure. World Specifies the world coordinate system unit as the unit of measure. Figure 3 - System.Drawing.GraphicsUnit You can use the Unit property of the Font class to specify the unit to use when sizing the font.
myFont.Unit = GraphicsUnit.Pixel;

Values

Font Styles
We can apply different font styles to a font. The Font class contains some property which accepts a boolean value specifying if a certain style is applied. For example, you can use the Bold property and set it to true to make a font bold, or the Italic property to italicized a font.
myFont.Bold = true; myFont.Italicized = true;

The code above makes the font bold and italicized at the same time. You can also use the Strikeout and Underline properties to apply those styles to a font. You can also use the values of the System.Drawing.FontStyles enumeration which contains different font styles you can apply to a font. Value Description Regular No style. Bold Bold text. Italic Italic text. Underline Underlined text. Strikeout Text with a line through the middle. Figure 4 - System.Drawing.FontStyle Enumeration
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

The following screenshot shows you how each style will look.

Figure 5 - Different Font Styles We can use a constructor of the Font class to apply a new style.
myFont = new Font(myFont, FontStyle.Bold);

We can also apply multiple styles to the font by using the bitwise OR operator.
myFont = new Font(myFont, FontStyle.Bold | FontStyle.Italic);

The line above applies both bold and italic font styles. The Styles property of the Font allows us to get the styles applied to a font. If we want to remove a particular style from a font with multiple styles, then we can use the bitwise XOR operator.
myFont = new Font(myFont, myFont.Style ^ FontStyle.Bold);

The bitwise XOR operator can also serve as a toggle mechanism because if removes a style if it exist as a style of the font or applies the style if it is not yet applied to a font. The bitwise AND operator is useful if you want to check if a certain style is already applied to a font.
if ( (myFont.Style & FontStyle.Bold) == FontStyle.Bold) MessageBox.Show("The font is bold.");

Notice that we enclosed the expression in parentheses because the == operator has higher precedence. We tested if the result of the expression is equal to the style being tested.

Modifying Fonts (An Example)


The following is an example application showing how we can modify a controls Font propery using other controls and components. We will use the techniques we have learned earlier to modify the font. Create a new Windows Forms Application and name it FontDemo. Below shows the GUI of the application we will create.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Label 1 2 3 4 5 6 7 8

Properties Values Text Sample Text TextBox fontTextBox TextAlignment Center CheckBox boldCheckBox Text Bold CheckBox italicCheckBox Text Italic CheckBox underlineCheckBox Text Underline CheckBox strikeoutCheckBox Text Strikeout Minimum 10 TrackBar sizeTrackBar Maximum 40 Button colorButton Text Pick Color ComboBox familyComboBox Text Choose Family

Type

Name

The user can choose from different styles using the check boxes (2 to 5) provided. When checked, the style is applied to the text in the text box. When unchecked, the style is removed from the styles of the font. We provide a combo box that will contain the names of all the installed font in your system. The user can then choose from those names and it will applied to the font of the text box. The button (7) when clicked, will show a ColorDialog to allow the user
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

to pick a color and apply it to the font. The track bar (6) is used to change the font size of the text inside the text box based on the position of the thumb of the track bar.

Using Bitwise XOR to Apply or Remove a FontStyle


Let us now add the functionality of our application. We will start with the check boxes that provides the style for the font. Double click each check box to generate CheckedChange event handlers. Use the following event handlers.
private void boldCheckBox_CheckedChanged(object sender, EventArgs e) { fontTextBox.Font = new Font(fontTextBox.Font, fontTextBox.Font.Style ^ FontStyle.Bold); } private void italicCheckBox_CheckedChanged(object sender, EventArgs e) { fontTextBox.Font = new Font(fontTextBox.Font, fontTextBox.Font.Style ^ FontStyle.Italic); } private void underlineCheckBox_CheckedChanged(object sender, EventArgs e) { fontTextBox.Font = new Font(fontTextBox.Font, fontTextBox.Font.Style ^ FontStyle.Underline); } private void strikeThroughCheckBox_CheckedChanged(object sender, EventArgs e) { fontTextBox.Font = new Font(fontTextBox.Font, fontTextBox.Font.Style ^ FontStyle.Strikeout); }

For each event handler, we created a new Font using the constructor that accepts a Font and a new font style. In the first argument of each constructores, we passed the actual font of the fontTextBox to preserve the settings such as the size and the family used. In the second argument of each constructors, we used the bitwise XOR operator between the current Style of the fontTextBox and the style to be applied or removed. Recall that bitwise XOR can act as a toggle mechanism that applies a style if that style does not yet applied, or remove it if its already applied.

Changing Font Size


We used a TrackBar control to allow the user to change the size of the font of the fontTextBox. The TrackBar's Minimum and Maximum properties has been set to 10 and 40 respectively so the user can only select font sizes from 10 to 40. Double click the track bar to generate an event handler for its Scroll event. Use the following event handler.
private void sizeTrackBar_Scroll(object sender, EventArgs e) {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

fontTextBox.Font = new Font(fontTextBox.Font.FontFamily, sizeTrackBar.Value, fontTextBox.Font.Style, fontTextBox.Font.Unit); }

We used the Font's constructor that accepts four arguments. We simply passed the current family, style, and unit used by fontTextBox to preserve those settings when we change the size of the font. The second argument specifies the size of the new font so we used the TrackBar's Value property to retrieve the value selected by sizeTrackBar.

Loading All Installed System Fonts


The combo box (9) will be used to select the font family used by the text of the text box. We can either enumerate a list of font family names, or you can load the names of all the installed fonts in your system. We will do the latter and add the list when the form has loaded so double click the title bar of the form to generate an event handler for the Form's Load event.
private void Form1_Load(object sender, EventArgs e) { InstalledFontCollection fonts = new InstalledFontCollection(); foreach (FontFamily font in fonts.Families) { familyComboBox.Items.Add(font.Name); } }

The InstalledFontCollection class allows you to access and enumerate all the fonts installed in your system. Please note that this class is contained inside the System.Drawing.Text namespace so you must import it first at the top of the program. We used a for loop to iterate each of the FontFamily item contained inside the Families property of the InstalledFontCollection class. The Famillies property contains a collection of FontFamily objects which represents the installed fonts. Back in the designer, double click the combo box to generate its SelectedIndexChange event handler. Use the following event handler.
private void familyComboBox_SelectedIndexChanged(object sender, EventArgs e) { fontTextBox.Font = new Font(familyComboBox.SelectedItem.ToString(), fontTextBox.Font.Size, fontTextBox.Font.Style, fontTextBox.Font.Unit); }

We create a new Font object using the constructor of Font that accepts four arguments. The most notable one is the first one which specifies the font family to use. We use the SelectedItem property of familyComboBox to get the item that is selected in the familyComboBox and convert it to text using the ToString() method. We passed the current size, style, and unit used by the fontTextBox to the constructor to preserve those settings when the font family is changed.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Changing the Color Using ForeColor Property


The color of the font is actually not handled by the Font itself. We use the ForeColor property of the control to set the color of the text of a control. Double click colorButton and use the following code for its Click event.
private void colorButton_Click(object sender, EventArgs e) { ColorDialog colorDialog = new ColorDialog(); if (colorDialog.ShowDialog() == DialogResult.OK) fontTextBox.ForeColor = colorDialog.Color; }

When you click the button, we creat a ColorDialog and show it to the user using ShowDialog() method to allow him/her to select a color. We then tested if the value returned by ShowDialog() is DialogResult.OK which means the user clicked the OK button in the dialog. If so, then we applied the color choosen by the user to the ForeColor property of the control using the ColorDialog's Color property.

Comparing Objects with IComparable<T> and IComparer<T>


There are two useful interfaces that are useful for comparing user-defined objects. These are the IComparable<T> and IComparer<T> interfaces. The IComparable interface is implemented in a class to allow comparason between it and another object. The IComparer<T> is implemented by a seperate class which does the comparison of two objects. Note that older, non-generic versions are available to use but the generic versions are much easier and you won't be needing to convert the objects to be compared.

The IComparable<T> Interface


Let's first take a look at how we can use the IComparable interface. The following example shows a class which implements the IComparable<T> interface.
1 public class Person : IComparable<Person> 2 { 3 public string FirstName { get; set; } 4 public string LastName { get; set; } 5 public int Age { get; set; } 6 7 public int CompareTo(Person other) 8 { 9 if (this.Age > other.Age) 10 return 1; 11 else if (this.Age < other.Age) 12 return -1; 13 else 14 return 0;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

15 16}

Example 1 When a class uses the IComparable<T> interface, you need to create an implementation for its single method which is the CompareTo() method. The CompareTo() method returns an integer value. It also accepts one argument which is the object to be compared to the current object. Inside our CompareTo() method in Example 1, we compared the age of the current person to the age of the other person passed to the method. By convention, if the current object is considered greater than the other object, then a value greater than 0 should be returned. We simply used 1 as the value but you can use any value greater than 0. If the current object is considered less than the other object, then a value less than 0 should be used as seen in line 12. If the two objects are considered equal, then the value 0 should be returned. The following code shows the Person object that implemented the IComparable<T> in action. The program will determine the youngest and the oldest among three Persons.
1 public class Program 2 { 3 static void Main(string[] args) 4 { 5 Person person1 = new Person { FirstName = "John", LastName = 6 "Smith", Age = 21 }; 7 Person person2 = new Person { FirstName = "Mark", LastName = 8 "Logan", Age = 19 }; 9 Person person3 = new Person { FirstName = "Luke", LastName = 10"Adams", Age = 20 }; 11 12 Person youngest = GetYoungest(person1, person2, person3); 13 Person oldest = GetOldest(person1, person2, person3); 14 15 Console.WriteLine("The youngest person is {0} {1}.", 16 youngest.FirstName, youngest.LastName); 17 Console.WriteLine("The oldest person is {0} {1}.", 18 oldest.FirstName, oldest.LastName); 19 Console.ReadKey(); 20 } 21 22 private static Person GetYoungest(Person person1, Person person2, 23Person person3) 24 { 25 Person youngest = person1; 26 27 if (person2.CompareTo(youngest) == -1) 28 youngest = person2; 29 30 if (person3.CompareTo(youngest) == -1) 31 youngest = person3; 32 33 return youngest; 34 } 35 36 private static Person GetOldest(Person person1, Person person2, Person

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

37person3) 38 { 39 Person oldest = person1; 40 41 if (person2.CompareTo(oldest) == 1) 42 oldest = person2; 43 44 if (person3.CompareTo(oldest) == 1) oldest = person3; return oldest; } }

Example 2
The youngest person is Mark Logan. The oldest person is John Smith.

Lines 5-7 creates three Person objects with sample values that we can use. Lines 9-10 creates variables that will hold references to the youngest and oldest Person. In line 9, we called the GetYoungest() method which is defined in lines 19-30. It accepts the three Persons that we will be comparing against each other. Line 21 assumes that the first person is the youngest. We test if person2 is younger than the current youngest person by using the implemented CompareTo() method of the IComparable<T> interface. Inside that method, the age of person2 is compared to the age of the current youngest person. If the person2's age is lower, then -1 should be returned and person2 will be considered as the new youngest person as seen in line 24. Line 26-27 uses the same technique to person3. After the comparisons, the youngest person is returned in line 29. Line 10 calls the GetOldest() method which is defined in lines 32-43. The code is simillar to the GetYoungest() method except that it compares if a person's age is greater than the current oldest person. Therefore, we are expecting a return value of 1 instead of -1 when you call the CompareTo() method. Lines 12-15 prints the youngest and oldest person's name.

The IComparer<T> Interface


The IComparer<T> is implemented by a seperate class. As the name of the interface suggests, implementing it makes a comparer class. For example, you can create multiple comparers for a Person class. You can make a comparer which compares the age, or a comparer which compares the FirstName or LastName of every person. The following examples uses the Person class created in Example 1. We will be creating three comparer classes for the FirstName, LastName, and Age a person.
1 public class FirstNameComparer : IComparer<Person> 2 { 3 public int Compare(Person person1, Person person2) 4 { 5 return person1.FirstName.CompareTo(person2.FirstName); 6 } 7 }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

8 9 public class LastNameComparer : IComparer<Person> 10{ 11 public int Compare(Person person1, Person person2) 12 { 13 return person1.LastName.CompareTo(person2.LastName); 14 } 15} 16 17public class AgeComparer : IComparer<Person> 18{ 19 public int Compare(Person person1, Person person2) 20 { 21 return person1.CompareTo(person2); 22 } 23}

Example 3 Using the IComparer<T> class requires you to implement one method named Compare() which accepts two T objects and returns an int result. Since we used IComparer<Person> interface, then the Compare() method will automatically have two Person parameters. The FirstNameComparer compares the first names of two person being compared. Inside it's Compare() method, we simply used the already defined CompareTo() method of the String class(since FirstName property is string) for simplicity and return the value it will return. We do the same for the LastNameComparer class but we compare the LastName of two persons instead. The Compare() method of the AgeComparer class uses the CompareTo() method of the actual Person class we defined in Example 1 to save as from repeating the same code again. The Compare() method should return 0 if both parameters are considered equal, a value greater than 0 if the first parameter is greater than the second parameter, and a value less than 0 if the first parameter is less than the second parameter. The following program asks a user which property to use to sort a list of person.
1 public class Program 2 { 3 static void Main(string[] args) 4 { 5 List<Person> persons = new List<Person> { 6 new Person { FirstName = "John", LastName = "Smith", Age = 7 21 }, 8 new Person { FirstName = "Mark", LastName = "Logan", Age = 9 19 }, 10 new Person { FirstName = "Luke", LastName = "Adams", Age = 1120 }}; 12 13 Console.WriteLine("Original Order"); 14 foreach(Person p in persons) 15 Console.WriteLine("{0} {1}, Age: {2}", p.FirstName, p.LastName, 16p.Age); 17 18 Console.WriteLine("\nSort persons based on their:"); 19 Console.WriteLine("[1] FirstName\n[2] LastName\n[3]Age"); 20

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

21 Console.Write("Enter your choice: "); 22 int choice = Int32.Parse(Console.ReadLine()); 23 24 ReorderPersons(choice, persons); 25 26 Console.WriteLine("New Order"); 27 foreach (Person p in persons) 28 Console.WriteLine("{0} {1}, Age: {2}", p.FirstName, p.LastName, 29p.Age); 30 } 31 32 private static void ReorderPersons(int choice, List<Person> persons) 33 { 34 IComparer<Person> comparer; 35 36 if (choice == 1) 37 comparer = new FirstNameComparer(); 38 else if (choice == 2) 39 comparer = new LastNameComparer(); 40 else comparer = new AgeComparer(); persons.Sort(comparer); } }

Example 4
Original Order John Smith, Age: 21 Mark Logan, Age: 19 Luke Adams, Age: 20 Sort persons based on their: [1] FirstName [2] LastName [3]Age Enter your choice: 1 New Order John Smith, Age: 21 Luke Adams, Age: 20 Mark Logan, Age: 19 Original Order John Smith, Age: 21 Mark Logan, Age: 19 Luke Adams, Age: 20 Sort persons based on their: [1] FirstName [2] LastName [3]Age Enter your choice: 2 New Order Luke Adams, Age: 20 Mark Logan, Age: 19 John Smith, Age: 21

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Original Order John Smith, Age: 21 Mark Logan, Age: 19 Luke Adams, Age: 20 Sort persons based on their: [1] FirstName [2] LastName [3]Age Enter your choice: 3 New Order Mark Logan, Age: 19 Luke Adams, Age: 20 John Smith, Age: 21

Lines 5-8 creates a List of Person objects containing three Person with predefined values for each property. Lines 11-12 shows the origninal order of the persons. Lines 14-15 shows the list of options that the user can choose as the basis of the sorting. Lines 17-18 asks the user of the his/her choice. Line 20 calls the ReorderPersons() method defined in lines 27-39. The method accepts the choice and the list of persons to sort. Inside the method, we defined a variable that will hold the type of comparer class to use. We used the IComparer<Person> as the type so it can hold any comparer class since they all implement this interface. We look at the different possible values of choice in lines 31-36 and assign the proper comparer based on the number value. In line 38, we used the Sort() method of the List<T> class. The Sort() method has an overloaded version which accepts an an IComparer<T> object. We passed the created comparer class in line 29 containing whichever type of comparer it has based on the choice. The Sort() method will then sort the Person object using the comparer class that we provided.

Simple Calculator
We will create a simple calculator using C# and Windows Forms that allows the user to do the 4 basic mathematical operations. Start by creating a new Windows Forms Application and name it SimpleCalculator. Create a form similar to the one presented in Figure 1. The left one shows the actual GUI and the right one shows the labeled version that will specify the names of each control.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 Label Name Label Name 0 zeroButton 9 nineButton 1 oneButton 10 addButton 2 twoButton 11 subtractButton 3 threeButton 12 multiplyButton 4 fourButton 13 divideButton 5 fiveButton 14 equalsButton 6 sixButton 15 dotButton 7 sevenButton 16 outputTextBox 8 eightButton Figure 2 You can change the font size of the buttons to a bigger one so it will be easier to see the text inside them. Also set the TextAlign property of the outputTextBox to Right, ReadOnly to True, and BackColor to White. From the Design View, switch to the Code Editor by hitting F7. The program will use the following class variables so add them.
private private private private private private bool isFirst = true; bool shouldClear = true; double firstOperand; double secondOperand; double result = 0; string symbol = String.Empty;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The isFirst variable will tell if the first inputs clicked by the user is the first operand. The shouldClear variable is used to determine if the outputTextBox should be cleared to welcome a new input. The firstOperand and the secondOperand variables are used to store the operands involved in calculations. The result variable will store the answer. We used double as the data type for the firstOperand, secondOperand, and result variables so the result will be accurate when doing a division operation. The symbol variable will hold the current mathematical symbol to be used in the calculation. The numbers buttons (0-9) will share a single event handler. This prevents us from writing repetitive code. Inside the Form1 class, type the following event handler.
1 private void numberButton_Click(object sender, EventArgs e) 2 { 3 Button sourceButton = (sender as Button); 4 double oldNumber, buttonNumber, newNumbernewNumber; 5 6 if (shouldClear) 7 { 8 outputTextBox.Clear(); 9 oldNumber = 0; 10 shouldClear = false; 11 } 12 else 13 { 14 oldNumber = Double.Parse(outputTextBox.Text); 15 } 16 17 18 buttonNumber = Double.Parse(sourceButton.Text); 19 newNumbernewNumber = (oldNumber * 10) + buttonNumber; 20 21 if (isFirst) 22 { 23 firstOperand = newNumbernewNumber; 24 } 25 else 26 { 27 secondOperand = newNumbernewNumber; 28 } 29 30 outputTextBox.Text += sourceButton.Text; 31 32 Calculate(symbol); 33}

Example 1 Go back to the Designer View and add the event handler to the Click event of each number button (zeroButton to nineButton). Select a button and go to the Events section of the Properties Window. Find the Click event and select the name of the event handler we created.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

After you have assigned the event handler to each of the number buttons' Click event, let's switch back to the Code Editor and explain the event handler we created in Example 1. Since the event handler will be used by multiple buttons, we need to determine the source button using the sender parameter of the event handler. In line 3, we convert the sender to a Button first because the sender is of type object. Line 4 declares three variables that will be used later for constructing the value of the operand. The oldNumber will contain the current content of the outputTextBox. buttonNumber will contain the digit represented by the button that was pressed. newNumber will contain the calculated new value after a number button is pressed. Line 6 tests if we should clear the text box. To better understand why we place this code, when you are using a normal calculator, we type a number and press the operation symbol. After pressing the operation symbol, when you press a new number, the current number displayed (which is the older number) will be cleared and the new number you typed will replace it. The value of should clear will be true if you press an operation button as you will see later. If this is true, it means that an operation symbol was pressed, so we clear the outputTextBox in line 8. Line 9 puts the value 0 to the oldNumber since we cleared the outputTextBox. Line 10 sets the shouldClear variable to false so the next digits clicked by the user will not reset the outputTextBox. If we omit line 10 and supposed that the user will type 12, pressing 1 will show the number 1 in the outputTextBox, but since we did'nt set the shouldClear to false, pressing 2 will clear the outputTextBox, and instead leaving you a value of 2 instead of 12. If the shouldClear variable is false, then we convert and place the value of the outputTextBox to the oldNumber variable. Line 18 gets the Text property of the source button, convert it and place it in the buttonNumber variable. For example, if you click the sevenButton, then it will be the source button and its Text property contains the number 7. Line 19 calculates the new value. For example, if we have a value 7 for the oldNumber (and also displayed in the outputTextBox), and then we click the number 2, the result should be 72. We used the formula in Line 19 where we simply multiply the old value by 10 and add the value of the button clicked by the user. The result is then assigned to the newNumber variable. Lines 21-28 checks if isFirst is true, which indicates that the user is giving the first input. We need this so that we can properly determine the first operand of the calculation. If this is the first
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

input of the user, then the calculated new value will be assigned as the firstOperand (line 23). Otherwise, we consider it as the secondOperand instead. Line 30 simply appends the value of the button clicked by the user to the outputTextBox. Finally, line 32 uses the Calculate() method which we will create next. The following is the definition of the Calculate() method that you should add inside the class.
1 private void Calculate(string operatorSymbol) 2 { 3 if (isFirst) 4 { 5 result = firstOperand; 6 return; 7 } 8 9 switch (operatorSymbol) 10 { 11 case "+": 12 result = firstOperand + secondOperand; 13 break; 14 case "-": 15 result = firstOperand - secondOperand; 16 break; 17 case "*": 18 result = firstOperand * secondOperand; 19 break; 20 case "/": 21 result = firstOperand / secondOperand; 22 break; 23 } 24}

Example 2 The calculate method has one parameter which indicates the symbol of the operation to be used. Lines 3-7 tests again if the user is giving the first input. If so, then no calculation is needed for now and the what the user types will be the result. Line 6 exits the method. If the input is not the first input, then we enter a switch structure in lines 9-23. We test which operator to be used. For example, if the operator to be used is "+" then we add the firstOperand and the secondOperand and place the result in the result variable. We now know how our calculator will calculate the result given that the symbol to be used is known. We now need to add the functionality for the four operation buttons so the Calculate() method will know which operation to used. Type the following event handler which will be shared by the four operation buttons.
1 private void operatorButton_Click(object sender, EventArgs e) 2 { 3 firstOperand = result; 4 5 Button sourceButton = (sender as Button); 6 string operatorSymbol = sourceButton.Text; 7

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

8 9 10 11 12 13 14}

if (isFirst) isFirst = false; shouldClear = true; symbol = operatorSymbol; outputTextBox.Text = result.ToString();

Example 3 After typing the event handler, go back to the Designer and assign the event handler we created to the addButton, subtractButton, multiplyButton, and divideButton's Click events. Line 3 assigns the value of the result to the firstOperand. This is so the user can continue doing calculations after the first one. For example, if the user adds 1 and 2, and decided to add 3, the result of (1 + 2) will now be the first operand and 3 will be the second operand. We also retrieved and convert the source button in line 5 so we can extract the symbol of the button in line 6. Line 8 tests if the isFirst is true. If so, we set it to false to indicate that the next input will no longer be the first input. Line 11 sets shouldClear so after clicking a symbol button, the next input will clear the text box and will not be appended to the previous input. Line 12 assigns the corresponding symbol of the button that was clicked. This is the line that will determine which operation will be used by the Calculate() method. When we called the Calculate() method in Line 32 of Example 1, we passed the value of the symbol and the right operation was performed. Continuing in Example 3, line 13 shows the value of the result to the outputTextBox. Only two buttons left. Double click the equalButton and use the following event handler.
private void equalsButton_Click(object sender, EventArgs e) { outputTextBox.Text = result.ToString(); isFirst = true; shouldClear = true; }

Example 4 The button simply shows the result of the calculations. It also resets the value of isFIrst to true and sets shouldClear to true. Double click the clearButton and use the following event handler.
private void clearButton_Click(object sender, EventArgs e) { outputTextBox.Text = "0"; result = 0; isFirst = true; shouldClear = true; }

Example 5

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The clearButton resets our calculator. SInce calculators start with zero when you open them, we set the text of the outputTextBox to 0. We also reset the result, isFirst, and shouldClear variables back to their original values. Run the program and test your calculator.

Congratulations! You have now completed our simple calculator application made with C# and Windows Forms controls. Download Project: SimpleCalculator

Simple Text Editor


We will be creating a simple text editor that allows you to format the text, save, and open an existing file. This lesson uses the ToolStrip and RichTextBox controls as its main components. Start by creating a new Windows Forms Application and name it SimpleTextEditor. Drag a ToolStrip control from the Toolbox to the form. We will use the standard items for our tool bar so click the square button to the upper right edge of the ToolStrip and choose Insert Standard Items.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Standard items will now show up in the ToolStrip control. Let's remove the items that we won't need. Delete the button for printing and the help button. Your form should now look like this:

Add a separator and three new ToolStripButtons to the ToolStrip. Name the buttons boldToolStripButton, italicToolStripButton, and underlineToolStripButton. The images that they will be using can be downloaded using the following link: formatIcons.rar After you have downloaded and extracted the icons, assign each icon to their corresponding ToolStripButton using their Image property. If the files are hidden when you are browsing them,

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

be sure that you use All Files as the file type. After you set the images for the three buttons, your form should now look like this:

Let's add another item in to the ToolStrip that will determine the font to be used by the editor. Add another separator and a ToolStripComboBox control. Increase the width of your form so the new item will not overflow. Name the combo box fontsToolStripComboBox. Your form should now look like this:

Add another ToolStripComboBox to the ToolStrip that will determine the font size. Name it sizeToolStripComboBox. We need to resize it to a smaller width. One way to resize a ToolStrip item is by setting its AutoSize property to False. You also need to set the AutoSize property of

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

the ToolStrip itself to False. Finally, set the Size property to 50, 23 to make the width smaller and look more like the one seen in word processors. Using its Items property, provide several font sizes that the user can choose from (5,8,10,12,14,16,18,20,24,30,45,72). You form should look like this:

Finally for our user interface, we need to add a RichTextBox control where the actual text will be displayed and typed. Drag a RichTextBox control from the toolbox to the form and change its Dock property to Fill. Name the control editorRichTextBox. Our final user interface looks like the following:

Adding Functionality to the Simple Text Editor


COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

We will now start the coding process for our Simple Text Editor. We will start at the first button which is the New Button. Double click that button and use the following event handler for its Click event.
private void newToolStripButton_Click(object sender, EventArgs e) { editorRichTextBox.Clear(); }

The code simply clears the content of the RichTextBox editor. The next button allows us to open an existing file. We will limit the user to only openning text and RTF files. Double click the button and use the following event handler.
private void openToolStripButton_Click(object sender, EventArgs e) 1 { 2 OpenFileDialog openDialog = new OpenFileDialog(); 3 openDialog.InitialDirectory = @"C:\"; 4 openDialog.Multiselect = false; 5 openDialog.DefaultExt = "txt"; 6 openDialog.Filter = "Text Files|*.txt|RTF|*.rtf"; 7 8 DialogResult result = openDialog.ShowDialog(); 9 10 if (result == DialogResult.OK) 11 { 12 string extension = 13 System.IO.Path.GetExtension(openDialog.FileName); 14 15 if (extension == ".txt") 16 editorRichTextBox.LoadFile(openDialog.FileName, 17 RichTextBoxStreamType.PlainText); 18 else 19 editorRichTextBox.LoadFile(openDialog.FileName, 20 RichTextBoxStreamType.RichText); 21 } 22 }

When you click the Open button, an OpenFileDialog will show up. Lines 3-7 are involve in creating and initializing the properties for the OpenFileDialog. Line 7 specifies that the user can only open .txt and .rtf files using the OpenFileDialog.Filter property. Line 9 opens the dialog using the ShowDialog() method. The user will choose the file to open. If the user presses the Open button of the dialog, then ShowDialog() will return DialogResult.OK. We test this in line 11, and if so, we first retrieve the extension in line 13 to determine what kind of file to show. We used the System.IO.Path.GetExtention() method and pass the filename of the selected file to extract the extention of it. If the extention is for a plain text file (.txt), then we used the LoadFile() method of the RichTextBox and pass RichTextBoxStreamType.PlainText as the second parameter to indicate that the RichTextBox should treat the contents of the file as a plain text. Otherwise, we used the RichTextBoxStreamType.RichText to indicate that the RichTextBox should read and render the RTF codes within the file being openned.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The next button which is the Save button has a similar code to the Open button, but it uses the SaveDialog and the SaveFile() method of the RichTextBox.
private void saveToolStripButton_Click(object sender, EventArgs e) { SaveFileDialog saveDialog = new SaveFileDialog(); saveDialog.InitialDirectory = @"C:\"; saveDialog.DefaultExt = "txt"; saveDialog.Filter = "Text Files|*.txt|RTF|*.rtf"; DialogResult result = saveDialog.ShowDialog(); if (result == DialogResult.OK) { string extension = Path.GetExtension(saveDialog.FileName); if (extension == ".txt") editorRichTextBox.SaveFile(saveDialog.FileName, RichTextBoxStreamType.PlainText); else editorRichTextBox.SaveFile(saveDialog.FileName, RichTextBoxStreamType.RichText); } }

The next buttons are used for cutting, copying, and pasting texts. Use the following event handlers for them.
private void cutToolStripButton_Click(object sender, EventArgs e) { editorRichTextBox.Cut(); } private void copyToolStripButton_Click(object sender, EventArgs e) { editorRichTextBox.Copy(); } private void pasteToolStripButton_Click(object sender, EventArgs e) { editorRichTextBox.Paste(); }

We simply used the methods provided by the RichTextBox control for cutting, copying, and pasting texts. The next button allows the selected text in the editor to be bold. Double click the Bold button and use the following for its event handler.
1 private void boldToolStripButton_Click(object sender, EventArgs e) 2 { 3 try 4 { 5 editorRichTextBox.SelectionFont = new

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

6 Font(editorRichTextBox.SelectionFont, 7 editorRichTextBox.SelectionFont.Style ^ FontStyle.Bold); 8 } 9 catch 10 { 11 editorRichTextBox.SelectionFont = new 12Font(fontsToolStripComboBox.SelectedText, 13 Single.Parse(sizeToolStripComboBox.Text), FontStyle.Bold); } }

Let's look at lines 5-6. We used the SelectionFont property of the RichTextBox control to modify the font style. We used the contructor for the Font to assign a new modified font. The first parameter passes an existing font (so it will preserve the size, font family, etc.). The second parameter is the font style. We used the XOR (^) operator to add or remove the Bold font style to the current font style of the selected font. A problem occurs when you are selecting text containing multiple fonts. For example, if you select the text Hello World and Hello uses Times New Roman, and World uses Arial, then SelectionFont won't be able to choose which to use from the two and it will contain null as the value. That's why we enclosed Lines 5-6 in a try block to test for NullReferenceException. If that error is encountered, then we simply assigned the selection with multiple fonts with whatever is in the font combo box and size combo box (we converted it to float). We simply applied the Bold style to the new font. (There's obviously a better solution to this, but for simplicity, I used this approach since we are only making a Simple Text Editor). The code for the Italic and Underline buttons are quite similar. You simply change the FontStyle to add or remove in the parameter of the constructor.
private void italicToolStripButton_Click(object sender, EventArgs e) { try { editorRichTextBox.SelectionFont = new Font(editorRichTextBox.SelectionFont, editorRichTextBox.SelectionFont.Style ^ FontStyle.Italic); } catch { editorRichTextBox.SelectionFont = new Font(fontsToolStripComboBox.SelectedText, Single.Parse(sizeToolStripComboBox.Text), FontStyle.Italic); } } private void underlineToolStripButton_Click(object sender, EventArgs e) { try { editorRichTextBox.SelectionFont = new Font(editorRichTextBox.SelectionFont, editorRichTextBox.SelectionFont.Style ^ FontStyle.Underline); }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

catch { editorRichTextBox.SelectionFont = new Font(fontsToolStripComboBox.SelectedText, Single.Parse(sizeToolStripComboBox.Text), FontStyle.Underline); } }

The next step is to load all the installed fonts to the fontToolStripComboBox. Double click the title bar of the form to generate an event handler to its Load event. Use the following event handler.
private void Form1_Load(object sender, EventArgs e) { System.Drawing.Text.InstalledFontCollection fonts = new System.Drawing.Text.InstalledFontCollection(); foreach (FontFamily family in fonts.Families) { fontsToolStripComboBox.Items.Add(family.Name); } fontsToolStripComboBox.Text = editorRichTextBox.Font.FontFamily.Name; sizeToolStripComboBox.Text = editorRichTextBox.Font.Size.ToString(); }

The InstalledFontCollection class contains a collection of all the fonts currently installed into your system. We used a foreach loop to retrieve each FontFamily object from the Families property of the InstalledFontCollection class. We then add the names of each FontFamily using its Name property. The two final lines detects the default font family and size of the editor and shows them in their respective tool strip combo boxes. There is one problem left. If you run the program, select some text, and proceed to either the fontToolStripComboBox or sizeToolStripComboBox, the selection of the text in the editor is gone. To fix this, one way I did is to save the SelectionStart and SelectionLength of the selection when the user leaves the editor, and when he/she returns to the editor, the text position and length specified by the SelectionStart and SelectionLength is reselected. Add the following private fields inside the Form1 class.
private int selectionStart = 0; private int selectionLength = 0;

We then need to add an event handler for the RichTextBox's Leave event so proceed to the Designer, going to the Events section of the Properties Window, and finding the Leave event. Double click it and use the following event handler.
private void editorRichTextBox_Leave(object sender, EventArgs e) { selectionStart = editorRichTextBox.SelectionStart; selectionLength = editorRichTextBox.SelectionLength;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

This code saves the SelectionStart and the SelectionLength of the currently selected text of the editorRichTextBox. We now need to add codes to the Enter event of the editorRichTextBox. Use the following event handler for its Enter event to restore the selection when the editorRichTextBox gains back the focus.
private void editorRichTextBox_Enter(object sender, EventArgs e) { editorRichTextBox.Select(selectionStart, selectionLength); }

We now need to add the codes for changing the font family of the selected text. In the Designer, select the fontToolStripComboBox and find the SelectedIndexChanged event. Use the following event handler.
private void fontsToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e) { editorRichTextBox.Focus(); try { editorRichTextBox.SelectionFont = new Font( fontsToolStripComboBox.SelectedItem.ToString(), editorRichTextBox.SelectionFont.Size, editorRichTextBox.SelectionFont.Style); } catch { editorRichTextBox.SelectionFont = new Font(fontsToolStripComboBox.Text, Single.Parse(sizeToolStripComboBox.Text), FontStyle.Regular); } }

Notice that we called the Focus() method first to reselect the text first before we applied the new modified font using another constructor of the Font class. The first parameter is the FontFamily to be used by the font. We used the selected font family of the fontsToolStripComboBox. The other two arguments specifies the size and font style of the font. We passed the current size and font style of the selected font to these parameters. Like we did with the Bold, Italic, and Underline buttons, if an error occurs due to the selection having two or more fonts, then in the catch block, we simply applied whatever is in the fonts combo box and the size combo box. We simply set the style to a Regular. The code for the sizeToolStripComboBox is similar. Double click it and use the following event handler.
private void sizeToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e) {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

editorRichTextBox.Focus(); try { editorRichTextBox.SelectionFont = new Font( editorRichTextBox.SelectionFont.FontFamily, Single.Parse(sizeToolStripComboBox.SelectedItem.ToString()), editorRichTextBox.SelectionFont.Style); } catch { editorRichTextBox.SelectionFont = new Font(fontsToolStripComboBox.Text, Single.Parse(sizeToolStripComboBox.Text), FontStyle.Regular); } }

Since we are changing the font of the selected text, the second parameter is based on the selected item of the sizeToolStripMenuComboBox. We then convert it to float using the Single.Parse() method. We also provide a catch block incase the user is selects a text which uses multiple font families. Run the program and try the functionality of our completed Simple Text Editor. You can open files, save the text to a file, and format the text however you want. It has missing a lot of features but it is enough to be called as a Text Editor.

Download Project: SimpleTextEditor.rar

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Simple Media Player


We will be creating an application that can play videos and music files. This tutorial will be using the Windows Media Player control that we will import to our project. Create a new Windows Forms Application and name it SimpleMediaPlayer. Right click anywhere in the Toolbox and select the "Choose Items..." option from the context menu.

Figure 1 You may have to wait for the following window to show up. The Choose Toolbox Items window should appear. You need to go to the COM components tab.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 2 Find the Windows Media Player check box and click it. If it isn't there, click the Browse button and find wmp.dll. The Windows Media Player control should now appear inside your Toolbox.

Figure 3 Note that Visual Studio adds references to AxWMPLib and WMPLib libraries. Drag the Windows Media Player control from the toolbox to the form. By default, the control will include user interface for controlling the video and the seek bar. Your form should now look like this.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Figure 4 We will be building our own customized user interface. We need to remove the default user interface of the control. The Windows Media Player control offers a property named uiMode. Change it from full to none. Your control should now look like a black square without the user interface.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 5 To simplify our code, change the default name of the control to wmpPlayer. Note that if the UI still shows up during runtime, you can manually change the uiMode property in the Form's constructor right after the InializeComponent(). You can also set the stretchToFit property to true so the movie will be stretched.
public Form1() { InitializeComponent(); wmpPlayer.uiMode = "none"; wmpPlayer.stretchToFit = true; }

Now that we removed the built-in UI of the control, we need to add our own controls that will control the movie or music being played. The following shows the additional components that will be used for our project.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Label 1 2 3 4 5

Properties TickStyle: None TrackBar trackBarSeekBar Anchor: Bottom, Left, Right Text: Browse Button buttonBrowse Anchor: Bottom, Left Text: Play Button buttonPlayPause Anchor: Bottom, Left Text: Stop Button buttonStop Anchor: Bottom, Left TickStyle: None TrackBar trackBarVolume Maximum: 100 Anchor: Bottom, Right

Type

Name

Figure 6 We will also be using a Timer control so drag one from the Components section of the Toolbox. Set its Interval property to 1000 so it will click every 1 second. After building the user iterface, let's now add the neccessary codes for the functionality of our simple media player. Let's start with the browse button. Double click it in the designer and add use the following event handler for it's Click event.
1 private void buttonBrowse_Click(object sender, EventArgs e) 2 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

3 4 5 6 7 8 9 10 11 12 13 14}

OpenFileDialog fileChooser = new OpenFileDialog(); DialogResult result = fileChooser.ShowDialog(); if (result == DialogResult.OK) { wmpPlayer.URL = fileChooser.FileName; } buttonPlayPause.Text = "Pause"; trackBarVolume.Value = wmpPlayer.settings.volume; timer1.Enabled = true;

Example 1 The browse button will show up an open file dialog to let you choose which media file is to be played. Lines 3-9 handles all of this. Line 8 uses the path of the file chosen by the user for the URL property of the WindowsMediaPlayer control. Assigning the path of a file to the URL property automatically plays it. Line 11 changes the text of the buttonPlayPause button to "Pause" because the video is currently playing. Line 12 involves the trackbar used for adjusting the volume. We initialize it using the value of the volume property of WindowsMediaPlayer control. Line 13 enables our timer so the trackBarSeekBar will begin to move. The buttonPlayPause is a toggle button which pauses the video/music if it's currently playing or play a paused video/music. Double click this button in the designer and use the following code:
1 private void buttonPlayPause_Click(object sender, EventArgs e) 2 { 3 if (wmpPlayer.playState == WMPLib.WMPPlayState.wmppsPaused) 4 { 5 wmpPlayer.Ctlcontrols.play(); 6 buttonPlayPause.Text = "Pause"; 7 } 8 else 9 { 10 wmpPlayer.Ctlcontrols.pause(); 11 buttonPlayPause.Text = "Play"; 12 } 13}

Example 2 Line 3 checks if the video/music is paused by using the playState property and the WMPPlayState.wmppsPaused enumeration value. If so, we used the play() method of the Ctlcontrols property of the player to play the paused video/music and adjust the text of the button. If the button is playing, then the else part (line 8) will be executed. Inside it, the pause() method is used instead to pause the playing video or music. The buttonStop uses the following event handler for its Click event.
private void buttonStop_Click(object sender, EventArgs e)

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

{ wmpPlayer.Ctlcontrols.stop(); }

For the our Timer's Tick event, use the following event handler:
private void timer1_Tick(object sender, EventArgs e) { trackBarSeekBar.Maximum = (int)wmpPlayer.currentMedia.duration; trackBarSeekBar.Value = (int)wmpPlayer.Ctlcontrols.currentPosition; }

First, we set the Maximum property of the trackBarSeekBar to whatever the duration of the media being played. (You will see soon that the trackBarSeekBar serves as our seekbar). The second line will move the pointer of the trackbar to the right every second. The trackBarSeekBar will serve as our seekbar. By clicking and draging the thumb of this trackbar, you can go to different parts of the movie or music. First, let's add an event handler for its MouseDown event.
private void trackBarSeekBar_MouseDown(object sender, MouseEventArgs e) { timer1.Enabled = false; }

When you click the thumb of the trackbar, we first need to disable the timer so it won't move while we are holding it. You can then drag the thumb to the left or right to move to any part of the video. We should add an event handler for its MouseUp event so when you release the mouse, the video will move to the part where you placed the thumb of the trackbar.
private void trackBarSeekBar_MouseUp(object sender, MouseEventArgs e) { wmpPlayer.Ctlcontrols.currentPosition = trackBarSeekBar.Value; timer1.Enabled = true; }

We used the currentPosition property and assigns the position of the thumb of the trackbar using its Value property. We then reenabled our timer so our seekbar will move again. Note that we used the MouseDown and MouseUp events instead of the Scroll event. We do this so we can stop the seekbar from moving when you are holding it. Finally, lets add an event handler for the Scroll event of the trackBarVolume which adjusts the volume. Since the volume trackbar isn't moving, we can simply use the Scroll event.
private void trackBarVolume_Scroll(object sender, EventArgs e) { wmpPlayer.settings.volume = trackBarVolume.Value; }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Now run the program and browse for a movie or music in your system to test our simple media player.

Download Project: SimpleMediaPlayer.rar

Tic-Tac-Toe Game in C#
In this tutorial, we will be creating a Tic-Tac-Toe game. If you are not familiar to that game, it is normaly composed of 3x3 board contaning blank tiles or squares. Each player take turns to mark a square by their corresponding symbols. The first player will represent a Circle and the second player will represent a Cross. The first one to make three similar symbols in horizontal, vertical, or diagonal orientation wins the game. If no one makes the said patterns, the result is draw. For this project, we will be using the images contained in the following file. After extracting the images, we can now proceed with our project. Download tic-tac-toe-tiles.rar Create a new Windows Forms Application project and name it TicTacToe. You first need to import the images you have extracted from the downloaded file. In the Solution Explorer, right click the project node, choose Add, then Existing Item. Browse for the location of the three image files. Change the file type to All Files (*.*) and browse for the location of the three images. You can Ctrl click on each image to select all three. Click add to add the three images to your project.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 The images should now show in the Solution Explorer. The next thing to do is to add a PictureBox control from the Toolbox to the form. Change the Size property of the picture box to 100, 100 in the Properties window. Copy the

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

control and create 8 more copies of it. Form a 3x3 board as seen in the following: Figure 2 Be sure that the squares are in proper order. Follow the numbers at the end of their default name and position them right next to each other going down if you reach 3 squares in a row. Add a button to the bottom of the form and name it buttonStart which will be used to start/reset the game. Let's now proceed to the actual coding of our Tic Tac Toe game. Press F7 to go to the Code editor and add the following fields to the Form1 class.
private private private private int currentPlayer = 1; int winner = 0; int turnCounter = 0; PictureBox[,] tiles;

The currentPlayer field will determine the player who will make the turn. The winner variable tells which player wins the match. It has a default value of 0 which will indicate that no one is a winner yet. The turnCounter field specifies the number of turns. This will be used to check if all the squares has been filled, resulting to draw. The tiles field is a 2-dimensional PictureBox array that will contain all the PictureBoxes that represents the tiles. We will also need to create an enumeration named TileState which will determine the state of each tile. Inside the Form1 class, add the following code.
public enum TileState { Blank, Circle, Cross }

The enumeration contains three values. Blank indicates that the tile is blank and no player has clicked it yet. Circle indicates that the first player already clicked the tile, and Cross indicates that the second player already clicked the tile. Inside the Form1 constructor add codes to place all the PictureBoxes to the tiles field.
public Form1() { InitializeComponent(); tiles = new PictureBox[3,3] { { pictureBox1, pictureBox2, pictureBox3 }, { pictureBox4, pictureBox5, pictureBox6 }, { pictureBox7, pictureBox8, pictureBox9 } }; }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We specified the array to have 3 rows and 3 columns and used a multidimensional array initializer. Since the tiles field is a 2-dimensional array with 3 rows and 3 columns, we add the first 3 PictureBoxes to the first row followed by the next three and so on. Go back to the Designer and double click the title bar to create an event handler for its Load event. Add a call to ResetSquares() method which we will define later.
private void Form1_Load(object sender, EventArgs e) { ResetSquares(); }

Also add an event handler to the buttonStart method and also call the ResetSquares() method within it.
private void buttonStart_Click(object sender, EventArgs e) { ResetSquares(); }

The ResetSquares() method's code is presented below.


1 private void ResetSquares() 2 { 3 foreach (PictureBox tile in tiles) 4 { 5 tile.Image = new Bitmap(@"..\..\blank-tile.jpg"); 6 tile.Tag = TileState.Blank; 7 } 8 9 currentPlayer = 1; 10 winner = 0; 11 turnCounter = 0; 12 this.Text = "Player 1's Turn"; 13}

Example 1 The ResetSquares() method simply resets the game back to the original state to allow players to start playing the game again. Lines 3-7 loops through the tiles array and retrieve each PictureBox that represents each tile. Line 5 set's the image of the tile to the blank image that we have downloaded. Notice that we need to go up to the directory twice using the double dot syntax since the images are located in the projects root directory which requires two steps up from the directory where the actual program is located. We also set the Tag property of the PictureBox to TileState.Blank. We do this on all the tiles so that all tiles are in Blank state when the program starts or the game resets. Lines 9-11 resets the currentPlayer, winner, and turnCounter fields back to their original value. Line 12 prints a message in the form's title bar indicating that it's the Player 1's turn to begin.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

For the 9 PictureBox tiles, we will create one event handler that will be shared by their Click events.
1 private void tile_Click(object sender, EventArgs e) 2 { 3 PictureBox tile = (PictureBox)sender; 4 5 if ((TileState)tile.Tag != TileState.Blank || winner != 0) 6 return; 7 8 if (currentPlayer == 1) 9 { 10 tile.Image = new Bitmap(@"..\..\o-tile.jpg"); 11 tile.Tag = TileState.Circle; 12 this.Text = "Player 2's Turn"; 13 } 14 else 15 { 16 tile.Image = new Bitmap(@"..\..\x-tile.jpg"); 17 tile.Tag = TileState.Cross; 18 this.Text = "Player 1's Turn"; 19 } 20 21 turnCounter++; 22 23 winner = DetermineWinner(); 24 25 if (winner != 0) 26 this.Text = String.Format("Player {0} Wins!", winner); 27 else if (winner == 0 && turnCounter == 9) 28 this.Text = "Draw!"; 29 else 30 currentPlayer = currentPlayer == 1 ? 2 : 1; 31}

Example 2 When you click a blank picture box, an image will replace it depending on which player clicked it. For player 1, the image is a circle and for player 2, the image is a cross. Also, after clicking the image, furthing clicking it is disabled. Go back to the Designer and Ctrl Click each PictureBox. On the events section of the Properties Window, find the Click event and choose tile_Click method that we have created. Since the handler is shared by multiple PictureBoxes, we need to get the picture box that sent the event by using the sender parameter of the event handler. We convert the sender to a PictureBox object (Line 3) so that we can access properties such as the Tag property. Lines 5-6 checks if the current tile is already occupied or if there is already a winner. If so, then we exit the method and ignore the click of the user. Lines 8-19 checks whose turn is it so the the proper image will be shown. If its Player 1's turn, then line 10 changes the blank image of the clicked tile to the circle image. We also changed the the Tag property of that tile to TileState.Circle and adjusted the Text of the form to indicate that the turn will now go to Player 2. If it's player 2's turn then we show the cross image and assign the TileState.Cross value to the Tag property of the tile.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Line 21 increments the turnCounter by 1. This will be used to monitor the number of tiles clicked or the number of turns that passed. If all the nine tiles has been clicked and there is still no winner, then the game will be considered as draw. Line 23 calls the DetermineWinner() method that will be defined later. The method checks the game board for winning combinations and if a combination is met, returns the player number of the winning player. If no combination is found, then 0 will be returned. The resulting value is stored in the winner field. Line 25 tests if there is a winner and prints the player to the form's title bar. Line 27 checks if the game should be a draw by testing if there are no current winners and the turnCounter has reached the maximum turns which is 9. If there is no winner and the number of turns hasn't still met the maximum, then we simply switch the players by assigning the currentPlayer with the next player to play (line 30). We used the conditional operator to assign the right player who will have the next turn. The DetermineWinner() method's code is shown below.
1 private int DetermineWinner() 2 { 3 if ( 4 //Check for diagonals 5 ((TileState)tiles[0, 0].Tag != TileState.Blank && 6 tiles[0, 0].Tag.Equals(tiles[1, 1].Tag) && 7 tiles[1, 1].Tag.Equals(tiles[2, 2].Tag)) || 8 ((TileState)tiles[0, 2].Tag != TileState.Blank && 9 tiles[0, 2].Tag.Equals(tiles[1, 1].Tag) && 10 tiles[1, 1].Tag.Equals(tiles[2, 0].Tag)) || 11 //Check for horizontals 12 ((TileState)tiles[0, 0].Tag != TileState.Blank && 13 tiles[0, 0].Tag.Equals(tiles[0, 1].Tag) && 14 tiles[0, 1].Tag.Equals(tiles[0, 2].Tag)) || 15 ((TileState)tiles[1, 0].Tag != TileState.Blank && 16 tiles[1, 0].Tag.Equals(tiles[1, 1].Tag) && 17 tiles[1, 1].Tag.Equals(tiles[1, 2].Tag)) || 18 ((TileState)tiles[2, 0].Tag != TileState.Blank && 19 tiles[2, 0].Tag.Equals(tiles[2, 1].Tag) && 20 tiles[2, 1].Tag.Equals(tiles[2, 2].Tag)) || 21 //Check for verticals 22 ((TileState)tiles[0, 0].Tag != TileState.Blank && 23 tiles[0, 0].Tag.Equals(tiles[1, 0].Tag) && 24 tiles[1, 0].Tag.Equals(tiles[2, 0].Tag)) || 25 ((TileState)tiles[0, 1].Tag != TileState.Blank && 26 tiles[0, 1].Tag.Equals(tiles[1, 1].Tag) && 27 tiles[1, 1].Tag.Equals(tiles[2, 1].Tag)) || 28 ((TileState)tiles[1, 2].Tag != TileState.Blank && 29 tiles[0, 2].Tag.Equals(tiles[1, 2].Tag) && 30 tiles[1, 2].Tag.Equals(tiles[2, 2].Tag)) 31 ) //close if condition 32 { 33 return currentPlayer; 34 } 35 else 36 return 0; 37}

Example 3

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

At first look the code might be very hard to read and very cryptic. But it is just a combination of multiple condtions using logical operators. Lines 4-30 are the conditions of the if statement and if this is met, then Line 33 declares the currentPlayer as the winner by returning its value. SInce we added the PictureBoxes into the tiles array, Figure 6 shows the corresponding element in the tiles array for each PictureBox.

Figure 3 Going back to the code in Example 3. Let's disect the condition of the if statement which tells the different winning conditions. Each combination is composed of three conditions combined using logical AND (&&). Because of lack of space, I need to divide them into three lines for each winning condition. Each condition is enclosed in a set of parenthesis so they will be considered as 1 group of condition. All the three conditions must be met for the group to be evaluated as true. Between each condition is a Logical OR (||) operator so it means that we only need to meet one winning condition for the player to win. For example, line 5-7 is the condition for determining if there are three matching symbols in diagonal order starting at position (0,0).

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The first condition(line 5) checks if the the first tile is not a blank tile which means that it should be either a circle or a cross. The second condition (line 6) checks if the first tile (0,0) matches the next tile (1,1) in the pattern. Note that we used the Equals() method instead of the == operator since the Tag property is an Object which is a reference type. Line 7 checks if the second tile (1,1) matches the third tile (2,2) in the pattern. Of all of these are true, then lines 12-14 will be evaluated as true and the body of the if statement will be executed. Lines 8-10 shows a group of conditions for determining the other diagonal direction which starts from (0,2) to (2,0). Lines 1220 are the conditions for determining the horizontal combinations and lines 22-30 are for the vertical combinations. Our Tic-Tac-Toe game is finally finished. Run the program and start playing the game. Try the different winning combinations. Pressing the Start button will reset the game.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

There are lot more of features you can add on our TicTacToe game. For example, you can let the user define how the dimension of the board. You can also make a computer enemy using simple Artificial Intelligence that randomly selects a blank tile or a harder oponent which searches for adjacent tiles. Since we have a predefined number of rows and columns in our game board, we can simply hard code the combinations for simplicity. You can use a loop that checks each row, column and diagonals for matching patterns. Download Project: TicTacToe.rar

MORE TUTORIALS COMING SOON

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

C# Language Integrated Query (LINQ) Language Integrated Query (LINQ)


Language Integrated Query (LINQ) was introduced in .NET version 3.5 to allow a programmer to query data from many kinds of data sources without knowing any external language. Querying is the process of obtaining data from a data source. LINQ makes it very easy for you to query data from different kinds of data sources. LINQ is integrated to both C# and VB, and multiple special keywords and syntax for querying using LINQ have been added. Before the arrival of LINQ, programmers write different set of codes for querying different data sources. For example, they have to write codes for querying an SQL database using an SQL command or using XPath for querying XML files. With LINQ now in the programmer's arsenal, querying different data sources requires only the knowledge of the LINQ keywords and methods that were added in .NET 3.5.

Figure 1 - Different Flavors of LINQ There are multiple flavors of LINQ. This is made possible by LINQ providers as seen in Figure 1. Visual Studio already includes some of this providers such as LINQ to Objects. This section of the site will focus on LINQ to Objects which is used to query a collection of objects in your code that implements the IEnumerable<T> interface. Examples of such objects are arrays and lists or a custom collection that you created. There is also a LINQ to SQL which is specifically designed
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

to make it easier to query SQL Server databases. For querying XML files, you can use the LINQ to XML. You can extend LINQ to query more kinds of data sources. You can create you own providers if you want to support querying another type of data source using LINQ. The querying techniques that will be thought in the following lessons can be applied on the different flavors of LINQ. LINQ is made possible by the extension methods that are attached to IEnumerable<T> interface. You can call these methods directly but you need to have a knowledge of lambda expressions. You can also use query expressions which syntax looks like SQL. Query expressions is the main tool you will use to query data using LINQ although you can call the extension methods and use lambda expressions. C# is an imperative language which means that you write the step by step codes to make something happen, but LINQ promotes declarative programming. This simply means that you tell the computer exactly what you want and the computer will handle everything else. Before LINQ, you can only use imperative programming for querying results. For example, suppose that you want to get all the even numbers from an array. Without LINQ and using imperative style of programming, your code will look like this:
List<int> evenNumbers = new List<int>(); int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; foreach(int num in numbers) { if (num % 2 == 0) evenNumbers.Add(num); }

Figure 2 - Using Imperative Style of Programming to Query Values You instruct the computer to go through every value in a collection and then retrieve the number that matches the condition in an if statement. Now take a look at the declarative version that uses the query expression syntax.
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; var evenNumbers = from n in numbers where n % 2 == 0 select n;

Figure 3 - Using a Query Expression to Query Values Don't mind the new syntax yet as this will be described in later lessons. You can see that the declarative version is much clear as to what your objective really is.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Query Expressions
Query expressions are special statements used for querying a data source using the LINQ. LINQ are just extension methods that you call and returns the data that you want. These methods are located in the System.Linq namespace so you must include it when you want to use LINQ in your project. Query expressions are tranlated into their equivalent method syntax that can be understood by CLR. You will learn about using the method syntax for querying data using LINQ in the next lesson. Let's take a look at the first example of using LINQ query expression to query values from a collection. Note that we are using LINQ to Objects so we will simply use a simple array as the source.
1 using System; 2 using System.Linq; 3 4 namespace LinqExample 5 { 6 class Program 7 { 8 static void Main(string[] args) 9 { 10 int[] numbers = { 1, 2, 3, 4, 5 }; 11 12 var result = from n in numbers 13 select n; 14 15 foreach (var n in result) 16 { 17 Console.Write(n + " "); 18 } 19 } 20 } 21}

Example 1
1 2 3 4 5

Line 2 imports the System.Linq namespace so that we can use LINQ in our program. Line 10 declares an array of 5 integers containing some values. Line 12-13 is the simplest query expression you can make although it is currently useless right now but we will be studying more forms of query expressions. This query expression simply gets every number from the numbers array which can then be accessed using the results variable. The structure of a basic query expression is as follows:
var query = from rangeVar in dataSource <other operations> select <projection>;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Example 2 - Structure of a basic query expression Note that you can write a query expression in a single line, but a good practice is to seperate each clause into multiple lines. Each line of the formatted query expression above is called a clause. There are seven types of clauses you can use in a query expression which includes, from, select, where, orderby, let, join, and group-by clauses. For now, we will be only looking at the from and select clauses. Query expressions begin with the a from clause. The from clause uses a range variable (rangeVar) which will temporarily hold a value from the dataSource, followed by the in contextual keyword and then the data source itself. This can be compared to the mechanisims of the foreach loop where a range variable will hold each value retrieved from the source. But the range variable in a from clause is different as it only acts as a reference to each successive element of the data source. This is because of the deferred execution mechanism which you will learn later. The range variable automatically detect its type using type inference based on the type of every element from the data source. After a from clause, you can insert one or more where, orderby, let, or join clauses. You can even add one or more from clauses which will be demonstrated in a later lesson. At the end of a query expression is a select clause. Following the select keyword is a projection which will determine the shape or type of each returned element. For example, if a value following the select clause is of type int, then the type of the query will be a collection of integers. You can even peform more kinds of projection and transformation techniques which will be demonstrated in a later lesson. Note that a query expression can also be ended with a group-by clause but a seperate lesson will be dedicated for it. So to wrap up, a typical query expression starts with a from clause with a range variable and a data source, then followed by any of the from, where, orderby, let, or join clauses, and finally the select or group-by clause at the end of the query expression. If you know SQL, then the syntax of the query expression might look wierd to you because the from clause is placed first and the select clause is placed last. This was done so that Visual Studio can use the Intellisense feature by knowing what type an item of the data source is in advance. The keywords used in a query experession such as from and select are examples of contextual keywords. They are only treated as keywords during specific events and locations such as a query expression. For example, you can simply use the word select as a variable name if it will not be used in a query expression. To see the complete list of contextual keywords, you can go to this link. The result of the query is of type IEnumerable<T>. If you will look at our example, the result was placed in a variable of type var which means it uses type inference to automatically detect the type of the queried data. You can for example, explicitly indicate the type of the query result like this:

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

IEnumerable<int> result = from n in numbers select n;

but it requires you to know the type of the result in advance. It is recommended to use var instead to take advantage of a lot of its features. Line 15-18 of Example 1 shows the the value of every data from the query. We simply used a foreach loop but you must also take note that we used var as the type of the range variable. This allows the compiler to simply detect the type of every data in the query result. The LINQ has a feature called deferred execution. It means that the query expression or LINQ method will not execute until the program starts to read or access an item from the result of the query. The query expression actually just returns a computation. The actual sequence of data will be retrieved once the user asks for it. For example, the query expression will be executed when you access the results using a foreach loop. You will learn more about deferred execution a little bit later. We have successfully written our very first query expression, but as you can see, it does nothing but to query every data from the data source. Later lessons will show you more techniques such as filtering, ordering, joining, and grouping results. We will look at each of the seven query expression clauses in more depth.

Using the Method Syntax


LINQ is composed of extensions methods that are attached to the IEnumerable<T> interface. These methods exist in the System.Linq namespace and are members of the Enumerable static class. If you can recall, extension methods are special kinds of methods that are use to extend pre-existing types from the .NET class library or to a class in which you don't have access to the source code. For example, you can add a ToTitleCase() method to the System.String type which you can simply call using ordinary strings to change their case style to title case. Let's examine Select<TSource, TResult>() method from the System.Linq namespace and look at its declaration, you can see that it is attached to the IEnumerable<T> interface.
public static IEnumerable<TResult> Select<TSource, TResult>( this IEnumerable<TSource> source, Func<TSource, TResult> selector)

The first parameter of an extension method determines which type to extend. It is preceded by the this keyword followed by the type to extend and an instance name. You can also see that the return type of this method is IEnumerable<T>. This will allow you to nest or chain method calls as you will see later. I have said in an earlier lesson that calling the LINQ methods directly requires you to use lambda expressions. Although using annonymous methods are okay, lambda expressions are much simpler and shorter and makes your code more readable. I therefore assume that you have a good knowledge of lambda expression before going on with this lesson. You will now be presented with another way to query data using LINQ, and that is by using the method syntax which is simply calling the LINQ methods directly.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

The .NET Framework contains delegate types that can hold methods with different number of parameters and different return types. Looking at the definition of the Select() method, the second parameter is a generic delegate with a type of Func<TSource,TResult>. The delegate will be able to accept a method that has one parameter of type TSource and a return type of TResult. For example, Func<string,int> will be able to accept a method that has one string parameter and returns an int. Figure 1 shows you some delegates you can use depending on the number of parameters of the method it will hold. Delegate Func<T1, TResult> Func<T1, T2, TResult> Func<T1,T2,T3,TResult> Func<T1,T2,T3,T4, TResult> Figure 1 Based on the table, you can already see the pattern and guess the delegates for methods with more number of parameters. The delegate with the highest number of parameters available can have 16 parameters. Back on observing the Select() method, the second parameter accepts a reference to a method with one parameter and returns a value. Let's look at how we can use the Select() method by passing a lambda expression as its parameter.
int[] numbers = { 1, 2, 3, 4, 5 }; var result = numbers.Select(n => n); foreach(var n in result) { Console.Write(n + " "); }

Description Encapsulates a method that has one parameter of type TSource and returns a value of type TResult. Encapsulates a method that has two parameters T1 and T2 and returns TResult. Encapsulates a method that has three parameters and returns a value of type TResult. Encapsulates a method that has four parameters and returns a value of type TResult.

Example 2
1 2 3 4 5

Note that the first parameter of an extension method is not actually a parameter but is used to indicate which type to extend. Therefore the second parameter which accepts a lambda expression becomes the only parameter of method Select(). Inside the Select() method, we used a lambda expression that accepts one integer parameter and returns an integer value. Again, if you don't know lambda expressions then it might look wierd to you. What the lambda expression did was to retrieve every number and then add (return the value) to the query result. The code merely queries every number without modifying them. Let's modify the lambda expression inside the Select() method to do something more useful.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

int[] numbers = { 1, 2, 3, 4, 5 }; var result = numbers.Select(n => n + 1); foreach(var n in result) { Console.Write(n + " "); }

Example 3
2 3 4 5 6

Our lambda expression parameter now retrieves a value from the numbers array, add 1 to its value, and add the new value to the query result. Most methods from the System.Linq return IEnumerable<T>. This allows you to nest calls of LINQ methods. For example, consider the line of code below (ignore the new methods for now). The important thing is you can see how LINQ method calls can be nested or chained.
var result = numbers.Where(n => n > 3).OrderBy(n => n).Select(n => n);

This lesson only shows how to use the Select() method but there are numerous LINQ methods that we will be looking at in the upcoming lessons. You will also see how to create more exciting results using the Select() method but for now, the important thing is that you know how to use the method syntax for querying data sources using LINQ. The method syntax is the real way the compiler does LINQ queries. The query expression syntax for querying from data sources is just a layer to simplify calling these extension methods. For example consider the query expression below:
var result = from p in persons where p.Age >= 18 order by p.Name select p.FirstName + " " + p.LastName;

is translated at compile time into a series of calls to corresponding methods from the System.Linq namespace. The actual code uses the method syntax as show below:
var result = persons.Where(p => p.Age >= 18) .OrderBy(p => p.Name) .Select(p => p.FirstName + " " + p.LastName);

You can see the chained method calls (I only aligned them for better readability). This was made possible because most of the LINQ methods return IEnumerable<T>. After calling the Where() method, we used the OrderBy() method on the returned data, and then we used the Select() method on the returned data of OrderBy().

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Now that you know two ways to query data using LINQ, query expressions and method syntax; the question is which one should you use? I recommend using query expressions because it promotes declarative style of programming and it is simpler and easier to read than method syntax. But it is also important that you have knowledge of using method syntax because this is the way CLR read your query expression.

Deferred Execution
There is one thing that you must know before we continue to the next lessons. You must know that LINQ uses deferred execution when performing queries. This simply means that the actual query is not executed until you iterate over or access each value from the result. Consider the following example:
1 int[] numbers = { 1, 2, 3, 4, 5 }; 2 3 int i = 3; 4 5 var result = from n in numbers 6 where n <= i 7 select n; 8 9 i = 4; 10 11foreach (var n in result) 12{ 13 Console.WriteLine(n); 14}

Example 1
1 2 3 4

We haven't look at the where operator up to now so I will give a brief description of it for the sake of describing deferred execution. The where operator is used to filter the results from a query based on a specified condition. On the code above, the where operator(line 6) instructs the query to only retrieve values which are less than or equal to whatever the value of i is. We will look at the where operator in more detail in a later lesson but for now, let's concentrate on understanding deferred execution. You can see that 3 was assigned to i at line 3. Therefore, when the query expression in lines 5 to 7 executes, the where operator is comparing each item to 3 and if it is less than or equal to it, then they will be included in the result. You must be assuming now that the result variable contains values 1, 2, and 3, but actually, it only contains a computation on how you can get those values. Now in line 9, the value of i is modified by assigning it a value of 4. Because of deferred execution, this directly affects the result of the query expression in lines 5-7. I have said earlier that this query will only be executed once the program asks for the first item of the result and this

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

can be done using a foreach loop. The foreach loop in lines 11-14 executes the query expression and returns the first item from the result of the query. Note that since we modified the value of i, then the query expression was updated as well. The foreach loop will show values from 1 to 4 instead of 1 to 3. This is one of the use of deferred execution. The program is allowed to update the query expression before actually using or executing it to get values. Deferred execution is just the default behavior of LINQ, but you can also make the execution of the query immediate. You can use another set of methods from the System.Linq namespace which compose of ToArray<T>(), ToList<T>(), ToDictionary<T>(), and ToLookUp<T>(). These are also extension methods for the IEnumerable<T> interface. For example, you can use the ToList<T>() method to convert the result of the query expression into a List<T> collection. Example 2 shows how we can use ToList() to immediately execute the query expression.
1 int[] numbers = { 1, 2, 3, 4, 5 }; 2 3 int i = 3; 4 5 var result = (from n in numbers 6 where n <= i 7 select n).ToList(); 8 9 i = 4; 10 11foreach (var n in result) 12{ 13 Console.WriteLine(n); 14}

Example 2
1 2 3

Since the query expression was immediately executed, once the program leaves line 7, the result variable already contains the results of the query. So even if we edit the value of i in line 9, the contents of the result is not changed. This can be seen by iterating each value using a foreach loop. The values shown will be 1 to 3 instead of 1 to 4. Please note that deferred execution is not associated with the query expression itself but to the set of methods that those query expression represent. It is the extension methods of the System.Linq namespace that tells whether the query will use deferred execution or not. For example, the Select() method uses deferred execution while the ToList() method uses immediate execution. For example, the query below uses the method syntax and the Select() method to query everything from an array.
var result = numbers.Select(n => n);

Since the Select() method uses deferred execution, this will not immediately execute until a foreach loop iterates every result. On the other hand, if you use a method using a deferred
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

execution right after the Select() method, then execution of the methods will immediately take place.
var result = numbers.Select(n => n).ToList();

Whichever method is executed last determines whether deferred execution will be used. The following table shows the methods of System.Linq and tells whether calling them will cause deferred execution. Method Execution Method Execution Distinct Deferred Reverse Deferred DefaultIfEmpty Deferred Select Deferred ElementAt Immediate SelectMany Deferred ElementAtOrDefault Deferred SequenceEqual Immediate Except Deferred Single Immediate First Immediate SingleOrDefault Immediate FirstOrDefault Immediate Skip Deferred GroupBy Deferred SkipWhile Deferred GroupJoin Deferred Sum Immediate Intersect Deferred Take Deferred Join Deferred TakeWhile Deferred Last Immediate ThenBy Deferred LastOrDefault Immediate ThenByDescending Deferred LongCount Immediate ToArray Immediate Max Immediate ToDictionary Immediate Min Immediate ToList Immediate OfType Deferred ToLookup Immediate OrderBy Deferred Union Deferred OrderByDescending Deferred Where Deferred Figure 1 - Methods Using Deferred Exection or Immediate Execution If the table above is too hard to remember, then you can just remember one rule on determining whether a query is deferred. If a query is expected to return a single result such as a single number or object, then it will be immediately executed. When a query will return an IEnumerable<T> result, then most of the time it will use deferred execution. One technique to see if a query returns an IEnumerable<T> result is by hovering over the var keyword of the query expression while you are in the Visual Studio editor. Look whether the help bubble shows that it is an IEnumerable<T> type. If so, then the query will use deferred execution

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The select Clause


The select clause in LINQ shapes the data to be included in the query result using projection. Projection is the process of transforming an object into a new form. The select clause of a LINQ query must be placed at the end of the query. You can do many kinds of manipulations to the currently queried value, retrieve certain properties of it, or create an annonymous type based on the queried object's properties. A typical LINQ query returns a collection that implements the IEnumerable<T> interface where T is the resulting data type of the expression in the select statement. For example, if the select clause indicates to retrieve every person in a Person collection, then the returned collection implements the IEnumerable<Person> interface. If the select statement only selects the FirstName of every person, and assuming FirstName property is of type string, then the returned result implements the IEnumerable<string> interface. You can then use a foreach loop to start the retrieving of results that will be yielded by the query expression. You can simply select the whole queried object by using the value of the range variable. This will select the queried object without any modifications or variations.
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; var results = from number in numbers select number; foreach (var n in results) { Console.Write("{0, -2}", n); } 1 2 3 4 5 6 7 8 9 10

You can use different kinds of expressions that yield a result during selection. For example, you can query every number in an array of numbers and increment each of them by one.
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; var results = from number in numbers select number + 1; foreach (var n in results) { Console.Write("{0, -2}", n); } 2 3 4 5 6 7 8 9 10 11

You can also select individual properties or combination of properties during the selection process. For example, you can only select the FirstName of every Person object from a List of Persons.
List<Person> people = new List<Person> { new Person("Johnny", "Smith"),

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

new new new new };

Person("Mark", "Lawrence"), Person("Jessica", "Fisher"), Person("Danny", "Mayer"), Person("Raynold", "Alfonzo")

var firstNames = from person in people select person.FirstName; Johnny Mark Jessica Danny Raynold

You can even combine different properties or other external data to the final value for the selection. For example, you can combine the FirstName property and the LastName property to select every person's full name.
var fullNames = from person in people select person.FirstName + " " + .person.LastName; Johnny Smith Mark Lawrence Jessica Fisher Danny Mayer Raynold Alfonzo

The above select clause will select the person's FirstName, followed by a space, and then his/her LastName. You can use methods to manipulate the final value to be selected. For example, suppose you want to select every FirstName and convert them into all caps.
var namesInCaps = from person in people select person.FirstName.ToUpper(); JOHNNY MARK JESSICA DANNY RAYNOLD

You can even select values not related to the data source being queried. For example, we can have a collection of indices and select a value from another collection or array.
int[] indices = { 0, 1, 2, 3, 4 }; string[] words = { "Example1", "Example2", "Example3", "Example4", "Example5" }; var result = from index in indices select words[index]; Example1 Example2 Example3 Example4 Example5

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We can create annonymous types during selection and include certain properties of each object. For example, suppose we have a Person object that has FirstName, LastName, Age, and Gender properties, and we only want to retrieve their FirstName and LastName, we can create a new annonymous type in the select clause which only includes the FirstName and LastName properties.
var annonymous = from person in people select new { person.FirstName, person.LastName }; foreach (var p in annonymous) { Console.WriteLine(p.FirstName + " " + p.LastName); }

The type of the selected result would be an annonymous type having the properties included in the select clause. You can even create new properties based on the properties of the queried object.
var results = from person in people select new { FN = person.FirstName, LN = person.LastName }; foreach (var p in results) { Console.WriteLine(p.FN + " " + p.LN); } Johnny Smith Mark Lawrence Jessica Fisher Danny Mayer Raynold Alfonzo

The select clause of the query expression above assigns the values of FirstName and LastName properties to new properties with different names. The type of these new properties are determined by the compiler based on the values being assigned to them thanks to type inference. These new properties are absorbed by the created annonymous type.
var results = from person in people select new { Upper = person.FirstName.ToUpper(), Lower = person.FirstName.ToLower() }; foreach (var p in results) { Console.WriteLine("Upper={0}, Lower={1}", p.Upper, p.Lower); } Upper=JOHNNY, Lower=johnny Upper=MARK, Lower=mark Upper=JESSICA, Lower=jessica Upper=DANNY, Lower=danny Upper=RAYNOLD, Lower=raynold

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The select clause above assigns the FirstName converted to uppercase to a new property named Upper, and it's lowercase version to the new Lower property which are then included in an annonymous type. We then used this new properties inside a foreach loop.
var results = from person in people select new { FullName = person.FirstName + " " + person.LastName }; foreach (var p in results) { Console.WriteLine(p.FullName); } Johnny Smith Mark Lawrence Jessica Fisher Danny Mayer Raynold Alfonzo

The above query's select clause creates a new property named FullName and assigns the combined value of each person's FirstName and LastName. The resulting annonymous type will have the FullName property which automatically gets the full name of the person.
var results = from person in people select new { person.Age, FullName = person.FirstName + " " + person.LastName }; foreach (p in results) { Console.WriteLine("FullName={0}, Age={1}", p.FullName, p.Age); } FullName=Johnny Smith, Age=22 FullName=Mark Lawrence, Age=24 FullName=Jessica Fisher, Age=19 FullName=Danny Mayer, Age=21 FullName=Raynold Alfonzo, Age=25

The preceding query contains a select clause creates an annonymous type with a combination of an orginal property of each person and a new property FullName which contains the combined firstname and lastname of each person.

The Select Method


The query method which is the direct equivalent of the select clause is the Select method. The Select method allows you to project the results of the query. We can use the Select method by passing a selector predicate which can be supplied using a lambda expression. As an example of the Select method, the following is a simple use of it where it retrieves every item in a collection. Consider the people variable is a collection of Person object.
var result = people.Select(p => p);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

A lambda expression is passed as the selector predicate for the method. The lambda expression has a single parameter p which will hold every Person object in the collection, and the right side of the lambda expression specifies what will be selected, in this case, the Person object itself. The following are more examples of using the Select method. The following are more varieties of using the Select method with different lambda expressions: 1. Select the FirstName of every person from people.
var firstNames = people.Select(p => p.FirstName);

2. Select the combined FirstName and LastName of each person to form their fullname.
var fullNames = people.Select(p => p.FirstName + " " + p.LastName);

3. Create an annonymous type that contains new property FullName which is the combined FirstName and LastName of each person.
var annonymous = people.Select(p => new { FullName = p.FirstName + " " + p.LastName } );

Another overload of the Select method accepts a lambda expression which has two parameters, the first one is the queried element, and the second one is the index of that queried element from the data source.
var personsWithIndex = people.Select((p, i) => new { Person = p, Index = i });

The following is its equivalent LINQ query:


var personsWithIndex = from p in people select new { Person = p, Index = people.IndexOf(p) };

You can then print values of each person including their index.
foreach (var p in personsWithIndex) { Console.WriteLine(String.Format("[{0}] {1}", p.Index, p.Person.FirstName)); } [0] John [1] Mark [2] Lisa

You can use the LINQ query syntax for a cleaner more readable code or you can directly call the LINQ methods using the query method syntax if you prefer to use lambda expressions.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The SelectMany Method


When objects contains properties which holds a collection of objects, using the Select method is not applicable as it will return a "collection of collection" rather than all the items from those collection properties. We need to use the SelectMany method. The functionality of a SelectMany method is similar to a query expression with multiple from clauses. Let's say we have a class named Company, and it has a property named Employees which holds a collection of Employee type objects. A collection of Company objects can then be created. By using Select method, we can only query each company as seen below:
var result = companies.Select(c => c);

What if we want to access or retrieve all of the employees for every company and flatten the result as a one whole list of items. Let's take a look at the following example:
1 class Company 2 { 3 public string CompanyName { get; set; } 4 public IEnumerable<Employee> Employees { get; set; } 5 } 6 7 class Employee 8 { 9 public string FirstName { get; set; } 10 public string LastName { get; set; } 11} 12 13class Program 14{ 15 public static void Main(string[] args) 16 { 17 //Create some sample companies with employees 18 List<Company> companies = new List<Company> 19 { 20 new Company 21 { 22 CompanyName = "Company 1", 23 Employees = new List<Employee> 24 { 25 new Employee { FirstName = "John", LastName = "Smith" 26}, 27 new Employee { FirstName = "Mark", LastName = "Halls" 28}, 29 new Employee { FirstName = "Morgan", LastName = "Jones" 30} 31 } 32 }, 33 new Company 34 { 35 CompanyName = "Company 2", 36 Employees = new List<Employee> 37 { 38 new Employee { FirstName = "Winston", LastName = "Mars"

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

39}, 40 new Employee { FirstName = "Homer", LastName = "Saxton" 41}, 42 new Employee { FirstName = "Creg", LastName = "Lexon" } 43 } 44 }, 45 new Company 46 { 47 CompanyName = "Company 3", 48 Employees = new List<Employee> 49 { 50 new Employee { FirstName = "Ben", LastName = 51"Greenland" }, 52 new Employee { FirstName = "Anthony", LastName = 53"Waterfield" } 54 } 55 } 56 }; 57 58 //Get All the FirstName of all employees 59 var firstNames = 60companies.SelectMany(c=>c.Employees).Select(e=>e.FirstName); 61 62 var lastNames = companies.SelectMany(c => c.Employees, (c, e) => 63e.LastName); 64 Console.WriteLine("FirstNames of all employees from the three companies."); foreach (var firstName in firstNames) Console.WriteLine(firstName); Console.WriteLine("\nLastNames of all the employees from the three companies."); foreach (var lastName in lastNames) Console.WriteLine(lastName); } }

Example 1 - Using the SelectMany Method


FirstNames of all employees from the three companies. John Mark Morgan Winston Homer Creg Ben Anthony LastNames of all the employees from the three companies. Smith Halls Jones Mars Saxton

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Lexon Greenland Waterfield

We have defined two classes for this example. The first one named Company contains two properties named CompanyName and Employees. The Employees property has a type of IEnumerable<Employee> which simply means that it allows you to store a collection of Employee objects to it. The Employee class was defined and has two simple properties to define a single employee. In the Main method, we created a collection of Company objects and initialize it to have three Company objects. Each Company objects was set a value for their CompanyName and a collection of Employee objects for their Employees property. Note that we are using the collection and object initializers here. Lines 52 to 54 uses the SelectMany method. Line 52 queries the FirstNames of all the employees from all the companies.
companies.SelectMany(c => c.Employees).Select(e => e.FirstName);

This version of SelectMany method accepts only one argument. We pass a lambda specifying the property that the SelectMany will select. As the name of the method implies, "select many" means the method will select a collection of objects. In our example above, we selected the Employees property of every company which contains a collection of Employees. The SelectMany method will now return an IEnumerable<Employee>. This allows us to nest another call to a plain Select method in which, we selected the first name of every employee from the result of the SelectMany method. There is another version of the SelectMany method which accepts two arguments, a collectionSelector and a resultSelector. If we are to rewrite line 52 using this different version of SelectMany, it will look like this.
companies.SelectMany(c => c.Employees, (c, e) => e.FirstName);

Notice that we don't need to use the Select method to select a specific property of every Employee. The second argument handles that. The second argument accepts a lambda with two arguments. The first is the current item from the original collection, and the second is the current item from the selected property of the collectionSelector.

The where Clause


You can filter the results of the query by using the where clause in a query expression. Following the where keyword is the condition (or conditions) that must be met by an item to be included in the results. The great thing with LINQ is that, you can use the available methods in .NET Framework to supplement your condition. This lesson will show you some examples on using the where clause to filter queried data.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can use relational operators to compare a value or property of an item into another value. For example, suppose we want to retrieve numbers which are greater than 5 from an array of numbers, we can do so using the following LINQ query.
int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; var greaterThanFive = from number in numbers where number > 5 select number;

The where clause states that the value of a number must be greater than 5 for it to be selected and included. We can even use logical operators for more complex conditions such as the following:
var sixToTen = from number in numbers where number > 5 && number <= 10 select number;

The query above only retrieves values greater than 5 and less than or equal 10, that is, values 6 to 10. If you have a collection of objects with several properties, you can also test those properties if they met the required condition.
List<Person> people = GetPersonList(); var smiths = from person in people where person.LastName == "Smith" select person;

The query retrieves every person whose LastName is Smith. We can use .NET methods in our condition. For instance, suppose we want to retrieve all the person whose last name starts with the letter 'R'.
var startsWithR = from person in people where person.LastName.StartsWith("R") select person;

We used the StartsWith() method of the String class which returns true if a particular string starts with a specified string argument of the method. Alternatively, we can use the Where() extension method from the System.Linq namespace. You can then pass a lambda expression that has one parameter representing every item from data source and its body containing the boolean expression for the condition. The method returns the collection of objects that pass the required condtion.
var greaterThanFive = numbers.Where ( number => number > 5 );

The lambda expression's body is a single condition which tests the value of number if it is greater than 5. The following is another example which retrieves persons whose last name starts with 'R'.
var startsWithR = people.Where( person => person.LastName.StartsWith("R") );

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can use another overloaded version of the method which accepts a lambda expression having two parameters. The first parameter represents every object from the collection, and the second parameter represents the index of that item in the collection. The following call to Where() method returns numbers whose index in its collection is even.
var evenIndices = numbers.Where( (number, index) => index % 2 == 0 );

You can use the Where() method when you simply want to filter a collection using a specified condition.

The orderby Clause


LINQ makes it easy for you to sort or modify the order of the results of the query. We can use the orderby clause and specify which value or property will be used as a key for sorting results. For example, suppose we have an array of numbers that we want to query and then arrange the results from highest to lowest, we can use the following query expression:
int[] numbers = { 5, 1, 6, 2, 8, 10, 4, 3, 9, 7 }; var sortedNumbers = from number in numbers orderby number select number;

The query uses the orderby clause to order the results and we used the number or the actual object as the key for ordering those results. When you use the actual object, then their default behavior when being compared is used. For example, the above statement will compare the values of each queried integer and tests which is larger or smaller than the other one. The default behavior of the orderby clause is to sort the results from lowest to highest. We can explicitly command the query to sort it in ascending order by using the ascending keyword.
var sortedNumbers = from number in numbers orderby number ascending select number;

To reverse its effect, that is, to sort values from highest to lowest, we can append the descending keyword in the orderby clause.
var sortedNumbers = from number in numbers orderby number descending select number;

In cases where complex types are involved, you can use their properties as the key for ordering the results of a query. For example, suppose we have a collection of Person objects which has FirstName, LastName, and Age properties. We can sort the results from the youngest to the oldest person using the following query.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

var sortedByAge = from person in people orderby person.Age select person;

Again, we can use the descending keyword if you want to reverse the order of the query. We can also sort the results alphabetically based on each person's last name.
var sortedByFirstName = from person in people orderby person.LastName select person;

What if two persons have the same last name? How will those items with the same values be sorted? We can specify multiple values in the orderby clause if you want to properly handle cases like these.
var sortedByFnThenLn = from person in people orderby person.LastName, person.FirstName select person;

We seperate each soring key in the orderby clause by commas. The query above sorts the result based on every person's LastName, and if multiple persons have the same LastName, their FirstName will then be sorted. You can specify even more keys in orderby if for example, two persons still has the same FirstName. Note that using ascending or descending only affects one value in the orderby clause. For example, using a query like this with a descending keyword:
var orderByResults = from person in people orderby person.LastName, person.FirstName descending select person;

only affects the property preceding it, in this case, FirstName. LastName will be ordered in ascending order by default. You can explicitly specify the order to avoid confusion.
var orderByResults = from person in people orderby person.LastName ascending, person.FirstName descending select person;

A class can implement the IComparable<T> interface which determines the default way an object can be sorted. The definition of the Person class is persented below showing an implementation of the IComparable<T> interface.
1 class Person : IComparable<Person> 2 { 3 public string FirstName { get; set; } 4 public string LastName { get; set; } 5 public int Age { get; set; } 6 7 public Person(string fn, string ln, int age) 8 { 9 FirstName = fn; 10 LastName = ln;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

11 12 13 14 15 16 17 18 19 20 21 22 23}

Age = age; } public int CompareTo(Person other) { if (this.Age > other.Age) return 1; else if (this.Age < other.Age) return -1; else //if equal return 0; }

Example 1 Line 1 specifies that the method implements IComparable<T> interface. We need to replace T with the type of the object to be compared, in this case, Person. Implementing that interface requires you to implement a method named CompareTo() which accepts the other object to be compared to this instance and returns an integer value which is the result of the comparison. Lines 14 to 22 defines that method and inside it, we tests whether the Age of this instance is greater than, less than, or equal to the other Person being compared. A value greater than 0 is returned if value from this instance is greater than the value of the other. A value less than 0 is returned if value of this instance is less than the other, and 0 if both values are equal. We can simply use 1 for greater than, -1 for less than, or 0 for equal. Now that a class implements the IComparable<T> interface, we can simplify the LINQ query. Since we used the Age property inside the CopareTo method, not specifying a property as a key for ordering the results in a LINQ query will sort the results based on each person's age.
List<Person> people = new List<Person>() { new Person("Peter", "Redfield", 32), new Person("Marvin", "Monrow", 17), new Person("Aaron", "Striver", 25) }; var defaultSort = from person in people orderby person select person; foreach (var person in defaultSort) { Console.WriteLine(String.Format("{0} {1} {2}", person.Age, person.FirstName, person.LastName)); } 17 Marvin Monrow 25 Aaron Striver 32 Peter Redfield

The OrderBy() and OrderByDescending() Methods

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The OrderBy() and OrderByDescending() methods in System.Linq are the corresponding LINQ methods of the orderby clause. The OrderBy() method sorts the results in ascending order based on a specified key, and the OrderByDescending() method is the opposite which sorts the results in descending order. We can pass a lambda expression specifying the key to be used for sorting.
int[] numbers = { 5, 1, 6, 2, 8, 10, 4, 3, 9, 7 }; List<Person> people = GetPersonList(); var orderByQuery1 = numbers.OrderBy( number => number ); var orderByQuery2 = numbers.OrderByDescending( number => number ); var orderByQuery3 = people.OrderBy( person => person.FirstName ); var orderByQuery4 = people.OrderByDescending( person => person.Age );

The ThenBy() and ThenByDescending() Methods


If you have multiple keys that you want to use, then you can use the ThenBy() and ThenByDescending() methods. For example, the LINQ query:
var orderByQuery5 = from p in people orderby p.LastName, p.FirstName select p;

is equivalent to the following.


var orderByQuery5 = people.OrderBy(p => p.LastName).ThenBy(p => p.FirstName);

You can use the ThenByDescending() method if you want the following keys to sort results in descending order.
var orderByQuery6 = people.OrderBy(p=>p.LastName).ThenByDescending(p=>FirstName); var orderByQuery7 = people.OrderByDescending(p=>p.LastName) .ThenByDescending(p=>p.FirstName);

Note that ThenBy() and ThenByDescending() are methods of IOrderedEnumerable<T> interface and the OrderBy() methods and the orderby clause returns a collection implementing this interface. Therefore, you must use OrderBy() or OrderByDescending() before calling ThenBy() or ThenByDescending().

Using an IComparer<T> Interface Object


An overloaded version of the four discussed ordering methods accepts a second comparer object argument. We can create a comparer class which implements the IComparer<TKey> interface.
class FirstNameComparer : IComparer<Person>

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

{ public int Compare(Person x, Person y) { return x.FirstName.CompareTo(y.FirstName); } }

The interface will require you to create an implementation for it's Compare() method which is similar to the CompareTo() method of the IComparable<T> described eariler, except that it accepts two arguments which are the objects to be compared. We simply use the CompareTo() method of the String class which also returns and integer. We compared the FirstNames of the persons being compared . We can then pass an instance of this comparer as a second argument to the OrderBy, OrderByDescending, ThenBy, or ThenByDescending.
var orderByQuery8 = people.OrderBy(person => person, new FirstNameComparer());

The second argument will then affect which key to use when ordering the results of a query. The above method call simply uses the whole person as the key, and with the help of the FirstNameComparer object, the method automatically orders the result by each person's FirstName property. An alternative for using methods for ordering in descending order and using the descending keyword is the Reverse() method.
var orderByQuery9 = (from person in people orderby person.FirstName select person).Reverse(); var orderByQeury10 = people.OrderBy(person => person.FirstName).Reverse();

On the first example, the whole query is enclosed in parentheses to treat it as one and then we used the Reverse() method to the result of the query. The second example is the same as the first but uses the method syntax.

The let Clause


The let clause allows you to store a result of an expression inside a query expression and use it on the remaining part of the query. A let clause is useful when the query is using an expression multiple times in a query or if you simply want to create an short alias to a very long variable or property name.
List<Person> persons = new List<Person> { new Person { FirstName="John", LastName="Smith" }, new Person { FirstName="Henry", LastName="Boon" }, new Person { FirstName="Jacob", LastName="Lesley" } };

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

var query = from p in persons let fullName = p.FirstName + " " + p.LastName select new { FullName = fullName }; foreach (var person in query) { Console.WriteLine(person.FullName); }

Example 1 In the query expression in Example 1, the result of an expression to combine a person's FirstName and LastName properties and it store it to a variable for easy access. The rest of the query expression after the let clause can now use the variable containing the result of the expression. As you can see in the select clause of the query expression in Example 1, we used the newly created variable from the let clause and to create a property named FullName during projection. The let clause doesn't have an equivalent query method. The following rewrites the query expression above using the method syntax.
var query = persons.Select(p => new { fullName = p.FirstName + " " + p.LastName }) .Select(p => new { FullName = p.fullName });

The following are more examples of using the let clause.


int[] numbers = { 1, 2, 3, 4, 5 }; //Query Expression var query1 = from n in numbers let squared = n * n select squared; //Method Syntax var query2 = numbers.Select(n => new { squared = n * n }) .Select(n => n.squared);

Example 2
//Query Expression var query1 = from p in persons let isTeenager = p.Age < 20 && p.Age > 12 where isTeenager select new { p.FirstName, p.LastName }; //Method Syntax var query2 = persons.Select(p => new { isTeenAger = p.Age < 20 && p.Age > 12 }) .Where(p => p.isTeenager) .Select(p => new { p.FirstName, p.LastName });

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Example 3 The above query uses the variable created by the let clause as an argument to the where clause since the expression in the let clause is a boolean expression.

Joining Data Sources


There are times where you want to combine values from different data sources into just one result. Of course those data sources must be related in some way. In LINQ, you can use the join clause or the Join() method to join multiple data sources with properties or fields that can be test for equivalency. With the join clause or the Join() method, you can do inner joins, group joins, or left outer joins. The concepts of joins in LINQ can be compared to joins in SQL. If you know how to do joins in SQL, then you may find the following concepts very familliar. Joins can be very hard to understand for a begginer so I will try my best to explain every concept as clear as possible. You will see how to use the join clause in the next lesson. Consider an Author database table containing names of authors and their respective AuthorId. Another table named Books which contains records of books with their titles and the AuthorId of the author that wrote them. One can join this two tables which means, each record of the result of a query is a combination of values from each of the table. A combined record for example, will have the Name of the author and the Title of the book. For two data sources to be joint together, each item or record must have a key that will be tested for equivalence. Only the two records which have equivalent keys will be combined. In our Authors and Books example, we can add an AuthorId field to both of the tables. An author can have an AuthorId that will uniquely identify him, while a book can have an AuthorId that determines which author wrote that book. In a join, there is an inner data source and an outer data source. The inner data source contains items which will be combined to the outer data source. Each of the inner item searches for a matching outer item and the two items are joined to create one new record. The following lessons discusses three types of joins. Inner joins allow you to combine two data sources and create a rectangular result. During an inner join, outer items that have no corresponding inner item are not included in the result set. Inner joins are the simplest and easiest type of join. Another type of join is the group join, which produces a hierarchical result set. It groups related items from one source by an item from another table. For example, you can place all the books written by a certain author into a group. Left outer joins is similar to an inner join as it also creates a rectangular result set, but it also includes outer items which has no corresponding inner item. You will learn more about each of this types of join in the following lessons. Note that you can also do joins using multiple from clauses but it will require you to properly structure your classes when defining them. For example, an Author can have a property named Books, which contains a collection of Book objects that the author writes. Join clause can be effectively used if both classes has no defined relationship. We just need to define the key property to be compared during the join operation.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

The join Clause - Doing an Inner Join


Inner joins are the simplest type of join. This type of join returns a flat or rectangular result. It means that when you look at the result of the query, it would look like a table in which every cell has a value. Suppose we have two database tables named Authors and Books. The Authors table contains data of different authors. The Books table contains data of different books along with the ID of author that wrote a particular book. Joining the two tables using inner join will yield a rectangular result as seen in Figure 1. Author Book John Smith Little Blue Riding Hood John Smith Snow Black John Smith Hanzel and Brittle Harry Gold My Rubber Duckie Harry Gold He Who Doesn't Know His Name Ronald Schwimmer The Three Little Piggy Banks Figure 1 - A Rectangular Result An author can have multiple books assigned to him. In Figure 1, you can see that John Smith wrote three books, Harry Gold wrote two, and Ronald Schwimmer wrote only one book.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 2 - Inner Join For every item in the inner data source, it searches for its corresponding item in the outer data source and creates a combined item of that outer item and the inner item. After the first inner item finds its corresponding outer item, the second inner item is next and it also searches for its corresponding item in the outer data source. This repeats until all the inner items from the inner data source have found their corresponding item. To determine if two items are equal, both items must have a member or property which should have equal value. As you can see in Figure 2, Outer Item 4 was not included in the results. Any outer items that has no corresponding inner item is not included in the results. Same goes to an inner item that has no corresponding outer item. Let's take a look at the following example. The following code defines two classes, Author and Book.
class Author { public int AuthorId { get; set; } public string Name { get; set; } } class Book { public int AuthorId { get; set; } public string Title { get; set; } }

As you can see in the above code, both Author and Book has the same AuthorId property. This will be the property that will determine the correspondence of a Book object to an Author object. Note that the properties doesn't need to have the same name but they should have the same data type. Example 1 creates Author and Book objects. Each book has its AuthorId pointed to a specific Author.
1 class Program 2 { 3 public static void Main(string[] args) 4 { 5 Author[] authors = new Author[] 6 { 7 new Author() { AuthorId = 1, Name = "John Smith" }, 8 new Author() { AuthorId = 2, Name = "Harry Gold" }, 9 new Author() { AuthorId = 3, Name = "Ronald Schwimmer" }, 10 new Author() { AuthorId = 4, Name = "Jerry Mawler" } 11 }; 12 13 Book[] books = new Book[] 14 { 15 new Book() { AuthorId = 1, Title = "Little Blue Riding Hood" }, 16 new Book() { AuthorId = 3, Title = "The Three Little Piggy 17Banks" }, 18 new Book() { AuthorId = 1, Title = "Snow Black" }, 19 new Book() { AuthorId = 2, Title = "My Rubber Duckie" },

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

20 new Book() { AuthorId = 2, Title = "He Who Doesn't Know His 21Name" }, 22 new Book() { AuthorId = 1, Title = "Hanzel and Brittle" } 23 }; 24 25 var result = from a in authors 26 join b in books on a.AuthorId equals b.AuthorId 27 select new { a.Name, b.Title }; 28 29 foreach (var r in result) 30 { 31 Console.WriteLine("{0} - {1}", r.Name, r.Title); 32 } } }

Example 1
John Smith - Little Blue Riding Hood John Smith - Snow Black John Smith - Hanzel and Brittle Harry Gold - My Rubber Duckie Harry Gold - He Who Doesn't Know His Name Ronald Schwimmer - The Three Little Piggy Banks

The query expression in lines 23-25 uses a join clause. The query expression first gets an Author object from the outer data source which is the authors. Then in the join clause, we retrieve a Book object from the inner source named books and test if the AuthorId of the retrieved author is equal to the books AuthorId. Note that the equals keyword was used instead of ==. The join clause can only test for equality. You cannot use operators such as > or < to compare keys. So to remind you that you can only do equality comparison, Microsoft created an equals keyword instead. If the current book's AuthorId is equal to an author's Author ID, then we can proceed to the select clause where the Name of the author and the Title of the book will be projected. Each of the book is iterated and compared to each author and all of the books with a corresponding author will be included in the results when execution of the query begins. Note that Jerry Mawler was not included in the results because he did not right any book, therefore, there is no item in the inner source that can be joined to him. Also, any book which AuthorId does not exist in the authors will not be included. The join clause, like any other clause, is translated during compilation into a call to the Join method. The query expression in Figure 4 can be translated into the following call to the Join method:
var result = authors.Join(books, author => author.AuthorId, book => book.AuthorId, (author, book) => new { author.Name, book.Title } );

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

This version of Join method performs an inner join. The method accepts four parameters. The first parameter accepts the inner data source, in this case, the books collection. The second parameter accepts a lambda expression that describes the outer key selector. It should have one parameter which will hold the every item from the outer source and then return the key that will be used for joining (we used the AuthorId as the key). The third parameter accepts a lambda expression which has one parameter that will hold every item from the inner data source, and returns the key to be compared to the outer source's key. Finally, the fourth parameter accepts a lambda expression with two parameters, the outer item and inner item that have matching keys. You can then use projection to create the type with the results from the two items.

The join Clause - Doing a Group Join


With the join clause, you can also do group joins. A group join groups the items from the inner data source by their corresponding item from the outer data source. For example, all the books written by John Smith will be grouped together and all the books written by Harry Gold will have a separate group. The diagram below shows how group join works.

Figure 1 All the inner items which has a common key and has a matching key in the outer data source is grouped together to form one group. As you can see, the result of the group join is a collection of groups, each representing a group for a specified key. Again, for example, the key could be the author of the book. You can group a collection of books by authors and the result will be a collection of books grouped by authors. Any outer item that has no matching inner items will produced an empty group but still included in the result. Let's take a look at an example of doing a group join. We will define two classes named Author and Book.
class Author { public int AuthorId { get; set; } public string Name { get; set; } } class Book {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

public int AuthorId { get; set; } public string Title { get; set; } }

The following code contains a query expression that uses a group join using the join clause.
Author[] authors = new Author[] 1 { 2 new Author() { AuthorId = 1, Name = "John Smith" }, 3 new Author() { AuthorId = 2, Name = "Harry Gold" }, 4 new Author() { AuthorId = 3, Name = "Ronald Schwimmer" }, 5 new Author() { AuthorId = 4, Name = "Jerry Mawler" } 6 }; 7 8 Book[] books = new Book[] 9 { 10 new Book() { AuthorId = 1, Title = "Little Blue Riding Hood" }, 11 new Book() { AuthorId = 3, Title = "The Three Little Piggy Banks" }, 12 new Book() { AuthorId = 1, Title = "Snow Black" }, 13 new Book() { AuthorId = 2, Title = "My Rubber Duckie" }, 14 new Book() { AuthorId = 2, Title = "He Who Doesn't Know His Name" }, 15 new Book() { AuthorId = 1, Title = "Hanzel and Brittle" } 16 }; 17 18 var result = from a in authors 19 join b in books on a.AuthorId equals b.AuthorId into 20 booksByAuthor 21 select new { Author = a.Name, Books = booksByAuthor }; 22 23 foreach (var r in result) 24 { 25 Console.WriteLine("Books written by {0}:", r.Author); 26 27 foreach (var b in r.Books) 28 { 29 Console.WriteLine("---{0}", b.Title); 30 } 31 }

Example 1
Books written by John Smith: ---Little Blue Riding Hood ---Snow Black ---Hanzel and Brittle Books written by Harry Gold: ---My Rubber Duckie ---He Who Doesn't Know His Name Books written by Ronald Schwimmer: ---The Three Little Piggy Banks Books written by Jerry Mawler:

Take a look at the join clause in line 20. The join clause will join a book from the books data source to the authors data source in which the AuthorId of the book is equal to the AuthorId of

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

an author. The into keyword signifies the group join followed by a grouping variable. All the inner items' key that corresponds to an outer item's key will be grouped together and will be stored in the grouping variable. The select clause in line 21 projects the result to a new variable with an Author property and a Books property assigned with the group variable. The result of the query expression is a collection of groups of Books. The nested foreach loop in lines 23 to 31 shows the results of the query. Inside the first foreach loop, the name of the author is shown. After that, an inner foreach loop iterates through each of the Book in the author's Book property. Remember that this property contains the collection of books grouped together for a particular author. As you can see in the output, Jerry Mawler written no books so his Books property is empty, therefore, no books were shown. The GroupJoin method is the equivalent method of a join-group-by clause. The equilent query using the GroupJoin method is shown below:
var result = authors.GroupJoin(books, author => author.AuthorId, book => book.AuthorId, (author, booksByAuthor) => new { Author = author.Name, Books = booksByAuthor });

The first parameter is the inner data source that will be joined to the outer data source. The second parameter is a delegate that accepts a lambda expression to determine the outer key to used for joining. The third parameter determines the inner key and the final parameter is used to create the group and project each result.

The join Clause - Doing a Left Outer Join


Using LINQ's join clause, you can also perform a left outer join. Like an inner join, a left outer join also returns a flat result. An inner join omits any item that has no corresponding items from another data source. As an example, if an author wrote no book, then he will be omitted in the result of the query. The left outer join includes even the items that has no corresponding partner in the result. This is made possible using the DefaultIfEmpty method.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 - Left Outer Join Let's take a look at an example of doing a left outer join.
1 Author[] authors = new Author[] 2 { 3 new Author() { AuthorId = 1, Name = "John Smith" }, 4 new Author() { AuthorId = 2, Name = "Harry Gold" }, 5 new Author() { AuthorId = 3, Name = "Ronald Schwimmer" }, 6 new Author() { AuthorId = 4, Name = "Jerry Mawler" } 7 }; 8 9 Book[] books = new Book[] 10{ 11 new Book() { AuthorId = 1, Title = "Little Blue Riding Hood" }, 12 new Book() { AuthorId = 3, Title = "The Three Little Piggy Banks" }, 13 new Book() { AuthorId = 1, Title = "Snow Black" }, 14 new Book() { AuthorId = 2, Title = "My Rubber Duckie" }, 15 new Book() { AuthorId = 2, Title = "He Who Doesn't Know His Name" }, 16 new Book() { AuthorId = 1, Title = "Hanzel and Brittle" } 17}; 18 19var result = from a in authors 20 join b in books on a.AuthorId equals b.AuthorId into 21booksByAuthors 22 from x in booksByAuthors.DefaultIfEmpty(new Book 23{AuthorId=0,Title="None"}) 24 select new { Author = a.Name, x.Title };

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

25 26Console.WriteLine("{0, -20} {1}", "Author", "Book"); 27foreach (var r in result) 28{ Console.WriteLine("{0, -20} {1}", r.Author, r.Title); }

Example 1
Author John Smith John Smith John Smith Harry Gold Harry Gold Ronald Schwimmer Jerry Mawler Book Little Blue Riding Hood Snow Black Hanzel and Brittle My Rubber Duckie He Who Doesn't Know His Name The Three Little Piggy Banks None

To do a left outer join using the join clause, you first need to group join the two data sources. You then perform another query by using the created groups as the data source. You need to callthe DefaultIfEmpty for each group so whenever a group contains no items, a specified default value will be provided. As you can see in the query expression in lines 19 to 22, the first two lines of the query expression performs a group join by querying every author object and joing every book object which has an equal AuthorId property as the queried author's AuthorId property. The next line performs another query by using the grouped result of the first query as the data source. Notice that we call the DefaultIfEmpty method of the group to yield a default value if the group is empty. The DefaultIfEmpty method accepts one argument, which is an instance of an object which has a similar type as every items of the group. Since each group in our query contains Book items, we created new instance of the Book class and specified some default values for its properties using objection initialization syntax. Based on our data sources, Jerry Mawler (AuthorId 4) has no corresponding book from the books data source. If we simly used an inner join, Jerry Mawler will be gone in the results, but since we used left outer join, Jerry Mawler was included and as you can see in the output of Figure 2, the default value you specified was shown as his book. There is no direct equivalent of a left outer join when you want to use the method syntax. Doing a left outer join using the method syntax requires the combination of the GroupBy method and the SelectMany method.
var result = authors.GroupJoin(books, author => author.AuthorId, book => book.AuthorId, (author, booksByAuthor) => new { Author = author, Books = booksByAuthor }) .SelectMany(x=>x.Books.DefaultIfEmpty(new Book{AuthorId = 0,Title = "None"}),

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

(x, y) => new { Author = x.Author.Name, y.Title });

The GroupJoin method simply groups each books by author and projects a new type with an Author property assigned with the author and Books property assigned with the group of books he wrote. We then nested a call to the SelectMany method. The SelectMany method here accepts two parameters. The first is the collection selector which selects item from the result yielded by the GroupJoin method. Notice that we call the DefaultIfEmpty method so if the Books property of an item is empty, then a default set of values specified will be used. The second parameter is the result selector and through here, you can project the final result of the query.

The join Clause - Doing a Left Outer Join


Using LINQ's join clause, you can also perform a left outer join. Like an inner join, a left outer join also returns a flat result. An inner join omits any item that has no corresponding items from another data source. As an example, if an author wrote no book, then he will be omitted in the result of the query. The left outer join includes even the items that has no corresponding partner in the result. This is made possible using the DefaultIfEmpty method.

Figure 1 - Left Outer Join Let's take a look at an example of doing a left outer join.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Author[] authors = new Author[] 1 { 2 new Author() { AuthorId = 1, Name = "John Smith" }, 3 new Author() { AuthorId = 2, Name = "Harry Gold" }, 4 new Author() { AuthorId = 3, Name = "Ronald Schwimmer" }, 5 new Author() { AuthorId = 4, Name = "Jerry Mawler" } 6 }; 7 8 Book[] books = new Book[] 9 { 10 new Book() { AuthorId = 1, Title = "Little Blue Riding Hood" }, 11 new Book() { AuthorId = 3, Title = "The Three Little Piggy Banks" }, 12 new Book() { AuthorId = 1, Title = "Snow Black" }, 13 new Book() { AuthorId = 2, Title = "My Rubber Duckie" }, 14 new Book() { AuthorId = 2, Title = "He Who Doesn't Know His Name" }, 15 new Book() { AuthorId = 1, Title = "Hanzel and Brittle" } 16}; 17 18var result = from a in authors 19 join b in books on a.AuthorId equals b.AuthorId into 20booksByAuthors 21 from x in booksByAuthors.DefaultIfEmpty(new Book 22{AuthorId=0,Title="None"}) 23 select new { Author = a.Name, x.Title }; 24 25Console.WriteLine("{0, -20} {1}", "Author", "Book"); 26foreach (var r in result) 27{ 28 Console.WriteLine("{0, -20} {1}", r.Author, r.Title); }

Example 1
Author John Smith John Smith John Smith Harry Gold Harry Gold Ronald Schwimmer Jerry Mawler Book Little Blue Riding Hood Snow Black Hanzel and Brittle My Rubber Duckie He Who Doesn't Know His Name The Three Little Piggy Banks None

To do a left outer join using the join clause, you first need to group join the two data sources. You then perform another query by using the created groups as the data source. You need to callthe DefaultIfEmpty for each group so whenever a group contains no items, a specified default value will be provided. As you can see in the query expression in lines 19 to 22, the first two lines of the query expression performs a group join by querying every author object and joing every book object which has an equal AuthorId property as the queried author's AuthorId property. The next line performs another query by using the grouped result of the first query as the data source. Notice that we call the DefaultIfEmpty method of the group to yield a default value if the group is empty. The DefaultIfEmpty method accepts one argument, which is an instance of an object

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

which has a similar type as every items of the group. Since each group in our query contains Book items, we created new instance of the Book class and specified some default values for its properties using objection initialization syntax. Based on our data sources, Jerry Mawler (AuthorId 4) has no corresponding book from the books data source. If we simly used an inner join, Jerry Mawler will be gone in the results, but since we used left outer join, Jerry Mawler was included and as you can see in the output of Figure 2, the default value you specified was shown as his book. There is no direct equivalent of a left outer join when you want to use the method syntax. Doing a left outer join using the method syntax requires the combination of the GroupBy method and the SelectMany method.
var result = authors.GroupJoin(books, author => author.AuthorId, book => book.AuthorId, (author, booksByAuthor) => new { Author = author, Books = booksByAuthor }) .SelectMany(x=>x.Books.DefaultIfEmpty(new Book{AuthorId = 0,Title = "None"}), (x, y) => new { Author = x.Author.Name, y.Title });

The GroupJoin method simply groups each books by author and projects a new type with an Author property assigned with the author and Books property assigned with the group of books he wrote. We then nested a call to the SelectMany method. The SelectMany method here accepts two parameters. The first is the collection selector which selects item from the result yielded by the GroupJoin method. Notice that we call the DefaultIfEmpty method so if the Books property of an item is empty, then a default set of values specified will be used. The second parameter is the result selector and through here, you can project the final result of the query.

More LINQ Examples


Now that you have learn some basic LINQ querying including how to select, filter, and order results of a query, let's take a look at more examples combining the concepts of the past lessons and introducing some new LINQ features as well. The examples will allow you to more familiar to more techniques of using LINQ. I will show the LINQ query and its corresponding method calls to LINQ methods.
var query1 = from p in people orderby p.LastName where p.Age >= 18 select new { p.FirstName, LN = p.LastName }; var query1 = people.OrderBy(p => p.LastName).Where(p => p.Age >= 18) .Select(p => new { p.FirstName, LN = p.LastName });

The queries above are equivalent and they both represent sombe combinations of selecting, filtering and ordering results. We must take note of the second version where we used the actual
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

LINQ methods. The dot operator was used immediately after the end of the previous method. The methods or members you can call after the dot operator depends on the value returned by the previous method. Since LINQ methods returns a result implementing IEnumerable<T>, you can nest or cascade method calls one after the other. The final result to be stored in the result variable depends on the final results of the last LINQ method call, in the case above, the Select method. The second version presented can also be called the dot notation style.
var query2 = from p in people orderby p.LastName, p.FirstName where p.Age >= 18 && p.LastName.StartsWith("A") select new { FullName = p.FirstName + " " + p.LastName }; var query2 = people.OrderBy(p=>p.LastName).ThenBy(p=>p.FirstName) .Where(p=>p.Age >= 18 && p.LastName.StartsWith("A")) .Select(p=> new {FullName = p.FirstName + " " + p.LastName });

The query selects persons from the people collection ordering the results by LastName and then by FirstName, and whose Age is greter than or equal 18 and has a LastName which starts with A. The query then selects an annonymous type containing the FullName of the person that met the condition in the where clause. We can use the let clause to define another range variable inside a query and assign it with an expression or property of the original range variable. The following shows you an example of using the let clause.
var query2 = from p in people let lastName = p.LastName where lastName.StartsWith("A") select lastName; var query2 = people.Select(p=> new { p, lastName = p.LastName }) .Where(pln => pln.lastName.StartsWith("A")) .Select(pln => pln.lastName)

We defined a new range variable and assigned the LastName property of the original range variable. We can now use the new range variable in the following clauses. The second version that uses dot notation style shows how we can do the same functionality as the first version. The let clause in a LINQ query is just similar to a Select method. We called the Select method at the very beginning so the following methods will know the modifications made. We can use multiple data sources and compare each of their values against each other. The following uses two from clauses that retrieves values from two integer arrays.
var query3 = from x in n1 from y in n2 where x == y select x; var query3 = n1.Intersect(n2);

The query first retrieves a value from n1. The retrieved value will then be compared to each value in n2 thanks to the second from clause and the where clause. The where clause states that

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

only retrieve the value of x that has an equal value in any of the elements of y. This is also called intersections where only values that both exists in two sets will be returned in the result set. We can simply use the Intersect method to do the same thing. Another example is an object that contains a property containing a collection of more objects. Imagine our Person class having a property named Siblings which is a list of siblings (List<Person>) of a person. We can select every sibling of a person and even specify a condition for the selection.
var query4 = from p in people from s in p.Siblings where s.Age < p.Age select new { FullName = p.FirstName + " " + p.LastName, SiblingName = s.FirstName + " " + s.LastName }; var query4 = people.SelectMany(p => p.Siblings.Select(s => s).Where(s => s.Age < p.Age));

The first from clause retrieves a Person from the list of Person objects. The second from clause retrieves every Person object in the current Person's Sibling property. The first from clause will only continue to retrieve the next Person object after the second from clause is finish retrieving all of the items from the Siblings property. The where and select clauses in the query also executes for every item retrieve by the latter from clause from its corresponding data source. The second version of the query uses the SelectMany method. You can see that inside it is a lambda expression selecting every Person from people and we accessed each person's Sibling property and used another Select method followed by a Where method inside the SelectMany method.

LINQ Aggregate Methods


LINQ has aggregate operators or methods that allows you to perform mathematical calculations based on the values of all the elements in a collection. We will learn here the different aggregate operators that will simplify the way you do most common tasks involving sets or collections of values. Example of what aggregate operators can do is automatically getting the sum, average, min, max, and how many elements a collection has.

The Count and LongCount Methods


We can determine the number of elements a collection or array has by using the Count and LongCount methods. The Count method simply counts the number of elements of a collection. For collections containing a very huge number of elements, we can use the LongCount method instead. The following example shows the use of the Count operator.
int[] numbers = { 7, 2, 6, 1, 7, 4, 2, 5, 1, 2, 6 }; Console.WriteLine("numbers has {0} elements.", numbers.Count());

An overload of both Count and LongCount allows you to pass a predicate that will determine which elements to include in the counting. Consider the following example:

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Console.Write("Number of even numbers in the collection: {0}", numbers.Count(n => n % 2 == 0));

The lambda expression inside the overloaded Count method specifies the condition that an element must meet for it to be included in the counting.

The Min and Max Methods


The Min and Max methods returns the minimum and maximum values from a collection respectively. The parameterless versions of this method is very simple and returns the expected results.
int[] numbers = { 7, 2, 6, 1, 7, 4, 2, 5, 1, 2, 6 }; Console.WriteLine("Min = {0}\nMax = {1}", numbers.Min(), numbers.Max());

For complex objects that does has no implementation for IComparable, that is, a default behavior when being compared, we can use an overloaded of the Min() and Max() methods which accepts a predicate that specifies the key or expression to be used.
List<Person> people = GetPersonList(); //Assume the method returns a collection of Person objects Console.WriteLine("Youngest Age is {0}", people.Min( p=>p.Age )); Console.WriteLine("Oldest Age is {0}", people.Max( p=>p.Age ));

We passed a lambda expression specifying that we should use the Age property of each person as a key and therefore, the Min and Max methods returned the minimum and maximum age of all the persons in the collection.

The Average Method


The Average method is obviously used for determining the average of numeric values. The average is the sum of all the values of every element divided by the number of elements.
int[] numbers = { 7, 2, 6, 1, 7, 4, 2, 5, 1, 2, 6 }; Console.WriteLine("Average = {0}", numbers.Average());

Like Min and Max methods, the Average method has an overloaded version which accepts a predicate to determine which key to use when obtaining the average of a complex object such as our example Person class.
List<Person> people = GetPersonList(); Console.WriteLine("Average age of all the persons"); Console.WriteLine("Average = {0}", people.Average( p => p.Age ));

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The lambda expression states that we use the Age of every person as the key on getting the average value. Therefore, the method Average results to the average Age of all the persons in the collection.

The Sum Method


The Sum method is also a very simple to understand operator which simply gets the overall sum of all the values of elements in a collection.
int[] numbers = { 7, 2, 6, 1, 7, 4, 2, 5, 1, 2, 6 }; Console.WriteLine("Sum = {0}", numbers.Sum);

Again, we can use an overloaded version which accepts a predicate that will determine a key from a complex object such as Person.
List<Person> people = GetPersonList(); Console.WriteLine("Total age of all the persons"); Console.WriteLine("Total = {0}", people.Sum(p => p.Age));

The expression inside the Sum method instructs the method to add the age of every person together.

The Aggregate Method


The Aggregate method is a more flexible version of method Sum. Instead of limiting you to just summing up values in a collection, you can define a predicate with two parameters, the first one being the first nubmer or the previous result, and the second one is the second or next number to participate the calculation.
int[] numbers = { 1, 2, 3, 4, 5 }; Console.WriteLine( numbers.Aggregate( (n1, n2) => n1 + n2 ) );

The Aggregate method contains a two-parameter lambda expression and inside its body, we add the two numbers. Initially, n1 will contain the first value of the array, and n2 will have the second value. It will be added and stored to n1. The next value (third value) will then be stored to n2, and will be added again to n1 whose result will be stored to n1 and n2 aquiring the value of the next element. This repeats until n2 has the value of the last element. The result of the above call to Aggregate is similar to Sum method since we add every numbers. A great thing about the Aggregate method is we can choose the operator we want on the calculation. Below is a modification of the previous code where the Aggregate returns the overall product of the collection using the multiplication operator.
int[] numbers = { 1, 2, 3, 4, 5 };

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Console.WriteLine( numbers.Aggregate( (n1, n2) => n1 * n2 ) );

You can even create complex expressions like this.


int[] numbers = { 1, 2, 3, 4, 5 }; Console.WriteLine( numbers.Aggregate( (n1, n2) => (n1 / 2) + (n2 / 2) ) );

The Aggregate method above halves the values before adding them to each other. Another overload of the Aggregate method accepts a seed which is simple the one that will take the first slot in the calculation.
int[] numbers = { 1, 2, 3, 4, 5 }; Console.WriteLine( numbers.Aggregate( 1, (n1 , n2) => n1 + n2 ));

Notice that Aggregate now has two parameters, the first one being the seed and the second one is the predicate specifying how to process each pair of values. Since we specified a seed of 1, the calculation will start at 1 plus whatever the first value of the array is. Since the first value of the array in the code above is 1 and the specified seed is 1, then the first calculation will be 1 + 1 (seed + first). A third overload of the Aggregate method accepts a third argument which specifies the formatting of the result.
Console.WriteLine( numbers.Aggregate( 1, (n1, n2) => n1 + n2, n => String.Format("{0:C}", n)));

The third parameter is another lambda expression that will format the result into currency format. Using these aggregate methods is a great help for programmers as it saves development time and is really easy to use once you mastered them.

LINQ to SQL
LINQ to SQL is a powerful tool which allows developers to access databases as objects in C#. With LINQ to SQL, you are able to use LINQ query operators and methods instead of learning SQL. LINQ to SQL has an API for connecting and manipulating database. LINQ queries and calls to the API methods are then translated to SQL commands which are executed to provide changes or to retrieve queries from the database. LINQ to SQL is a more modern way of accessing database using C# and .NET. Please do note that LINQ to SQL is only applicable when you are using SQL Server as your database. We will be using the Northwind database as our sample database. If you are using the free Visual C# Express then we need to access the actual database file which has a .mdf file extension. If you installed the Northwind database correctly, the file can be found in C:\SQL Server 2000 Sample Databases. If the file extension is not visible, go to Control Panel, choose Folder

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Options and click the View tab, and uncheck "Hide extensions for known file types", then click OK. We will be using the Northwind.mdf database file. Database files are created with .mdf extensions whenever you create a database in SQL Server. SQL Server Express 2008 has a default folder for storing database files and it is located at C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data. So if you executed the scripts for creating the Northwind database as instructed in the first lessons, then you can also find a copy of Northwind.mdf here. We can proceed if once you have possession of the Northwind.mdf file. Visual Studio has a great tool for generating LINQ to SQL classes with the use of Object Relational Designer. You can simply drag and drop tables there and Visual Studio will automatically create the neccessary classes the corresponds to each tables and rows of the specified table and database. You will then see the tables with properties corresponding to its columns or fields. Arrows will also be visible representing relationships between tables.

Figure 1 - Object Relational Designer showing tables, fields and relationships. Classes will be created that represents the rows of each table.For example, we have an Employees table. Visual Studio will automatically singularize the table's name and an object named Employee will be created that will represent each row or records of the particular table.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

A corresponding class of type Table<TEntity> of the System.Data.Linq namespaces will be created for every table included in the LINQ to SQL Designer. The TEntity is replaced with the class of the row it contains. For example, the Employees table will have a corresponding class of Table<Employee> class. An object of that class will then be created containing a collection of objects for each of its rows or records. Table<TEntity> implements IQueryable<TEntity> interface of the System.Linq namespace. When a LINQ queries an object that implements this interface and obtains results from a database, the results are automatically stored to the corresponding LINQ to SQL classes. For related tables which are connected to each other via foreign keys, for each foreign key a table has, Visual Studio creates a corresponding property with the type and name similar to each row of the table the foreign key points to. Additionally, for a table whose primary key(s) are used as a foreign key by other tables, for each of those foreign tables, a property is also created. This additional properties allow you to call the properties of the foreign table of a current table. For example, two tables named Employees and Companies table both have CompanyID fields. The CompanyID is the primary key of the Companies table, and the CompanyID field of the Employees table is a foreign key pointing to the CompanyID of the Companies table. When Visual Studio creates the corresponding row class for each table, it will also consider the foreign keys. The Employee class for the Employees table will have an additional Company property since one of its columns points to the Companies table. The Company class of the Companies table will have an additional Employee property because the Employees table points to the Categories table. LINQ to SQL also creates a DataContext class which inherits from the System.Data.Linq.DataContext. This class will be responsible for connecting the program and the database. The objects created for each table that you include in the LINQ to SQL designer becomes a property of this class. Visual Studio will automatically create the DataContext in a format <Database>DataContext where <Database> is the name of the database. For example, using our Northwind database, a NorthwindDataContext will be created with properties corresponding to each tables we have included. These properties contains collections of objects representing the rows of each table. For example, our NorthwindDataContext class will have a Employees property which corresponds to the Employees table. This property is a collection of Employee objects representing each rows of the table. The next lesson will show you an example of using LINQ to SQL and connecting your application to the Northwind database using this technology.

Querying a Database with LINQ to SQL


We will be creating a Windows Forms Application that allows as to you to query and view records from a particular table using LINQ to SQL classes, SQL Server 2008, and the Northwind sample database. You will learn how to use the Object Relational Designer to generate LINQ to SQL Classes and how to use them in your code.

Creating LINQ to SQL Classes

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Create a new Windows Forms Application and name it LinqToSqlDemo. Once a project is created, we need to add a LINQ to SQL file. Click the Add New Item button in the toolbar and find LINQ to SQL Classes from the list of templates. Name it Northwind and click the Add button.

Once you click the Add button, you will land on the Object Relational Designer containing nothing as off now.

The Toolbox now also contains components used for creating classes and adding relationships. But since we will generate a class from an existing table in a database, we wont be using the components in the Toolbox. A DBML file (Database Markup Language) with extension .dbml will also be created and shown in the Solutions Explorer. Expanding that node will show two more files representing codes for the layout and the actual classes that will be generated. Double clicking the DBML file will also bring you to the Object Relational Desinger.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We need to use the Database Explorer window in Visual C# Express. If you are using the full version of Visual Studio, you need to open the Server Explorer window instead. If it is not visible, go to Views > Other Windows > Database Explorer. Open the Database Explorer window and click the Connect to Database icon.

You will be presented with the Choose Data Source Dialog which asks which type data source to use for the connection. Choose SQL Server Database File. Checking the check box allows you to always choose the specified type of data source when you want to add another one.

You will be presented by another window asking for the type of data source and the location of the database files. You can also specify which SQL Server account to use but if you are using an administrator windows user account, then you can simply leave the default option. You can also click the Advanced button to edit more advanced settings about the connection.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Click the Browse button and browse for the Northwind.mdf file. If you have installed it already, it will be located at C:\SQL Server 2000 Sample Databases. Choose the file and click Open. Be sure that the file is not used by other programs. We then need to test the connection. Click Test Connection button and if everything is working properly, you will receive the following message.

The Northwind.mdf will now appear as a child node of the Data Connections in the Database Explorer window. Expand the Northwind.mdf node to be presented with folders representing the different components of the database. Expand the Tables folder to see the different Tables of the Northwind database. We need to drag tables from the Database Explorer window to the Object Relational Designer's surface. For this lesson, drag the Employees table to the Object Relational Designer.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Visual Studio will prompt you whether to copy the Northwind.mdf database file since it will detect that it is located outside your project folder. Clicking Yes will copy the Northwind.mdf file from the origincal location to your project folder. Also note that everytime you run your program, the database file will also be copied to the output directory. You will learn later how to modify this behavior.

After clicking Yes, The Object Relational Designer will now show a class diagram representing a generated class that will hold values of each row in the Employees table. The name of the class is a singularized version of the Table's name. A property with an appropriate type is created for every column in the dragged table. You will see these properties in the Object Relational Designer. If a property conflicts with the name of the class, then it will be numbered. For

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

example, if the class' name is Employee and it has a column named Employee as well, then the column's corresponding property will be named Employee1.

As soon as you drag a table to the Object Relational Designer, the DataContext class for the coresponding database will be created. Since we used the Northwind database, the generated DataContext class will be named NorthwindDataContext. Clicking a blank space in the Object Relational Designer will allow you to edit the properties of the DataContext class using the Properties Window. You can also change the properties of the created row class and properties of its members. But leaving the default names and settings for the classes is recommended. If you are curious about the generated classes and wan't to take a look at its implementation, go to Solution Explorer and expand the node for the created DBML file. You will be presented with two files. Double click the one with .designer.cs extension. You will then see how the classes for your tables and DataContext was defined. You should always save the DBML file before using it in your application.

Using LINQ to SQL Classes


Once the required LINQ to SQL classes have been successfully generated, we can now use them in our application. For our GUI, we will be using a DataGridView control to display the queried records. Head back to the Windows Forms Designer. Drag a DataGridView control from the Toolbox's Data cetegory to the form. Set the DataGridView's Dock property to Fill so it will take up all the space of the form. Then resize the form to a larger size so it will properly show all the records that we will query.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We will be using the following code:


1 using System; 2 using System.Linq; 3 using System.Windows.Forms; 4 5 namespace LinqToSqlDemo 6 { 7 public partial class Form1 : Form 8 { 9 public Form1() 10 { 11 InitializeComponent(); 12 } 13 14 private void Form1_Load(object sender, EventArgs e) 15 { 16 NorthwindDataContext database = new NorthwindDataContext(); 17 18 var employees = from employee in database.Employees 19 select new 20 { 21 employee.EmployeeID, 22 employee.FirstName, 23 employee.LastName,

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

24 25 26 27 28 29 30 31 32}

employee.BirthDate, employee.Address, employee.Country }; dataGridView1.DataSource = employees; } }

Double click the Form's title bar in the Designer to generate a handler for the form's Load event. Add the codes in lines 16-29. The code at line 16 creates a new NorthwindDataContext object. This will be used to access the tables of the database and the rows each table contain. Lines 1827 uses a LINQ query which access the NorthwindDataContext's Employees property containing each record for employee. The select clause of the query only selects some of the properties of every employee. Line 29 uses the DataGridView's DataSource property and assigns the result of the query as it's data source. When you run the program, you will see all the records from the Employees table.

Lines 18-27 is a simple LINQ query that retrieves several properties of every employee in the Employees database. You can perform different LINQ queries that suit your needs. For example, we can modify the LINQ query in 18-27 to only show employees who live in USA.
var employees = from employee in database.Employees where employee.Country == "USA" select new

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

{ employee.EmployeeID, employee.FirstName, employee.LastName, employee.BirthDate, employee.Address, employee.Country };

You can provide controls, for example, a combo box containing different countries, and modify the query based on the selected country in the combo box. For more LINQ techniques, you can review the lessons for the basics of LINQ querying.

Modifying Database with LINQ to SQL


Mapping the database tables and its records to their corresponding LINQ to SQL classes makes it even easier to manipulate databases. Once LINQ to SQL classes are generated, you can do the modification directly to objects of those class. For adding, the DataContext class offers the InsertOnSubmit and pass the new object of the row class to add. When deleting, we can use the DeleteOnSubmit and pass the specified object to delete. We can directly modify the properties of an object representing a record if we want to update it. All of this operations will not immediately affect the actual tables and records in the database. We need to call the SubmitChanges method of the DataContext class first. To access an element of the property representing the Table, we can use the ElementAt method which accepts an integer index and returns the corresponding record object. Our example application will allow the user to check details of every record, and allows you to add, delete and update records using LINQ to SQL and the method offered by the DataContext and Table<TEntity> classes. For the following example the we will create, we will be using a sample database containing a single table named Persons which contains some records. Download Sample Database Once you downloaded the rar file, open it and extract the database file inside it to a location that you can easily find. We will create an application that queries one person at a time and allows us to move through every record using navigation buttons. The appilcation will also allow the user to add, delete, or update records. You will see how easy this can be done using LINQ to SQL classes. Create a new Windows Forms Application and name the project LinqToSqlDemo2. Create a LINQ to SQL and name it Sample.dbml.. Go to the Database Explorer and click the Connect to Database button. Choose Microsoft SQL Server Database file and click OK then browse for the location of the Sample.mdf file you have downloaded. It will now show up in the Database Explorer as a seperate node. Open the nodes and inside the Tables node, drag the Persons table to the Object Relational Designer. Click Yes to accept the option to copy the database file to your project folder.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You will now be presented with a class inside the Object Relational Designer named Person.

As you can see, it only has several properties. We will now create the GUI that we will use to present details of each records and also to add or delete records. Add the neccessary controls and their corresponding text as shown in the GUI below. The numbers will indicate the corresponding names to be used by the controls.

Number Name 1 firstButton 2 prevButton


COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Number Name 3 nextButton 4 lastButton 5 idTextBox 6 firstNameTextBox 7 lastNameTextBox 8 ageTextBox 9 addButton 10 deleteButton 11 updateButton Set the idTextBox's ReadOnly property to true so it can't be modified as it will show a primary key value. You can also set the StartPosition property of the form to CenterScreen. The buttons above will be used to move to the first, previous, next, or last record in the Persons table. The text boxes will be used to display the values of every field of the current person. The buttons below are used to Add, Delete, and Update records. Clicking the addButton will clear the textboxes so it can accept new values from the user to be added to the table. Clicking the deleteButton will delete the current record being shown. Clicking updateButton will update the record being shown if some of its details were modified. We will be using the following code for our application:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 using using using using System; System.Collections.Generic; System.Linq; System.Windows.Forms;

namespace LinqToSqlDemo2 { public partial class Form1 : Form { private int currentIndex; private int minIndex; private int maxIndex; private bool addPending; private SampleDataContext database; private IEnumerable<Person> persons; public Form1() { InitializeComponent(); database = new SampleDataContext(); persons = from p in database.Persons select p; currentIndex = 0;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

27 minIndex = 0; 28 maxIndex = persons.Count() - 1; 29 30 DisableButtons(); 31 32 addPending = false; 33 } 34 35 private void Form1_Load(object sender, EventArgs e) 36 { 37 ShowPersonInfo(currentIndex); 38 } 39 40 private void firstButton_Click(object sender, EventArgs e) 41 { 42 ShowPersonInfo(minIndex); 43 currentIndex = minIndex; 44 DisableButtons(); 45 } 46 47 private void lastButton_Click(object sender, EventArgs e) 48 { 49 ShowPersonInfo(maxIndex); 50 currentIndex = maxIndex; 51 DisableButtons(); 52 } 53 54 private void prevButton_Click(object sender, EventArgs e) 55 { 56 ShowPersonInfo(--currentIndex); 57 DisableButtons(); 58 } 59 60 private void nextButton_Click(object sender, EventArgs e) 61 { 62 ShowPersonInfo(++currentIndex); 63 DisableButtons(); 64 } 65 66 private void addButton_Click(object sender, EventArgs e) 67 { 68 if (addPending == false) 69 { 70 ClearFields(); 71 int newIDnewID = persons.Count() == 0 ? 1 : 72 persons.Last().PersonID + 1; 73 idTextBox.Text = newIDnewID.ToString(); 74 addButton.Text = "Done"; 75 addPending = true; 76 } 77 else 78 { 79 try 80 { 81 //Create new person 82 Person newPersonnewPerson = new Person(); 83 newPersonnewPerson.PersonID = maxIndex + 1;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

84 newPersonnewPerson.FirstName = firstNameTextBox.Text; 85 newPersonnewPerson.LastName = lastNameTextBox.Text; 86 newPersonnewPerson.Age = Int32.Parse(ageTextBox.Text); 87 88 //Add new Person 89 database.Persons.InsertOnSubmit(newPersonnewPerson); 90 database.SubmitChanges(); 91 maxIndex++; 92 currentIndex = maxIndex; 93 DisableButtons(); 94 MessageBox.Show("Successfully added to database.", 95 "Success", 96 MessageBoxButtons.OK, 97 MessageBoxIcon.Information); 98 addButton.Text = "Add"; 99 addPending = false; 100 } 101 catch 102 { 103 MessageBox.Show("Failed to add new record to database. 104Make sure " + 105 "that every field is not empty and in 106a correct " + 107 "format", "Failed", 108 MessageBoxButtons.OK, 109MessageBoxIcon.Error); 110 } 111 } 112 } 113 114 private void deleteButton_Click(object sender, EventArgs e) 115 { 116 try 117 { 118 119database.Persons.DeleteOnSubmit(persons.ElementAt(currentIndex)); 120 database.SubmitChanges(); 121 122 maxIndex--; 123 124 if (currentIndex > maxIndex) 125 currentIndex--; 126 127 MessageBox.Show("Successfully removed from the database.", 128"Success", 129 MessageBoxButtons.OK, MessageBoxIcon.Information); 130 131 ShowPersonInfo(currentIndex); 132 DisableButtons(); 133 } 134 catch 135 { 136 MessageBox.Show("Unable to delete.", "Error", 137 MessageBoxButtons.OK, 138MessageBoxIcon.Error); 139 } 140 }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

141 142 private void updateButton_Click(object sender, EventArgs e) 143 { 144 try 145 { 146 Person modifiedPerson = persons.ElementAt(currentIndex); 147 modifiedPerson.FirstName = firstNameTextBox.Text; 148 modifiedPerson.LastName = lastNameTextBox.Text; 149 modifiedPerson.Age = Int32.Parse(ageTextBox.Text); 150 151 database.SubmitChanges(); 152 MessageBox.Show("Update success!", "Success", 153 MessageBoxButtons.OK, 154MessageBoxIcon.Error); 155 } 156 catch 157 { 158 MessageBox.Show("Error on updating.", "Error", 159 MessageBoxButtons.OK, 160MessageBoxIcon.Information); 161 } 162 } 163 164 private void ShowPersonInfo(int index) 165 { 166 if (persons.Count() == 0) 167 { 168 ClearFields(); 169 MessageBox.Show("Nothing to show.", "Error", 170 MessageBoxButtons.OK, 171MessageBoxIcon.Error); 172 return; 173 } 174 175 Person currentPerson = persons.ElementAt(index); 176 177 idTextBox.Text = currentPerson.PersonID.ToString(); 178 firstNameTextBox.Text = currentPerson.FirstName; 179 lastNameTextBox.Text = currentPerson.LastName; 180 ageTextBox.Text = currentPerson.Age.ToString(); 181 } 182 183 private void DisableButtons() 184 { 185 if (persons.Count() <= 1) 186 { 187 firstButton.Enabled = false; 188 prevButton.Enabled = false; 189 nextButton.Enabled = false; 190 lastButton.Enabled = false; 191 return; 192 } 193 194 if (currentIndex == minIndex) 195 { 196 firstButton.Enabled = false; 197 prevButton.Enabled = false;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 }

nextButton.Enabled = true; lastButton.Enabled = true; } else if (currentIndex == maxIndex) { firstButton.Enabled = true; prevButton.Enabled = true; nextButton.Enabled = false; lastButton.Enabled = false; } else if (currentIndex > minIndex && currentIndex < maxIndex) { firstButton.Enabled = true; prevButton.Enabled = true; nextButton.Enabled = true; lastButton.Enabled = true; } private void ClearFields() { idTextBox.Text = String.Empty; firstNameTextBox.Text = String.Empty; lastNameTextBox.Text = String.Empty; ageTextBox.Text = String.Empty; firstNameTextBox.Focus(); } } }

Example 1 Lines 10-15 declares some required variables that we will use throughout our program. Line 10 declares a variable that will hold the current index of the person to show. Line 11-12 declares variables that will be used to hold the minimum and maximum possible indices so we can avoid IndexOutOfRangeExceptions and disable specific navigation buttons. Line 13 will be used by the addButton later as we will see. Line 14 declares a SampleDataContext object which is the corresponding DataContext of the Sample database. We will use this object to call methods for adding, deleting, updating, and retrieving records from the tables of the Sample database. Line 15 declares an object of type IEnumerable<Person> which will hold all the person records queried from the database. Recall the results of a LINQ query implements IEnumerable<T> so we can simple use this type in the declaration of the object in line 15. This is so we don't have to query all the records everytime we need to use them. We can simple use this object throughout our program. We will first discuss the utility methods that will be used by the application. The ClearFields method (line 205-212) simply clears every text field and sets the focus to the firstNameTextBox. Method DisableButtons (line 172-203) will be used to disable navigation buttons once the currentIndex reached the minimum or maximum bounds. This is to prevent the user to move when no more elements are available to show. It also checks if there is 1 or 0 records left so it can disable all the navigation buttons to prevent the user from moving. The ShowPersonInfo method (153-169) accepts an index and retrieve a Person object using the specified index. Lines
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

155-161 first checks if the number of elements or records in the Persons property is empty using the Count method. If so, we print an error message and return to the caller to prevent the other codes from of the method from executing. In line 163, we used the ElementAt method of the Persons property to retrieve the right object using the index as an argument to the ElementAt method. We then displayed the properties of the retrieved Person object to their corresponding text boxes. Now let's go inside the Form1's constructor (Line 17 - 33). Line 21 creates an instance of the SampleDataContext so it can now be used to perform operations to the database. Lines 22-23 is a simple LINQ query that selects all the person from the Persons property of the SampleDataContext instance which contains every record of person. We then set the currentIndex to 0 to indicate the program should initially show the first record. Lines 27-28 sets the minIndex and maxIndex which holds the minimum and maximum indices respectively. We simply assign the value 0 to the minIndex. The maxIndex was calculated by obtaining the number of person records in the Persons property and subtracting by 1 because indices are 0based. We called the DisableButtons method that we created to disable the buttons that the user won't need as of now. We also set the addPending to false. This will be used by the handler of the addButton later. Go back to the desinger and double click the form's title bar to generate an event handler for its Load event (lines 35-38). Inside the handler, we called the ShowPersonInfo and passed the current value of the currentIndex which is 0 to show the first record in the text boxes. We will now add the Click event handlers for the navigation buttons. In the Designer, double click the firstButton. Use the codes in lines 42-44 for the event handler. The first line calls the ShowPersonInfo and passing the minIndex value to show the very first record. The value of currentIndex is then set back to the value of minIndex. We called the DisableButtons to disable the firstButton and prevButton. The event handler for lastButton (47-52) is the same as the firstButton's only that it shows the details of the last record using the maxIndex variable. The prevButton and nextButton's Click event handlers (54-64) are also nearly identical. The both call the ShowPersonInfo method and pass the currentIndex to show the records at that specified index. We also increment or decrement the currentIndex right inside the method call to adjust value of the currentIndex. The event handler for addButton (66-106) has the following functionality. The addbutton will have two states. The first state is when addPending is set to false. Clicking the button in this state will first clear the text boxes(line 70). It will then calculate the next possible PersonID to assign for the soon to be added new reacord (71). The calculated new id is displayed to the appropriate text box. The Text of the addButton is changed to "Done" to indicate the it is waiting for the user to finish providing values for each fields of the new person to add. The addPending variable is then set to true to transfer the button to its second state. The second state of the addButton is when it is waiting for the user to finish providing values. When the user hits again the addButton while in this state, it will now execute commands to add the new record to the database. Note that everything that will be used to add the new record to the database is enclosed in a try block so we can catch exceptions that might occur including FormatExceptions or ChangeConflictExceptions which is thrown by the SubmitChanges method when it encounters

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

an error. Lines 81-85 creates a new Person object and assign its properties to values of the text boxes. Line 88 uses the Table<TEntity>.InsertOnSubmit method and passes the newly created Person object so it will be added to the database when the DataContext.SubmitChanges method is executed. The SubmitChanges method is called in line 89 to submit that new change that was made, that is, that adding of a new record to the list of Persons in the Persons table. Line 90 adjusts the value of maxIndex by incrementing it by one since the number of records was increased by 1. We set the currentIndex to the value of the maxIndex, called DisableButtons method, and print a success message telling that the adding of the new record to the database was successful. We changed back the button's caption to "Add" and set the addPending to false so it can accept again new records once clicked. The catch block simply shows an error message telling the user that problems occur while adding the new record to the database. The handler for the deleteButton (108-131) also encloses it's code in a try block to prevent uncaught exceptions that might occur. Line 112 uses the DeleteOnSubmit method which accepts the object to delete from table. To retrieve the right Person object to delete, we used the ElementAt method and passed the currentIndex to it. Since a change was made, we called the SubmitChanges method to send the change to the actual database table. We decrement the maxIndex by 1. We also adjust the currentIndex to an appropriate value. Decreasing the maxIndex while while the currentIndex will make currentIndex greater than the maxIndex. Therefore, we also decrement the value of the currentIndex to match the maxIndex. A person right before the deleted person will then be displayed. The updateButton will be used to update the values of the currently displayed person. When a person's details is displayed, you can change the values in the text boxes, and press the updateButton to update the corresponding record in the database. The handler for the updateButton (133-151) creates a Person that will hold a reference to the currently displayed Person. The properties of this Person is then changed using the new values that the user may have provided. We then immediately called the SubmitChanges method to send the changes and update the corresponding record in the database table. Note that there is no method such as UpdateOnSubmit which could have been similar to the two methods we have seen. You simply modify the values of the properties and call the SubmitChanges method. Download Project: LinqToSqlDemo2

LINQ to XML
The .NET Framework provided us with several techniques for accessing and manipulating an XML file. In the past, you can use the XmlReader or the different XML Document Object Model classes such as XmlDocument, XmlElement, and XmlComment. You can also use XML querying languages such as XPath or XQuery to select specific elements in an XML document. The problem is, you have to know this languages which really has nothing to do with C#. That's where LINQ to XML comes in. With LINQ to XML, you can use the LINQ operators to query, manipulate, and create XML documents. If you want to learn the old and non-LINQ way of manipulating and creating XML documents, this site already offers some tutorials for those.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Let's take a look at a simple example of using LINQ to XML on a preexisting XML file containing some data.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Persons> <Person name="John Smith"> <Age>30</Age> <Gender>Male</Gender> </Person> <Person name="Mike Folley"> <Age>25</Age> <Gender>Male</Gender> </Person> <Person name="Lisa Carter"> <Age>22</Age> <Gender>Female</Gender> </Person> <Person name="Jerry Frost"> <Age>27</Age> <Gender>Male</Gender> </Person> <Person name="Adam Wong"> <Age>35</Age> <Gender>Male</Gender> </Person> </Persons>

Example 1 - A Sample XML File Open Visual Studio and create a new Console Application project and name it LinqToXmlPractice. Right click the solution in the Solution Explorer and add a new item. Choose Xml file from the list of template and name it sample.xml. Replace the contents of that file with the one from Example 1. Our sample.xml file contains the XML markup that we will try to query. If you are unfamiliar with XML, there are many good tutorials in the internet that will teach you its concepts. There is also a quick introduction to XML that can be found in this site. The XML file contains one root element named Persons. It contains multiple child elements named Person. Each child element has a name attribute and contains yet another set of child elements, the Age and Gender elements. Now let's write some LINQ query to retrieve, let's say, the names of every person in the XML Document. Open up Program.cs and add using statement for the System.Linq.Xml namespace.
using System.Linq.Xml;

Inside the Main method, write the following:


XDocument doc = XDocument.Load(@"..\..\sample.xml");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

var names = from d in doc.Root.Elements("Person") select d.Attribute("name").Value; Console.WriteLine("Names of every person from the XML file."); foreach (var name in names) { Console.WriteLine("{0}", name); }

Example 2 - Using LINQ to query XML elements


Names of every person from the XML file. John Smith Mike Folley Lisa Carter Jerry Frost Adam Wong

Full explanation for the codes will be in the upcoming lessons. But for now, you can see how easy it is to get any data you want from the elements of an XML document.

Creating an XML Document Using LINQ to XML


If you played with the XML Document Object Model classes to create XML documents from scratch, it will be easy for you to migrate to a brand new set of classes which allows you to create XML elements in a much more natural and easier way. These classes are located inside the Sytem.Linq.Xml namespace. The classic way of loading an XML document is by using the XmlDocument class from the System.Xml namespace.
XmlDocument doc = XmlDocument.Load("myXmlFile.xml");

There is no difference if you are going to use the newer XDocument class.
XDocument doc = XDocument.Load("myXmlFile.xml");

So what makes this new classes have besides from having shorter names compared to their older versions? The answer is functional construction. With functional construction, you don't need to declare the XML DOM elements one by one. You can simply use the overloaded constructors of each X class to suit your needs. This can be seen clearer by looking at an example. By using the old System.Xml's XML DOM classes, the following code is used to create a simple XML file.
//A new XML Document XmlDocument doc = new XmlDocument(); //Xml Declaration XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "utf-8", "yes"); //Attach declaration to the document

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

doc.AppendChild(declaration); //Create a comment XmlComment comment = doc.CreateComment("This is a comment"); //Attach comment to the document doc.AppendChild(comment); //Create root element XmlElement root = doc.CreateElement("Persons"); //Attach the root node to the document doc.AppendChild(root); //Create a Person child element XmlElement person1 = doc.CreateElement("Person"); //Add an attribute name with value John Smith person1.SetAttribute("name", "John Smith"); //Crate Age element XmlElement person1Age = doc.CreateElement("Age"); person1Age.InnerText = "30"; //Create Gender element XmlElement person1Gender = doc.CreateElement("Gender"); person1Gender.InnerText = "Male"; //Attach Age and Gender element to the Person element person1.AppendChild(person1Age); person1.AppendChild(person1Gender); //Attach Person child element to the root Persons element doc.DocumentElement.AppendChild(person1); //Create another Person child element XmlElement person2 = doc.CreateElement("Person"); //Add attribute name with value Mike Folley person2.SetAttribute("name", "Mike Folley"); //Crate Age element XmlElement person2Age = doc.CreateElement("Age"); person2Age.InnerText = "25"; //Create Gender element XmlElement person2Gender = doc.CreateElement("Gender"); person2Gender.InnerText = "Male"; //Attach Age and Gender element to the Person element person2.AppendChild(person2Age); person2.AppendChild(person2Gender); //Attach second Person child element to the root Persons element doc.DocumentElement.AppendChild(person2); //Save the constructed XML into an XML file doc.Save(@"C:\sample1.xml");

Example 1 - Using XML DOM classes to create a file The above code will produce the following XML:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

<!--This is a comment--> <Persons> <Person name="John Smith"> <Age>30</Age> <Gender>Male</Gender> </Person> <Person name="Mike Folley"> <Age>25</Age> <Gender>Male</Gender> </Person> </Persons>

Now let's take a look at using the new LINQ to XML classes to create the very same XML markup.
XDocument doc = new XDocument( new XDeclaration("1.0", "utf-8", "yes"), new XComment("This is a comment"), new XElement("Persons", new XElement("Person", new XAttribute("name", "John Smith"), new XElement("Age", new XText("30")), new XElement("Gender", new XText("Male"))), new XElement("Person", new XAttribute("name", "Mike Folley"), new XElement("Age", new XText("25")), new XElement("Gender", new XText("Male"))))); doc.Save(@"C:\sample2.xml");

Example 2 - Using LINQ to XML classes to create an XML document As you can see, using the XML DOM classes to construct an XML document requires you to declare each component and attach each element to their proper parents one by one. Using the LINQ to XML classes, you can see the every part of the XML document you will create is instantiated inside the constructor of every classes. These method of creating XML markup is called functional construction. Each LINQ to XML class' constructor accepts arguments that may serve as child elements or values of the element it represents. For example, the XElement has the following overload of its constructor:
XElement(XName name, params object[] content)

The first parameter accepts the name of the element. You can simply pass a string as the name and it will automatically be converted to an XName instance. The second parameter is special because it allows you to pass any number of different kinds of objects such as an XText, XAttribute, or an XElement that will be a child element of that current XElement. Other LINQ to XML class only accepts one argument such as XComment and XText which both accept a string argument that represents the text they will render. The following table shows some of the LINQ to XML classes you can use together what part of an XML document they represent.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Class Description XDocument Represents an XML Document XDeclaration Represents an XML Declaration XElement Represents an XML Element XAttribute Represents an attribute of an XML Element XComment Represents an comment XText Represents the inner text of an XML element. Figure 1 - LINQ to XML Classes For example, if you want to create an element named Person with an name attribute of value John Smith, here's the code to do that.
var personElement = new XElement("Person", new XAttribute("name", "John Smith"));

If you want to add a child element for that person, simply add another argument to the constructor of XElement.
var personElement = new XElement("Person", new XAttribute("name", "John Smith"), new XElement("Age", new XText("30")));

The child argument has a name of Age and the next argument to its constructor is it's inner text represented by the XText class. You can also see in Example 2 how every XElement argument was indented. This is to make it look more like the way we indent XML elements. You can already see how the XML output will look like simply by looking at the code. At the end of Example 2 is a call to the XDocument.Save method. This method allows you to save the constructed XML which is currently in memory, into an external XML file. The method accepts a string argument which represents the file path of the file. If the file does not exist, then it will be created. If the file is already there, it will be overwritten. There are other overloads of this method, but for now, this version is sufficient to save the constructed XML to a file.

MORE TUTORIALS COMING SOON

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

C# ADO.NET AND DATABASES Databases and ADO.NET


Most of the applications today uses some sort of data storage. Perhaps the only applications I can imagine that doesn't use some kind of storage for its data are those small and very simple applications. An application can have many kinds of data sources such as a simple text file, an XML file, and a database. Databases are typically used when storing different kinds of data such as the name, address, age, gender, and occupation of a person, musics, pictures, and many more. A database is a collection of different kinds of data structured into tables consisting of fields and records. Most real world applications today uses databases to store informations. Relational databases contain data which are organized and linked to each other. Relational databases contains one or more tables interconnected to each other. Tables consists of rows and columns. In a database, the rows represents each record. For example, on a database containing records of employee, one row represents a record of an employee. The columns represents the fields or attributes. For example, an Employee has a FirstName field, a LastName field, and an Age field. You can also create relations between multiple tables. For example, an Employee table could have a field called City_ID. Then another table called Cities contains fields City_ID and the CityName. You can connect these two tables to form a relation. Structured Query Language (SQL) is the most popular and perhaps the standard way of communicating to a database. It has commands you can use for retrieving, updating, adding, and deleting data from the database. It also allows you to create and modify databases and tables and create relationships between different tables. Database Management Systems (DBMS) such as Microsoft SQL Server allows you to quickly access data from a database. It contains different tools such as tools for querying, creating, deleting and updating a database. Most DBMS provides you a graphical interface for creating common tasks. Other examples of DBMS are Access, Oracle, and MySQL. ADO.NET is part of the .NET framework technology that allows you to access and modify data from different data sources. It supports many types of data sources such as Microsoft SQL Server, MySQL, Oracle, and Mircrosoft Access. The .NET Framework provides a number of data providers that you can use. These data providers are used to connect to a data source, executes commands, and retrieve results.The following lessons uses Windows Forms Applications as a project type for connecting to databases although you can easily incorporate what you will learn in other areas such as ASP.NET.

SQL Basics
Before you deal with accessing and modifying databases, you first need to know the basics of SQL (Structured Query Language). This is the language used for querying databases. SQL is simple and easy to understand. SQL is not only used for querying data, it can pretty much do

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

anything from creating, updating, and deleting databases and tables. Since this site is not about SQL, we will only tackle those that will be needed in the upcoming lessons.

Creating Database and Tables


You can create database using the following syntax. Please do note that SQL is case insensitive. So it doesnt matter if you write the keywords in lowercase.
CREATE DATABASE <Name of Database>;

The <Name of Database> is the name that you want to give to your database. Here's an example.
CREATE DATABASE MyDatabase;

For us to store a Database, we need to create a table. We use the following syntax.
CREATE TABLE ( <Column1> <Column2> . . . <ColumnN> ); <Name of Table> <Datatype>, <Datatype>,

<Datatype>

Again <Name of Table> is the name of the table we want to create. Inside the parentheses are a list of columns and their data type. The data types that you will commonly used is listed below. Data Type Description Example int integer data -3, 1, 12, 57 char(n) fixed length string where n is the maximum length 'hello', 'goodbye' varchar(n) variable length string where n is the maximum length 'hello', 'goodbye' datetime stores date and time Jan 1, 2010 3:00PM date stores date only Jan 1, 2010 time stores time only 3:00PM money stores monetary data 123.45 You might notice that char(n) and varchar(n) seems to be the same. char(n) is fixed and once you give size to it, it will take up memory depending on that size. If the size you have given is 100, and the string you store only has 3 characters, then char(n) will still use memory for 100 characters. varchar(n) is different. It only takes up what is needed. Also note that character strings are enclose inside single quotes. Let's create an example table that can store the FirstName, LastName and Age of employees.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

CREATE TABLE Employees ( EmployeeID int primary key, FirstName varchar(100), LastName varchar(100), Age int );

Notice that we added the primary key word after the data type of EmployeeID. This will signify that EmployeeID will be the primary key of the Employees table. A primary key is a value that identifies a row or record. Primary key must be unique for each of the record. We used EmployeeID as the primary key and not, for example, the FirstName, because multiple employees could have the same name therefore, that will conflict the rule that primary keys need to unique. The FirstName and LastName fields have a data type of varchar(100), that means the length has a maximum of 100 characters. You can also specify a primary key field to be an identity field. An identity field is a field that is automatically being assigned with a value when adding new records. For example, if we add a new record, it will automatically assigned with value 1, and this will be incremented by 1 as new records are added. The following modifies our previous example to make the EmplyeeID as the identity column.
CREATE TABLE Employees ( EmployeeID int identity primary key, FirstName varchar(100), LastName varchar(100), Age int );

We simply used the identity keyword that will specify a column as the identity column. You can use the following SQL Command to Delete an existing table.
DROP TABLE Employees;

This will delete the Employees table and all of its records.

Inserting Records
We use the following syntax to insert records to a table..
INSERT INTO <Table Name> VALUES (<Value1>, <Value2>, ... , <ValueN>);

The <Table Name> is the name of the table where we want to insert our data into. Inside the parenthesis after VALUES, you list all the values for each of the field of the table. The order of data is important. You must follow the order defined when you created the Table. Let's add some records to our Employee Table.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

INSERT INTO Employees VALUES (1, 'John', 'Smith', 21); INSERT INTO Employees VALUES (2, 'Mark', 'Mayer', 23); INSERT INTO Employees VALUES (3, 'Alvin', 'Minsky', 27);

This will insert the 3 employees to our Employees table. Note the order of the parameters. Our table definition defines that the first parameter is the EmployeeID, the second is FirstName, LastName and then the last is the Age. Again, the EmployeeID must be unique because that is the primary key. Another form of the INSERT TO statement allows you to explicitly indicate the columns that you want to add with values. The following only adds values to FirstName and LastName fields.
INSERT INTO Employees (FirstName, LastName) VALUES ('John', 'Smith');

Note that the number and type of values should match the number and type of fields that have been specified.

Deleting Records
To delete a record, we used this syntax.
DELETE FROM <Table Name> WHERE <Condition>;

The condition tells what record you want to delete. Most of the time, you use the primary key field to delete a record. As an example, Let's delete John from our table.
DELETE FROM Employees WHERE EmployeeID = 1;

The above statement reads as "Delete a record from the Employees table whos EmployeeID is equal to 1. Since John has an EmployeeID of 1, he is deleted from the table.

Updating Records
If you want to change a value of a field or fields of an existring record, you can do that using the following syntax.
UPDATE <Table Name> SET <Column> = <Value> WHERE <Condition>;

For example, if you want to change the FirstName of Mark, use the following code.
UPDATE Employees SET FirstName = 'Marco' WHERE EmployeedID = 2;

We set the FirstName field of the employee with EmployeeID that is equal to 2 to 'Marco'. If you want to change the values of multiple fields, then you can seperate them with commas.
UPDATE Employees SET FirstName = 'Marco', LastName = 'Miller' WHERE EmployeedID = 2;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Querying Records
We can use the SELECT statements to query or get data from our database. The syntax is as follows:
SELECT <Column1>, <Column2>, ... <ColumnN> FROM <TableName>;

For example, if we want to query all the FirstNames of the employee, we cas write this code:
SELECT FirstName FROM Employees; FirstName John Mark Alvin

You can select multiple columns just like this.


SELECT FirstName, LastName FROM Employees; FirstName LastName John Smith Mark Mayer Alvin Minsky

You can also use the WHERE keyword to only select those that meet the condition.
SELECT FirstName, LastName FROM Employees WHERE FirstName = 'John'; FirstName LastName John Smith

To Select Everything from the table, you can use the * character.
SELECT * FROM Employees EmployeeID FirstName 1 John 2 Mark 3 Alvin LastName Smith Mayer Minsky Age 21 23 27

You can arrange the result by using the ORDERBY keyword.


SELECT FirstName, LastName FROM Employees ORDERBY FirstName FirstName LastName Alvin Minsky John Smith Mark Mayer

If you want to arrange the records in descending order, you can use the DESC keyword.
SELECT FirstName, LastName FROM Employees ORDERBY FirstName DESC FirstName LastName Mark Mayer John Smith

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Alvin

Minsky

SQL alone, is a very big language. There is many more not discussed in this lesson. Now that you have learned the basics of SQL, we can now proceed to how we can access databases from our application.

Installing SQL Server 2008 Express


We will be using Microsoft SQL Server 2008 Express as our main data source. SQL Server is already installed if you have Visual C# Express or Visual Studio 2010, provided that you didn't uncheck the option of installing SQL Server during installation. We will also be using the SQL Management Studio Express which is a program that contains graphical tools for creating databases. Even if SQL is already installed via the installation of Visual C# Express, the SQL Management Studio might still not be installed. To check if it is already installed, go to Start > All Programs > Microsoft SQL Server 2008 and check if SQL Management Studio is there. If not, then you have to download and install it first. Don't worry though if you don't have SQL Management Studio as I will present two ways on creating and manipulating databases; using SQL Management Studio and using the simple command prompt. If you don't have SQL Server 2008 and SQL Management Studio, then you can download and install it manually. The following shows you step by step guide on how to do download and install them to your computer. First step is to download an all-in-one package containing Microsoft SQL Server 2008 and Microsoft SQL Server Management Studio using the following link. Download Microsoft SQL Server 2008 When you arrive at the download page, click the SQL Server 2008 R2 Express tab.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You will now choose which system you are currently using as described earlier. Choose the type of system you have (32-bit or 64-bit).

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You will be taken to another page. Choose your language desired using the drop down list and then click the download button.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Once you have downloaded the installer, execute it to begin installation. The following shows step by step instructions on how to install Microsoft SQL Server 2008 R2 Express Edition and the SQL Server Management Studio.

The installer will begin extracting required files for the installation. Wait for it to finish.

The SQL Server Installation Center will show up. Be sure the "Installation" is selected. Since we will be installation SQL Server, choose the first option.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Wait for the installation to start up.

In this window, read the License Terms and check the first check box to accept it. Click Next to proceed to the next step.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Wait again for the installer to load the required installation files.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The setup will check for your system for required components. If it sees a missing component, then you need to download and install them first. Click Next if no errors were detected.

This window allows you to select different features and the installation path for your SQL Server Express. Leave everything as is and click Next.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

This window asks for the name of the database instance that will be used by SQL Server Express. You can name it anything you want but it is recommended to leave it to its default name of SQLEXPRESS.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The following window might be automatically skipped during installation. It shows the disk space requirements needed by the program. Click Next.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

This window specifies the accounts that will have access to the database. Change the account name of the first row to NT AUTHORITY\SYSTEM and the second row to NT AUTHORITY\LOCAL and be sure that both has their Startup Type as Automatic.Click Next.

This window allows you to choose an authentication type. Choose Mixed Mode to allow both Windows Authentication and database authentication. You will also need to provide a password for the sa (System Administrator Account) which will have full credentials and control with the databases. Please make sure that you remember that password that you will type. You can also add more users to your database, but for this tutorial, we won't be needing that. Click Next.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

This window gives you an option to send error reports to Microsoft so they can fix it. It is up to you to check the option or you can simply ignore this and click Next.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The setup will now begin installing Microsoft SQL Server 2008 R2 Express. Wait for the installation progress to finish. Then click Next.

Congratulations, you have now successfully installed Microsoft SQL Server 2008 R2 Express. Click Close. Close the SQL Server Installation Center if it is still open.

Creating a Sample Database and Table


We will create a database containing a table with several records that we will use in the following lessons. This lesson presents two ways of creating a database and table. If you don't have SQL Management Studio installed, then we can use the command prompt and the sqlcmd Utility. You also need to use the SQL commands we have discussed. If you would like to use SQL Management studio instead, then you can skip to the next section.

Connecting to Microsoft SQL Server Using sqlcmd Utility


Let's start by opening command prompt. In Windows XP, click Start > Run and then type cmd. In Vista and Windows 7, open up start and type cmd in the search box. Press enter to open up command prompt.
Microsoft Windows [Version 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved. C:\Users\YourName>

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The command that will allow us to connect to SQL Server is the sqlcmd. This will execute the sqlcmd Utility which allows you to feed SQL commands to a connected server instance. There are also a lot of options you can specify when using this command. The following table enumerates the useful ones that we can use. Option Description -U The user login ID. If this is not specified SQL uses Windows Authentication mode. The user password. If -P is not specified and -U is specified, then sqlcmd will prompt -P you for the password. -S Specifies the name of the instance of a server that we will be connecting to. Figure 1 - sqlcmd Options If you followed the tutorial on how to install Microsof SQL Server 2008 Express, note that we specified a name for the server instance. We used SQLEXPRESS as the name of the instance. This is important to know when connecting to a database. We have also indicated a password for the sa account. We will be using that password to enter the server using the sa account. The following shows how to connect to the SQLEXPRESS server using the sa account.
C:\Users\YourName>sqlcmd -S .\SQLEXPRESS -U sa -P mypassword

We used the -S option to specify that we will use the SQLEXPRESS server instance. When specifying server instances, we also need to specify the computer name, or the ip address of where the actual server containing the server instance resides. If you don't know a lot of networking and the concept of ip addresses, then we can connect to the SQLEXPRESS instance located in your own computer using the name of your machine, or by simply typing a dot. It is then followed by a backslash and then the name of the server instance. We also indicated the username and password using the -U and -P options. We used the sa account and the password that we have provided when we installed SQL server. Alternatively, if you can't remember the password, simply omit the -U and -P options and the sqlcmd will use Windows Authentication. You may recieve some issues regarding limited persmissions if you are not logged in with a windows administrator account.
C:\Users\YourName>sqlcmd -S .\SQLEXPRESS

This will use the credentials of the currently logged in windows user. Logging in as sa gives you full control with the database. In a real world scenario, you will have to create multiple accounts with limited privelages to prevent malicious users from compromising the contents of the database. After you have typed the command, press enter and if everything went well, you can see a prompt waiting for you to type an SQL command.
C:\Users\YourName>sqlcmd -S .\SQLEXPRESS 1>

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Creating a Database Using sqlcmd Utility


We will be creating a database named University which will be consisting of the Students table. To create the database, type the SQL command shown below.
1> CREATE DATABASE University

If you press enter, nothing will happen, and sqlcmd will wait for another line of SQL command to be typed. To execute the command we need to type GO and press enter.
1> CREATE DATABASE University 2> GO

You need to wait for a few seconds for the command to take effect. If everything is successful, no error messages will show up and the prompt will reset back to 1.
1> CREATE DATABASE University 2> GO 1>

Creating a Table Using sqlcmd Utility


We will now create the Students table which will contain the details about several students in the university. First, we need to ensure that the database we are using is the University database that we recently created. Type the following commands.
1> USE University 2> GO

Press enter to change the database that we are currently working to the University database. Also, a message will show up that will confirm the change. Let us now create the Students table. Type the following SQL commands.
1> CREATE TABLE Students 2> ( 3> StudentID int identity primary key, 4> FirstName varchar(50), 5> LastName varchar(50), 6> Gender varchar(10), 7> Age int, 8> Address varchar(50) 9> ) 10> GO 1>

The created table has 6 columns. The first one is the StudentID which we declared as the primary key and an identity column and having a type of int. We also declared FirstName, LastName,

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Gender, Age, and Address with their appropriate SQL data types. Excuting this command creates our new table.

Adding Records Using sqlcmd Utility


Now that we created our table, let's add several rows or records of students. The following table shows some fictional student data that we will add in our table. StudentID FirstName LastName Gender Age Address 1 Edward Lyons Male 17 Spencer Street 2 Jimmie Vargas Male 18 Blue Bay Avenue 3 Monica Ward Female 16 Mapple Street 4 Joann Jordan Female 17 Spencer Street 5 Cheryl Swanson Female 17 Wacky Street 6 Clara Webb Female 18 Spooner Street 7 8 9 10 Zack Randall Jessica Oscar Norris May Cole Manning Male 19 Blue Bay Avenue

Male 18 Golden Street Female 17 Mapple Street Male 18 Mapple Street

Figure 2 - Records of Students Table Now that we have 10 records, let's now add them to the Students table using SQL commands.
1> INSERT INTO Students (FirstName, LastName, Gender, Age, Address) VALUES 2> ('Edward', 'Lyons', 'Male', 17, 'Spencer Street'), 3> ('Jimmie', 'Vargas', 'Male', 18, 'Blue Bay Avenue'), 4> ('Monica', 'Ward', 'Female', 16, 'Mapple Street'), 5> ('Joann', 'Jordan', 'Female', 17, 'Spencer Street'), 6> ('Cheryl', 'Swanson', 'Female', 17, 'Wacky Street'), 7> ('Clara', 'Webb', 'Female', 18, 'Spooner Street'), 8> ('Zack', 'Norris', 'Male', 19, 'Blue Bay Avenue'), 9> ('Randall', 'May', 'Male', 18, 'Golden Street'), 10> ('Jessica', 'Cole', 'Female', 17, 'Mapple Street'), 11> ('Oscar', 'Manning', 'Male', 18, 'Mapple Street') 12> GO

We used a modified version of INSERT INTO Statement which allows inserting of multiple records at once. Each record is enclosed with parentheses and the records are separated with commas. After executing these SQL commands, your Students table should now be filled with 10 records. If everything went fine, a message will show up telling the number of rows affected. You can now skip the following section and proceed to the next lesson.

Querying Records With sqlcmd Utility

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

To perform a simple query in the sqlcmd Utility, you can use a simple SELECT statement.
1> SELECT FirstName, LastName FROM Students 2> GO FirstName LastName ------------------------- ------------------------Edward Lyons Jimmie Monica Joann Cheryl Clara Zack Randall Jessica Oscar (10 rows affected) 1> Vargas Ward Jordan Swanson Webb Norris May Cole Manning

Connecting to a Server Using SQL Server Management Studio


In this part of the lesson we will do the exact same thing done in the previous section using the SQL Server Management Studio. If you have already done the previous section, then you should skip this part. Using SQL Server Management Studio is easier and you won't have to make use of SQL commands. SQL Server Managament Studio offers tools that would be helpful to you. Open SQL Server Management Studio by going to Start > All Programs > Microsoft SQL Server 2008 or Microsoft SQL Server 2008 R2. Once executed wait for the program to initialize some settings.

After that, the splash screen will show up while the program is loading.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You will then be prompted to choose the server name, the type of the authentication, and the login and password details. Leave the Server type as is. If you followed the tutorial on how to install Microsof SQL Server 2008 Express, note that we specified a name for the server instance. We used SQLEXPRESS as the name of the instance. This is important to know when connecting to a database. We will be using that name in the Server name field. Note that it is preceded by a dot and backslash which simply means the SQLEXPRESS server instance located in your own machine. You can change the dot to, for example, an ip address of a remote server where the server instance is located. You can choose Windows Authentication as the Authentication to use the credentials of your windows account. You may need to be logged in as the administrator of your computer. Choosing SQL Server Authentication allows you to log in using a SQL Server account. We can log in using the sa account, in which the password is what we have indicated when we installed Microsoft SQL Server. The Remember password checkbox remembers your password so you wont have to type it again when you open SQL Server 2008. Click Connect to connect to SQLEXPRESS server.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You are now connected to the SQLEXPRESS server.

Creating a Database with SQL Server Management Studio


To the left of the interface is the Object Explorer which contains pretty much everything inside the server such as databases, tables, stored procedures, users, and many more. You can open up the Database folder to show databases that are already installed in your server. (You may not see any databases yet if this is your first time creating a database). To create a database, right click the Database folder and choose New Database.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The New Database Window will show up.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We will be creating a database named University which will contain a table with records of students. Type the name of the database which is University in the Database name field. You can leave the owner to default. The Database files section allows you to customize the location where the database files (the files that contain the actual database) will be located in your disk. You can also leave it to default as you will need enough permissions to change the location of the database files. Two database files will be created, a .mdf file which contains the database itself, and a .ldf file which contains logging information and transactions made to the database. Also make sure to change the Initial sizes to 3 MB and 2MB respectively so the files can acccomodate the contents of the database. Press OK to create the database. Your created database should now appear inside the Database node of the Object Explorer.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Creating a Table in SQL Server Management Studio


Creating a table is as simple as creating a database. In the Database node, find your created University database and expand it. Find the tables node and right click. Choose the New Table option.

The SQL Server's Table Designer will show up (Center) together with the Properties Window(Right) and the Column Properties Window Bottom.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can type the columns and their corresponding type in the Table Designer. The Properties window allows you to change certain properties of the table. The Column Properties window allows you to change certain properties of a column. In the Table Designer, type the following fields and their corresponding datatype.

Allow Nulls simply means that a column can be left blank for a single record. A good practice when designing tables is to uncheck this for a column that should always be required to have values. But for now, we are more concerned on creating a sample table that we can use in the following lessons. We should now set the primary key. The StudentID is the best candidate for a primary key and no two records should have the same StudentID. Select a particular column by clicking the blank

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

square to the left of the column's name then find in the toolbar the key icon which sets the selected column as the primary key.

The StudentID column will now have a key icon to its left to indicate that it is now the primary key. Also note that the its Allow Nulls check box was unchecked because primary keys should always have values.

We can also create the StudentID as the identity column. To do that, select the StudentID column and go to the Properties window. Find IdentityColumn and choose StudentID.

Save the table by pressing Ctrl + S. You will then be prompted for the name of the table. Name it Students and press OK to create our table with the name Students inside the University database.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You created table will appear in the Object Explorer inside the Tables node of the University database.

Adding Records to a Table Using SQL Server Management Studio


We will now add some records in the Students ttable that we created. To add records, right click the Student table in the Object Explorer and choose Edit Top 200 Rows.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

A new window will show up that allows you to add records simply by typing each value to each field. The records that we will add is shown in Figure 2. Type each column data for every row. Note that StudentID is an identity column so you wont be able to type on it as SQL Server will auto generate a value for it.

Viewing Records in SQL Server Management Studio


To View the records you create using SQL Server Management Studio, you can use the New Query command located in the toolbar.

The SQL Editor will show up. Type the following command.
SELECT FirstName, LastName FROM Students;

If you read the first section of this tutorial, note that we used semicolon instead of the word GO. To Execute the SQL command, click the Execute button in the toolbar (The one with red exclamation point).

The query will then be executed and the results will be presented to you.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Close SQL Server Managment Studio. We are now ready to create an application that will connect to the University database, and query or modify the contents of the Students table.

Connecting to a Database with Visual Studio Tools


Before we delve into the data-driven world of ADO.NET, let's first take a look at some tools available in the Visual Studio products. The following example shows you one way of connecting to a database without writing any code.

Creating a Connection to a Database


Open Visual C# Express and create a new Windows Forms Application. Name the project as DatabaseConnection. In Visual Studio, the Database Explorer is called Server Explorer. It is opened by default in Visual C# Express located in the left as a tab.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

If you can't find the Database Explorer, go to View > Other Windows > Database Explorer to open it up. Click the Connect to Database icon in the Database/Server Explorer.

Clicking it shows up the Add Connection Window.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Be sure that the Data source uses Microsoft SQL Server Database File. If not, you can click the Change button and choose the appropriate data source. We also need to provide the file name of the database file that was created when we create our database. Click Browse to show up the open dialog. By default, the database files of SQL Server Express is located in C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data. Paste this path in the url bar of the Open dialog to immediately go to that directory. Find the University.mdf file and select it. Click Open. If an error shows up tellng that file is used by another program. Open up the Services program by clicking Start and typing the word services in the search box. Find the SQL Server (SQLEXPRESS) service and right click on it. Choose Restart to restart the service.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

After it is restarted, we can now go back to choosing the University.mdf file. After pressing open, click the Test Connection button in the Add Connection Window to test if our application can successfully connect to the database. If nothing is wrong, then a success message will show up.

Press OK to close the message. You can also choose the Authentication mode to be used. You can ues Windows Authentication or SQL Server Authentication. You must provide the username and password if you are to use SQL Server Authentication mode. Press OK to close the Add Connection Window and add the database file to the Database Explorer window.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Database Explorer allows you to see the contents of a database. If you expand a database file such as the University.mdf, you can see parts of it such as its tables and stored procedures. Expanding the Tables node shows our Students table and expanding the table shows its columns.

Creating a DataSet
A DataSet can be considered as a mini database located in the computer's memory. It's main purpose is to obtain the data received from the database and store it in different tables just like how a database stores its records. The next step is to create a DataSet that will contain the contents the database that we have connected to. We will be using the Data Sources Window. If you can't see it, then go to Data > Show Data Sources. It will be located to the left of the IDE by default.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Click the Add New Data Source button to open up the Data Source Configuration Wizard.

Choose Database and click Next.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Choose Dataset then click Next.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

In the combo box, be sure to select University.mdf that we have connected using the Database Explorer. Click Next.

You will then be prompted that the database file needs to be coppied to the project's directory. Clicking yes will copy it to the project's directory. You can confirm that the database has been coppied by looking at the Solution Explorer and finding University.mdf.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

This window simply saves the connection string used to connect to the University database. Connection strings will be discussed in a later lesson. For now, you can leave the defaults and click Next.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Wait for the Wizard to load the contents of the database. You will then be asked which parts of the database you want to be included in the DataSet. Since we will only be needing the tables, simply check the Tables. The DataSet name specifies the name of the DataSet to be created. Click finish to create the DataSet.

You can now see the created DataSet in the Data Sources Window. Expanding it shows the tables contained in the data set. Expanding a table shows its fields or columns. Visual Studio also generated 4 files grouped as one which is used to created the DataSet. You can see them in the

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Solution Explorer. They contain all the codes that creates our DataSet. You don't have to look at them for now.

Showing Table Data Via Drag and Drop


Now is the most exciting part. With our DataSet available in the Data Sources Window, we can simply drag a table to the form. You can also drag each column to a form but for now, we will drag a whole table to the form.

After dragging the table into the form, Visual Studio will automatically create a DataGridView control. The DataGridView allows you to view different kinds of data that can be represented in a table. An example is a database table or a multidimensional array of values. You can see that each column of the Students table was automatically placed in the DataGridView (try to resize the form and the DataGridView to see all the columns). You can also use the Dock property of the DataGridView and set it to Fill so the DataGridView will take up all the space of the form's client area. You will a toolbar on the top of the form. It is called the BindingNavigator control and Visual Studio also created this to allow you to move through records, update a record, delete an old record, and add a new record. If you also look at the component try below, more components have been automatically created for you by Visual Studio. We won't be discussing each of them for now because there are lot's of concepts to learn first. But if you are to create everything manually, then it can take us a lot of time to create what we have accomplished in this lesson. Run the application and you will see that all the records are displayed in the DataGridView. You can use the BindingSourceNavigator control to modify the contents of the database.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

You can use the navigation buttons to move from 1 record to another. The plus icon allows you to add new records. Don't worry if the StudentID that will be assigned for the new record is a negative number, it will be fixed by clicking the Save button which should be done to save the changes to the database. You can modify each field of a record by double clicking it. You can also delete a selected record by clicking the red X icon in the BindingNavigator control. Again, press the Save button after you have made a change to send the changes to the database. Note that running your program copies the database from the root project folder to the Release or Debug folder so everytime you run your program, you will be working with a fresh copy of the database. It means any modification to the database you make will be overwritten and discarded the next time you run your application. This is good when you are just developing the application. If you don't want this behavior, select the database file (University.mdf) in the Solution Explorer and in the find the Copy To Output Directory option in the Properties Window. Change its value to Copy if newer. The database file in the project's root directory will now only be coppied if it a newer version of the one that already exists in the output directory.

Connection Strings
A connection string is a series of name/value pairs seperated by semicolon that indicate the settings for connecting to a database. Such settings include, the location of the database, authentication, security, and the name of the database to connect to. Connection strings for different data sources are not exactly the same. For example, OLE DB and ODBC requires an OLE DB and ODBC driver to be specified in their connection strings. The Connection classes of the data providers provides a ConnectionString property that you can use to specify the connection string for connecting to a database. Here is an example of a connection string for connecting to a SQL Server Expres data source:

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Data Source=.\SQLEXPRESS;Initial Catalog=University; Integrated Security=SSPI;

Figure 1 - A connection string example For a list of connection strings for different providers, you can go to the following site: http://connectionstrings.com The following table are the basic connection string parameters that you can use when building your connection string. Note that not all parameters are the same for every data source. Description Used only if you want to connect to an attachable database file (for AttachDBFileName / Initial example, an .mdf file that isn't registered with the database File Name system). Full version of SQL Server doesn't support this. The length of time (in seconds) to wait for a connection to the Connect Timeout / server before terminating the attempt and generating an error. Connection Timeout Defaults to 15 seconds, and 0 seconds represents an infinite wait. ; Data Source / Server / The server name or network address of the database product to Address / Addr / Network connect to. Use localhost for the current computer. Address Initial Catalog / Database The database the the connection will initially use. Defaults to false. When set to true or SSPI, the .NET provider Integrated Security / attempts to connect to the data source using Windows integrated Trusted_Connection security. When set to false (the default), security-sensitive information such as the password is removed from the ConnectionString property as Persist Security Info soon as the connection is opened. Thus, you can't retrieve this information in your code. User ID The database account user ID. Password/Pwd The password corresponding to the User ID. Figure 2 - Connection String Parameters The example that we will show here are connection strings for connecting to an SQL Server data source. You can proceed to the website using the link above if you are finding the connection strings for other data sources such as Access. When building connection strings, you need to specify the data source or the server to be used. This can be done using the Data Source or the Server parameters. The connection string shown below is used for connecting to an SQL Express data source.
Data Source=.\SQLEXPRESS;Initial Catalog=University;Integrated Security=SSPI;

Parameter

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

As specified by the Data Source parameter, ".\SQLEXPRESS", we are connecting to a server instance named SQLEXPRESS that lies within the current computer(localhost). Alternatively, you can use the word localhost instead so this is equivalent: "localhost\SQLEXPRESS". You can also specify the server or the computer name as the data source followed by the server instance. For example, suppose that the server we are connecting to is named MyServer and we want to connect to the SQLEXPRESS server instance, then the following connection string can be used.
Data Source=MyServer\SQLEXPRESS;Initial Catalog=University; Integrated Security=SSPI;

You can also use the Server parameter instead of the Data Source which does the same thing.
"Server=.\SQLEXPRESS;Initial Catalog=University; Integrated Security=SSPI"

We also need to specify the initial database to be used. The Initial Catalog or Database parameter indicates the initial database to use. You can change the database during runtime by calling the DbConnection.ChangeDatabase method or executing the SQL command "USE DATABASE <Database Name>" where <Database Name> is the name of the database that will replace the current database. Later lessons will show how to execute non-query SQL commands such as CREATE, UPDATE, and DELETE. Alternatively, you can use the Database parameter instead.
Data Source=.\SQLEXPRESS;Database=University;Integrated Security=SSPI;

The connection string also requires authentication and security information. Integrated Security was set to SSPI (Security Support Provider Interface) signifying the we will be using the credentials of the current windows user.
Data Source=.\SQLEXPRESS;Initial Catalog=University; Integrated Security=SSPI;

Alternatively, you can use the Trusted_Connection parameter instead and set it to True.
Data Source=.\SQLEXPRESS;Initial Catalog=University; Trusted_Connection=True;

You can change this to a specific database user by replacing Integrated Security with the User Id and Password parameters.
Data Source=.\SQLEXPRESS;Initial Catalog=University; User Id=database_user;Password=the_password;

When using Sql Server Express, we can also attach a database file on a local SQL server instance. We can use the AttachDbFilename to do just that.
Data Source=.\SQLEXPRESS;AttachDbFileName=C:\Data\University.mdf; Database=University; Trusted_Connection=True;

We specified the path of the database file that we will use. If a Data Directory is defined, then you can use the |DataDirectory| instead.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Data Source=.\SQLEXPRESS;AttachDbFileName=|DataDirectory|University.mdf; Database=University; Trusted_Connection=True;

ConnectionStringBuilder
.NET also provides the ConnectionStringBuilder class for each of the data providers. ConnectionStringBuilder classes inherit from the DbConnectionStringBuilder base class. The following shows the different flavors of the ConnectionStringBuilder class. Provider ConnectionStringBuilder Class SQL Server SqlConnectionStringBuilder OLE DB OleDbConnectionStringBuilder ODBC OdbcConnectionStringBuilder Figure 3 - ConnectionStringBuilder Classes We will use SQL Server provider as our example. We can use the SqlConnectionStringBuilder class to create SQL Server connection strings.
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(); builder.DataSource = @".\SQLEXPRESS"; builder.IntegratedSecurity = true; builder.InitialCatalog = "Northwind";

ConnectionStringBuilder contains properties which corresponds to the different parameters of a connection string. Each flavor of the ConnectionStringBuilder has different sets of properties because connection strings for different data sources are different. You can then access the connection string built by the ConnectionStringBuilder using the ConnectionString property.
string connectionString = builder.ConnectionString;

There are more advanced parameters that you can use when building connection strings. Only the basic ones were introduced here to give you an essential knowledge for building connection strings.

Data Providers
A data provider is a set of classes the manages and handles the connection to a data source such as SQL Server. The .NET Framework provides you with different data providers not just for SQL Server. For example, you can use the OLE DB and ODBC data providers to connect to other data sources such as Microsoft Access, MySql or even Oracle. The following are some of the data providers provided by .NET. There are currently three data providers supported by .NET. Provider
COMPILED BY:

Description
Bsc ABDULRAHIM ALI ATHUMAN

Provider Sql Server OLE DB Provider ODBC Provider

Description Provides access to a SQL Server database. Provides access to any data source that has an OLE DB driver such as MySQL, Provides access to any data source that has an ODBC driver.

Please note that another provider, Oracle Provider, has been considered deprecated since Microsoft recommends the use of ODP.NET instead. More data providers are offered by third party companies. Each data provider provides different classes that you can use to access your database. For example, the data provider for SQL Server consists of classes such as SqlConnection, SqlCommand, SqlDataReader, and SqlDataAdapter. The data provider for OLE DB consists of classes such as OleDbConnection, OleDbCommand, OleDbDataReader, and OleDbDataAdapter. The classes for the different providers inherit from a common set of classes and implement a common set of interfaces to provide consistent functionality regardless of the provider. Data Provider Sql Server OLE DB ODBC Components Connection SqlConnection OleDbConnection OdbcConnection Command SqlCommand OleDbCommand OdbcConnection DataReader SqlDataReader OleDbDataReader OdbcDataReader DataAdapter SqlDataAdapter OleDbDataAdapter OleDbDataAdapter Each data provider is located in its own namespace. For example, the Sql Provider is found inside System.Data.SqlClient and the OLE DB provider is found inside System.Data.OleDb. Data Provider Namespace Sql Server System.Data.SqlClient OLE DB System.Data.OleDb ODBC System.Data.Odbc The classes inside these namespaces implements a common interface. Consider the SqlConnection and OleDbConnection for example. They both implement the interface IDbConnection. If you look at this interface, you will see the common properties and methods of the Connection classes for all data providers. Note that the following lessons are mostly concepts and presents little code examples. This is OK as we will discuss how to use them in a working application after we have tackled this classes. You don't have to memorize each of them. In fact, you can skip the section and proceed to creating an ADO.NET application. You can then go back here whenever these classes are encountered on those lessons.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The Connection Class


Each data provider in ADO.NET contains a Connection class that inherits from the System.Data.Common.DbConnection class. The DbConnection serves as the base class for all the Connection classes of different data providers. The following are the Connection classes for each data provider. Data Provider Connection Class SQL Server SqlConnection OLE DB OleDbConnection ODBC OdbcConnection Figure 1 - Connection Classes The DbConnection class implements the IDbConnection interface which contains methods and properties that is used to define a connection and to open a connection to a data source. Openning a connection consumes resources of the computer so you need to close it as soon as possible. For you to open a connection, you must specify a Connection String to indicate the location, type and other configurations for connecting to a database source. The following are the methods and properties of the IDbConnection interface that are common to all Connection classes. Property ConnectionString Description Specifies the connection string to be used by the connection. Specifies the time to wait for the connection to be established before ConnectionTimeout declaring that the connection has timed out. Database Specifies the database that the connection is currently working on. State Specifies the current state of the connection. Figure 2 - IDbConnection Properties Method Description BeginTransaction Begins a database transaction. ChangeDatabase Changes the database the connection is currenly working on. Close Closes the connection. CreateCommand Creates and returns a command object associated with the connection. Open Opens the connection. Figure 3 - IDbConnection Methods

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Note that each Connection class of every data provider can have more properties and methods listed below which are unique to them. Let's use the SQL Server as the data provider for the following examples. It means that we will be using the SqlConnection class which is the Connection class of SQL Server data provider. To create a Connection object, simply use its parameterless constructor.
SqlConnection connection = new SqlConnection();

We need to specify the proper connection string for the connection. To assign a connection string to the Connection object, you can use the ConnectionString property.
connection.ConnectionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=University;" + "Integrated Security=SSPI";

Alternatively, you can use the overloaded constructor of the SqlConnection class when creating an instance of it.
SqlConnection connection = new SqlConnection(@"Data Source=.\SQLEXPRESS;" + "Initial Catalog=University;Integrated Security=SSPI");

The connection string above specifies a connection to an SQL Server database using the University as the initial database with Window Authentication. The ConnectionString property is set only when the connection is closed. The Connection class offers a number of properties that access the different components of the connection string. The Database property specifies the database to use. The initial database is indicated by the Initial Catalog parameter of the ConnectionString. To change the database to use, you can call the ChangeDatabase method as shown in the following code.
connection.ChangeDatabase("AnotherDatabase");

The code changes our database from University(specified in the connection string) to AnotherDatabase, provided that the AnotherDatabase database exists. The ConnectionTimeout property gets the value of the Connection Timeout parameter of the connection string. If it is not specified, it has a default value of 15. The Connection Timeout specifies how long the connection has to wait before it throws an exception indicating that a connection has timed out. To open a connection, we use the Open method. Be sure you have set the details needed in the connection string before calling this method. After you have used the database, you can use the Close method. Note that you can use the using keyword to automatically close the connection. This is shown below.
using (SqlConnection connection = new SqlConnection()) {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

// some code.... connection.Open(); // some code.... }

We put the declaration and initialization between the parentheses of the using statement. This means the the object created between these parentheses is only usable inside the block of the using statement. Once the closing blocked is reach, the Connection object is disposed automatically closing the connection. If you are using the Close method, be sure to always put it in the finally block like this.
try { connection.Open(); } catch(SqlException) { } finally { connection.Close(); }

This is because, if you put it inside the try block, and an exception was thrown, then the statement that calls the Close method might not be reached leaving the connection open. If it is in the finally block, then the Close method will always be called. You can use the State property to know the current state of a connection, whether it is close or open. The State property accepts a value from the System.Data.ConnectionStateEnumeration. The following are the values of the ConnectionState enumeration. Value Description Broken States that the connection is broken. Closed States that the conneciton is closed. Connecting States that the connection is currently connecting to a data source. Executing States that the connection is executing a command. Fetching States that the connection is retrieving data. Open States that the connection is open. Figure 4 - System.Data.ConnectionState Enumeration Values The Connection class offers two events that you can use. The first one is the InfoMessage event which is used to get specific information messages. The StateChange event is triggered when the connection state is changed.
static void con_StateChange(object sender, System.Data.StateChangeEventArgs e) { Console.WriteLine("State has been changed from {0} to {1}.",

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

e.OriginalState.ToString(), e.CurrentState.ToString()); } static void Main() { SqlConnection con = new SqlConnection(); con.ConnectionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=University;" + "Integrated Security=SSPI"; con.StateChange += new System.Data.StateChangeEventHandler(con_StateChange); con.Open(); // Opens a connection con.Close(); // Closes a connection } State has been changed from Closed to Open. State has been changed from Open to Closed.

When we called the Open() method, the connection's state was changed from Close to Open, triggering the event handler that is attached to the StateChange event. The event handler prints a message that shows the OriginalState and CurrentState. When we called the Close() method, the connection state was changed from Open to Closed also trigerring the StateChange event.

The Command Class


Each data provider has their Command class which is use to execute SQL commands or stored procedures to the database. Each Command class inherits from the System.Data.Common.DbCommand base class. The following are the different flavors of the Command class for each data provider. Data Provider Command Class Sql Server SqlCommand OLE DB OleDbCommand ODBC OdbcCommand Figure 1 - Command Classes DbCommand implements the IDbCommand interface which exposes some properties and methods as shown in the following tables. Property CommandText Description Specifies the SQL command or stored procedure or a name of a table. Specifies the time required to wait for the completion of a command before it CommandTimeout throws an exception. The default is 30 seconds. Accepts a value from the System.Data.CommandType enumeration that will determine the type of command specified in the CommandText property. It CommandType has 3 values, Text, for accepting SQL commands, StoredProcedure for stored procedures, and TableDirect to get all the rows and columns of one or

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Property

Connection Parameters

Description multiple tables. Note that by default, Text will be used. Specifies the connection that the command is associated to. The Command class must be hooked to an open connection which is the connection where the command is to be executed. A collection of Parameter defined in the CommandText.

FIgure 2 - IDbCommand Properties Property Cancel Description Tries to cancel the command being executed. Creates a new Parameter object that can be added to Command.Parameters CreateParameter collection. Executes the command and returns a forward-only read-only cursor in the ExecuteReader form of a DataReader. Executes the command and returns the number of rows that were affected. ExecuteNonQuery Often used with record UPDATE, DELETE, or INSERT statements. Executes the command, and retrieves a single value. Used with aggregate ExecuteScalar functions and in cases where you want to return the first column of the first row of a result set. Figure 3 - IDbCommand Methods We wll use the SQL Server provider's SqlCommand class for the following examples. To create a Command object, you can simply use it's parameterless constructor.
SqlCommand command = new SqlCommand();

A command is useless without specifying the CommandText which contains an SQL statement that the command will execute.
command.CommandText = "SELECT * FROM Students";

Alternatively, you can immediately specify the command text when creating the Command object using an overloaded constructor of SqlCommand.
SqlCommand command = new SqlCommand("SELECT * FROM Students");

Another required thing that the Command object should have is the Connection object where the command will be executed to. When you have created a Connection(for example, an SqlConnection object), then you can assign its instance to the Connection property of the IDbCommand.
SqlConnection connection = new SqlConnection(); SqlCommand command = new SqlCommand();

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

command.Connection = connection;

An overloaded version of the constructor allows you to specify the command text and the connection to be used by the command.
SqlCommand command = new SqlCommand("SELECT * FROM Students", connection);

The DbConnection class also offers a CreateCommand() method which returns a DbCommand with the connection already hooked to it. You can then use the CommandText property to specify the command.
SqlCommand command = connection.CreateCommand(); command.CommandText = "SELECT * FROM Students";

To execute commands, you first need an open connection. For reading the contents of a database, you can use the ExecuteReader() method which reaturns a DataReader object that can be used to step through each row of a database table. For updating, inserting, deleting, and any non-query commands, you can use the ExecuteNonQuery() method. These methods will be seen in action in a later lesson. Other properties and methods of the Command classes are reserved for later lessons. But for now, the ones introduced here are enough to execute basic SQL statements.

The DataReader Class


A DataReader object allows forward-only, read-only access to a database. Using DataReader is the connected way of accessing data and an open connection must be available first. Each provider has its own version of DataReader which inherits to the System.Data.Common.DbDataReader base class. Provider DataReader class SQL Server SqlDataReader OLE DB OleDbDataReader ODBC OdbcDataReader Figure 1 - DataReader Classes The DbDataReader class contains properties and methods used for reading a row in a database table. Some of this are presented in the following tables. Property FieldCount HasRows IsClosed Description Specifies the number of columns of the current row or record. Specifies whether the current row has at least 1 row. Specifies whether the DbDataReader is closed.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Property Description RecordsAffected Specifies the number of rows that has been updated, inserted, or deleted. Figure 2 - DbDataReader Properties Method Description GetBoolean Gets the value of a column as a boolean value. GetChar Gets the value of a column as a char value. GetDataTypeName Gets the name of the data type of the current column. GetDateTime Gets the value of the column as a DateTime object. GetDecimal Gets the value of the column as a decimal value. GetDouble Gets the value of the column as a double value. GetFieldType Gets the field type of the specified column. GetInt32 Gets the value of the column as a int value. GetName Gets the name of the column. GetOrdinal Gets the column ordinal with the specified column name. GetString Gets the value of the column as a string value. GetValue Gets the value of a column as an object. GetValues Gets all the column of a row as an array of objects. Advances the reader to the next result when reading the NextResult results of a batch of statements. Read Advances the reader to the next record. Figure 3 - DbDataReader Methods The DataReader only loads a single row in the memory at a time to ensure the minimum use of memory. DataReader can only be used when a connection is open, so you need to open a conenction first and as soon as you are over using it, then you must close the connection. A corresponding command assigned with an SQL SELECT statement should call the ExecuteReader() method to create an instance of DbDataReader object. Again, we will use SQL Server provider for the following examples. (Suppose that a connection was already declared).
SqlCommand command = new SqlCommand("SELECT * FROM Students", connection); SqlDataReader reader; connection.Open(); reader = command.ExecuteReader();

You can see that we first need an Open connection before using the ExecuteReader() method. We did this using the DbConnection.Open() method. An overloaded version of the ExecuteReader() method also exists that accepts a value from the System.Data.CommandBehavior enumeration. Here are some of its values you can use.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Value CloseConnection Default SingleResult SingleRow

Description Immediately closes the connection when the Close method of the DataReader is called. The default behavior of the DataReader. The query returns a single result set. The query is expected to return only a single row.

Figure 4 - System.Data.CommandBehavior Enumeration Values For example, if you want the reader to only read a single row, then you should past the SingleRow value to the ExecutReader() method.
reader = command.ExecuteReader(CommandBehavior.SingleRow);

You can also combine command behaviors using the bitwise OR operator.
reader = command.ExecuteReader(CommandBehavior.SingleRow | CommandBehavior.CloseConnection);

Once the ExecuteReader() was executed and an instance of DbDataReader was placed in a variable, we can now iterate through each record of the result set that was returned by by SELECT statement. The following shows you how to obtain the value of each field of every row.
while (reader.Read()) { MessageBox.Show(reader["FirstName"].ToString()); }

We used a for loop and inside its condition, we used the Read() method of the DataReader to read the first row of the result set that was returned by the query. If a row was successfully read, the method will return true and continue the loop. Once that method is executed, we can used an indexer for the DataReader object and pass the name of the column. This will return the result as an object so we need to convert it first to its proper data type. After the body of the loop is executed, the Read() method is executed once again to read the next row. If there the row previously read is the last row and no other rows left to be read, then the Read() method will return false and stop the loop. Alternatively, you can use the Get methods of the DataReader which accepts the column index of the value to be retrieved. For example, suppose we want to retrieve the StudentId which is a number, then you can use the following code.
int studentID = reader.GetInt32(0);

This will return the value of the first column (index 0) as a value of type int. After using the DataReader, you need to close the DataReader and the Connection to release the resources that was used and to make the connection availabe.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

reader.Close(); connection.Close();

We will use the DataReader classes to read the contents of a database in a connected fashion and it will be demonstrated in a later lesson.

The DataAdapter Class


A DataAdapter can be considered as a bridge between the actual data source to your application. It is commonly used together with a DataSet. Using DataAdapter and DataSet is the disconnected way of retrieving data from the data source. It means, you don't need an open connection for them to work. A DataAdapter allows you to fill a DataSet with values from the data source, or execute different commands to the data source.A DataAdapter class inherits from the System.Data.Common.DbDataAdapter base class. Each data provider has its own version of DataAdapter. Provider DataAdapter Class SQL Server SqlDataAdapter OLE DB OleDbDataAdapter ODBC OdbcDataAdapter Figure 1 - DataAdapter Classes The DbDataAdapter class provides the following properties and methods. Description Speicfies the Command object with the SQL command to be used for DeleteCommand deleting a record. FillCommandBehavior Specifies the behavior of the command used to fill the data adapter. Specifies the Command object with the SQL command yused for InsertCommand inserting a record. Specifies the Command object with the SQL command to be used for SelectCommand inserting a record. UpdateBatchSize Specifies the number of commands that can be executed as a batch. Specifies the Command object with the SQL command to be used for UpdateCommand inserting a record. Figure 2 - DbDataAdapter Properties Method AddToBatch ClearBatch ExecuteBatch
COMPILED BY:

Property

Description Adds a Command object to a batch that will be executed. Removes all the Command objects from the batch. Excutes the batch of commands.
Bsc ABDULRAHIM ALI ATHUMAN

Description Fill Executes the SelectCommand property and fills a DataSet that is provided. InitializeBatching Initialize the batching process. GetFillParameters Gets the paremeters of the SelectCommand property. TerminateBatching Terminates the batching process. Calls the corresponding INSERT, DELETE, or UPDATE command of this Update DataAdapter and updates the data source using the specified commands. Figure 3 - DbDataAdapter Methods We will use the SQL Server provider for the folowing examples. To create a DataAdapter, you can use its parameterless constructor.
SqlDataAdapter adapter = new SqlDataAdapter();

Method

The DataAdapter is the one that actually executes the commands to data source. It has a SelectCommand property which accepts a DbCommand object that specifies the SELECT statement used to retrieved data from the data source. The following shows you an example of assigning a SelectCommand.
SqlCommand selectCommand = new SqlCommand("SELECT * FROM Students", connection); SqlDataAdapter adapter = new SqlDataAdapter(); adapter.SelectCommand = selectCommand;

To execute the command specified by the SelectCommand property, we can use the Fill() method of the DbDataAdapter class. The Fill() method requires an instance of the DataSet or DataTable classes. The following shows an example of filling a DataTable instance with values retrieved from the database.
DataTable myTable = new DataTable("TableName"); adapter.Fill(myTable);

This will execute the command indicated in the SelectCommand property and the results of the query will be stored in the DataTable. The following is another form of the Fill command which accepts a DataSet and the name of the DataTable to be created.
DataSet myDataSet = new DataSet(); adapter.Fill(myDataSet, "TableName");

After execution of the above command, a new DataTable with the name TableName will be added to the Tables property oft the DataSet. You can then access the data using the Rows property of the DataTable.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The DbDataAdapter also allows you to specify commands for its UpdateCommand, InsertCommand, and DeleteCommand properties. Note that these commands will be autogenerated by a CommandBuilder as we will see in a separate lesson. You can then use the Update() method of the DbDataAdapter which executes these commands depending on the modification to the DataSet. You will see how to update, insert, and delete records using the Update() method in an upcoming lesson.

The DataSet Class


The System.Data.DataSet class holds data that are retrieved from the database. The DataSet class allows you to hold disconnected data. It means, you can work with the contents of the database while disconnected to the actual database. This is because, the contents that you will be working on already exists inside the DataSet. You can consider the DataSet class as a mini database management system inside the memory. The DataSet class has a Tables property which is a collection of System.Data.DataTable objects. A typical database can contain multiple tables. Just like a database, a DataSet can contain multiple tables as well. Records retrieved from the actual database are stored as a DataTable and added to the Tables property of the DataSet. The DataTable also has properties named Columns and Rows which are collections of DataColumn and DataRow respectively. This properties contain the individual columns and rows of the table from the database. The good thing about the DataTable and DataColumn is that, they can be assigned with names. This is done by using the TableName and ColumnName properties or using their constructors. Let's create a simple DataTable and add it to the a DataSet. Create a new Windows Forms Application and name it DataSetDemo. Add a DataGridView from the toolbar and set its Dock property to Fill.

Double click the title bar of the form to generate an event handler for the form's Load event. First, be sure to import the System.Data namespace. Use the following code for the Load even handler.
1 private void Form1_Load(object sender, EventArgs e)

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

2 { 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46}

//Initialize components DataSet personsDataSet = new DataSet(); DataTable personsTable = new DataTable("Persons"); DataColumn firstNameColumn = new DataColumn("FirstName"); DataColumn lastNameColumn = new DataColumn("LastName"); DataColumn ageColumn = new DataColumn("Age"); DataRow firstPerson; DataRow secondPerson; DataRow thirdPerson; //Construct the table's column personsTable.Columns.AddRange(new DataColumn[] { firstNameColumn, lastNameColumn, ageColumn }); //Create three rows/records firstPerson = personsTable.NewRow(); secondPerson = personsTable.NewRow(); thirdPerson = personsTable.NewRow(); //Assign values to rows firstPerson["FirstName"] = "Mark"; firstPerson["LastName"] = "Davidson"; firstPerson["Age"] = 18; secondPerson["FirstName"] = "John"; secondPerson["LastName"] = "Fredrich"; secondPerson["Age"] = 22; thirdPerson["FirstName"] = "Chelsey"; thirdPerson["LastName"] = "Bells"; thirdPerson["Age"] = 19; //Add the rows to the table personsTable.Rows.Add(firstPerson); personsTable.Rows.Add(secondPerson); personsTable.Rows.Add(thirdPerson); //Add the table to the DataSet personsDataSet.Tables.Add(personsTable); dataGridView1.DataSource = personsDataSet.Tables["Persons"];

Example 1 Lines 4-11 declares the different classes for creating a complete DataTable and DataSet. Notice the passed names inside the constructor for the DataTable and each DataColumn. This will make them easier to reference when we call them using the DataSet. Lines 14-17 adds the created DataColumn object to the Columns property of the DataTable. It is important that you do this first before specifying the rows. Lines 20-22 initializes each DataRow object using the DataTable.NewRow() method which returns a DataRow object that already has the proper

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

number of values it can have. Lines 25-35 assigns values to each field of the DataRow objects. Note that each field was accessed via indexers that accepts that name of the corresponding DataColumn. To complete the DataTable, lines 38-40 adds all the rows to the DataTable.Rows property. Finally, we added the DataTable object to the Tables property of the DataSet. To access the table that we have added, we can use an indexer for the Tables property and pass the name of the table. We assign the table to the DataSource property of the DataGridView so it will show the contents of the DataTable that we have created. Run the program and you will see the records of the table inside the DataGridView control.

Connecting to a Database Through Code


The first example we encountered for connecting to databases involves Visual Studio tools that doesn't require you to type any code at all. We will now begin a series of lessons which concentrates on using the ADO.NET classes to type codes that connect to differet data sources. We will use Windows Forms Application project type to present the different examples of connecting to a data source. You should have also followed the lesson on creating a database and table where we created the database and table that we will need in the following lesson. What we will be covering in the next lessons is how to query (retrieve records), insert or add records, delete records, and update existing records. I will present two ways of doing this things, the connected way and the disconnected way. Although both does the same thing, they have their specific purposes and scenarios where you can use them. The connected approach is good if you want to execute commands quickly and you are working with a big sets of data. The disadvantage of it is that, you need to open the connection and no other connection can use it until you close it again. The disconnected approach is recommended if you are working with small chunks of data from the database. One big advantage of using it is that you don't need an open connection as the results are filled inside a DataSet. You can then do the modifications in the DataSet and submit the changes to the database later. If you have already tried out connecting to the database using the tools offered by Visual Studio, this time, you have to type every single code used to connect to the data source. Why do this if such tools already exists? This is because those tools generates hundreds of lines of code which is optimized and full of advanced stuffs you won't be needing for a simple data-driven application. The codes we will write will only contain several lines of code. As we progress we will modify the codees we will learn and apply them to more advance applications and techniques. Note again that we will be using the Microsoft SQL Server 2008 Express as our main data source and I am assuming that you have installed it correctly including the sample database and tables we have created.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Querying a Database: Connected Approach


Querying is the process of retrieving data from a data source such as a database. We can do queries using the SELECT statement of the SQL. You will learn how to use this statement to query a table in a database using ADO.NET classes. We will present the connected approach of querying data from the data source. The following are the basic steps you should follow when querying results with an open connection. 1. Create A Connection 2. Create A Command 3. Create A DataReader 4. Specify connection string for the Connection 5. Specify Connection that will be used for the Command 6. Specify the CommandText that will be executed by the Command 7. Add values to command parameters (if any). 8. Open the Connection 9. Execute DataReader 10. Read every row from the result set 11. Close the Reader 12. Close the Connection With this steps, we can already query a table of data from the database. To demonstrate these steps, let's create a new Windows Forms Application and name it QueryingDatabaseConnected. Add a ListBox control to the form and name it studentsListBox.

Figure 1 Double click the title bar to generate an event handler for the form's Load event. Be sure to import the System.Data.SqlClient at the top.
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

using System.Data.SqlClient;

Use the following code for the Load event handler.


private void Form1_Load(object sender, EventArgs e) 1 { 2 SqlConnection connection = new SqlConnection(); 3 SqlCommand command = new SqlCommand(); 4 SqlDataReader reader; 5 6 connection.ConnectionString = @"Data Source=.\SQLEXPRESS;Initial 7 Catalog=University;" 8 + "Integrated Security=SSPI"; 9 command.Connection = connection; 10 command.CommandText = "SELECT FirstName, LastName, Age FROM Students"; 11 12 connection.Open(); 13 reader = command.ExecuteReader(); 14 15 while (reader.Read()) 16 { 17 string firstName = reader["FirstName"].ToString(); 18 string lastName = reader["LastName"].ToString(); 19 int age = Convert.ToInt32(reader["Age"]); 20 21 studentsListBox.Items.Add(String.Format("{0} {1}, 22{2}",firstName,lastName,age)); 23 } 24 25 reader.Close(); 26 connection.Close(); }

Example 1 Line 3 creates a Connection object (Step 1). Line 4 creates a command object (Step 2). Line 5 declares a reader object (Step 3). Line 7 assigns the proper connection string for our connection (Step 4). The connection string uses the SQLEXPRESS server instance and the University database as the initial database. Line 9 assigns the Connection to be used by the Command object (Step 5). Line 10 specifies the SQL command for the Command object (Step 6). The command specifies that we get the FirstName, LastName, and Age of every record from the Students table. The SQL command assigned to the CommandText of the Command has no parameters so we can skip Step 7 which adds the required values to command parameters. We then open the connection in line 12 by usign the DbConnection.Open() method (Step 8). Line 13 creates a DbDataReader instance using the DbCommand.ExecuteReader() method and we assigned the returned DbDataReader object to a variable so we can use it later (Step 9). Lines 15 to 22 iterates each row of the result set returned by executing the SELECT statement of the Command (Step 10). We used the DbDataReader.Read() method to obtain the first row of the result set. If there is at least one row available, the Read() will return true and the loop will continue. We then assigned the values of each column to their specific variables(lines 17-19). We used the indexer for the DbDataReader object that accepts a string representing the name of the column. We then converted their results to proper data types. For example, we converted the content of
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

reader["Age"] to integer and stored it to an integer variable. Line 21 simply adds the retrieved data to the Items of the ListBox. After the first loop, the Read() method will execute again and obtain the next row in the result set. If no more records are found, then Read() will return false and exit the loop. After exiting the loop, we closed the DataReader in line 24 (Step 11) and also the Connection in line 25 (Step 12). Execute the program and you will see the following output.

Figure 2 By using a while loop in our code, the Read() method was executed until no more records are found. Each record was then added to the ListBox and presented to the user. You can simplify the code even more by taking advantage of the overloaded constructors of the DbConnection and DbCommand classes. For example, you can simple combine Step 1 and Step 4 by using the DbConnection's overloaded constructor that accepts the connection string.
SqlConnection connection = new SqlConnection(@"Data Source=.\SQLEXPRESS;" + "Initial Catalog=University;Integrated Security=SSPI");

You can combine Steps 2, 5, 6 by using the DbCommand's overloaded constructor that accepts the command text and the connection to be used.
SqlCommand command = new SqlCommand( "SELECT FirstName, LastName, Age FROM Students", connection);

Another thing is that we can use the using statement when creating a connection. Consider the following modifications to the code in Example 1.
1 using (SqlConnection connection = new SqlConnection()) 2 { 3 SqlCommand command = new SqlCommand(); 4 SqlDataReader reader;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

5 6 connection.ConnectionString = @"Data Source=.\SQLEXPRESS;Initial 7 Catalog=University;" 8 + "Integrated Security=SSPI"; 9 command.Connection = connection; 10 command.CommandText = "SELECT FirstName, LastName, Age FROM Students"; 11 12 connection.Open(); 13 reader = command.ExecuteReader(); 14 15 while (reader.Read()) 16 { 17 string firstName = reader["FirstName"].ToString(); 18 string lastName = reader["LastName"].ToString(); 19 int age = Convert.ToInt32(reader["Age"]); 20 21 studentsListBox.Items.Add(String.Format("{0} {1}, {2}", 22 firstName, lastName, age)); 23 } 24 25 reader.Close(); }

Example 2 The whole connnection procces was enclosed inside the using block. On the first line of the using statement, we placed the declaration and initialization of the Connection object. This signifies the using block to immediately destroy the Connection the moment it exits the block. So if the execution reaches the closing brace of the using block, our Connection will be destroyed, and as a result, it will automatically be close. That's why, we can omit the call to DbCommand.Close() method. This technique is better because it ensures that the connection will be closed when you are finished using it. Note that the Connection object will no longer be accessable once the execution leaves the using block. Another good practice is enclosing the connection process into a try catch finally block. This ensures the program that it can handle any database errors or exceptions it can encounter during runtime. Suppose for example that the connection string is wrong or the connection has timed out, then exceptions will be thrown and you need to handle them. We can start adding the try block from the line where the DbConnection.Open() was called.
1 try 2 { 3 connection.Open(); 4 reader = command.ExecuteReader(); 5 6 while (reader.Read()) 7 { 8 string firstName = reader["FirstName"].ToString(); 9 string lastName = reader["LastName"].ToString(); 10 int age = Convert.ToInt32(reader["Age"]); 11 12 studentsListBox.Items.Add(String.Format("{0} {1}, {2}", 13 firstName, lastName, age));

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

14 } 15} 16catch (SqlException e) 17{ 18 MessageBox.Show(e.Message); 19} 20finally 21{ 22 reader.Close(); 23 connection.Close(); 24}

Example 3 From the moment of opening the connection, to accessing the contents of each row, exceptions can be thrown so we enclosed all of them in a try block. We used the SqlException class in the catch block (line 16) which is an SQL Server provider's version of DbException, to handle any database related errors. We then show the error message to the user using the Message property. We placed the codes that closes the DataReader and the Connection (lines 22-23) inside the finally block. We did this to ensure that this codes will always execute regardless of whether exceptions were found or not. If you used a using statement as shown earlier, then you wont have to write the code for closing the Connection. Try to get a habit of using exception handling when connecting and accessing a data source.

Querying a Database: Disconnected Approach


We can query results from a database without keeping an open connection. This is through the help of the DataAdapter classes and the DataSet class. The DataAdapter executes commands to the database and fills the results returned by the query inside a table of the DataSet. You can then access every record using the Rows property of the DataTable or every values of its fields by specifying the name of the column. The following are the basic steps for querying and displaying a result set from a database using the disconnected approach. 1. Create a Connection 2. Create a Command 3. Create a DataAdapter 4. Create a DataSet 5. Specify connection string for the Connection 6. Specify Connection that will be used by the Command 7. Specify the CommandText that will be executed by the command 8. Add values to command parameters (if any) 9. Specify SelectCommand for the DataAdapter 10. Fill the DataSet using the DataAdapter 11. Display results Let's create a simple application to demonstrate these steps. We will create an application that shows the result returned by a query using the disconnected approach. Create a new Windows

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Forms Application and name it QueryingDatabaseDisconnected. Add a ListBox to the form and name it studentsListBox.

Figure 1 Double click the form to generate the event handler for the form's Load event. Be sure to import the System.Data namespace for the DataSet class, and the System.Data.SqlClient namespace for classes required for connecting to SQL Server.
using System.Data; using System.Data.SqlClient;

After that, use the following code for the Load event handler.
1 private void Form1_Load(object sender, EventArgs e) 2 { 3 SqlConnection connection = new SqlConnection(); 4 SqlCommand command = new SqlCommand(); 5 SqlDataAdapter adapter = new SqlDataAdapter(); 6 DataSet dataset = new DataSet(); 7 8 connection.ConnectionString = @"Data Source=.\SQLEXPRESS;" + 9 "Initial Catalog=University;Integrated Security=SSPI"; 10 command.Connection = connection; 11 command.CommandText = "SELECT FirstName, LastName, Age FROM Students"; 12 adapter.SelectCommand = command; 13 adapter.Fill(dataset, "Students"); 14 15 foreach (DataRow student in dataset.Tables["Students"].Rows) 16 { 17 studentsListBox.Items.Add(String.Format("{0} {1},{2}", 18 student["FirstName"], student["LastName"], student["Age"]));

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

19 20}

Example 1 Lines 3-6 creates the necessary objects as stated in Steps 1 to 4. We then assigned the connection string to the ConnectionString property of the Connection object (lines 8-9). Lines 10-11 assigns the Connection and CommandText to be used by the Command object. Since there is no command parameters specified in the command text, we can skip Step 8. Line 12 specifies the Command to be used as the SelectCommand by the DataAdapter. We passed the Command that we created which retrieves the FirstName, LastName, and Age of every student. Line 13 uses the Fill() method of the DataAdapter to execute the command. The first argument of the method is the DataSet to be filled and the second argument is the name of the table that will hold the result set. The Fill() method creates a DataTable with the specified name where the result set will be contained. Then that DataTable will be added to the Tables property of the DataSet. Lines 15 to 19 access each row in the DataTable using a foreach loop. As you can see, we used the Tables property of the DataSet and specified the name of the table using an indexer. We then used the Rows property of the returned DataTable which contains the collection of all DataRows of the result set. We assigned each row in a temporary variable student. Line 17 adds the value FirstName, LastName, and Age fields using indexers and specifying the name of the collumn. Execute the application and you will see all the students loaded in the ListBox.

Figure 2 Using the disconnected approach, we can also easily bind a DataTable into a DataGridView control. As an example, let's modify our previous application by deleting the ListBox control and replacing it with a DataGridView control with the name studentsDataGridView.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 3 Modify the code inside the form's Load event handler.
private void Form1_Load(object sender, EventArgs e) { SqlConnection connection = new SqlConnection(); SqlCommand command = new SqlCommand(); SqlDataAdapter adapter = new SqlDataAdapter(); DataSet dataset = new DataSet(); connection.ConnectionString = @"Data Source=.\SQLEXPRESS;" + "Initial Catalog=University;Integrated Security=SSPI"; command.Connection = connection; command.CommandText = "SELECT FirstName, LastName, Age FROM Students"; adapter.SelectCommand = command; adapter.Fill(dataset, "Students"); studentsDataGridView.DataSource = dataset.Tables["Students"]; }

Example 2 We used the DataSource property of the DataGridView the specifies the source of data to be shown by the control. We specified it's value to be the DataTable that we have field by accessing the Tables property and providing the name we have specified in the indexer. Execute the program and see the results.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 4 We have seen how to query results using the disconnected approach using the DataAdapter and the DataSet classes.

Inserting Records: Connected Approach


Inserting records is very easy to do using the ADO.NET's Command classes. We will discuss inserting of records using the connected approach. We will also take a look at using parameters. The following are the basic steps of inserting record. 1. 2. 3. 4. 5. 6. 7. 8. 9. Create a Connection Create a Command Specify connection string to Connection Specify Connection that the Command will use Specify the INSERT Statement for the CommandText of the Command Add values to command parameters if any Open Connection Execute the command Close Connection

You can see that the steps are fewer compared to querying a data from a database. The following application uses the University database and allows you to insert new records to the Students table. Create a new Windows Forms Application and name it InsertingRecordsConnected. Add labels and text boxes for FirstName, LastName, Gender, Age, and Address fields. Name the textboxes firstNameTextBox, lastNameTextBox, genderTextBox, ageTextBox, and addressTextBox. Also add a button and name it addButton.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 Double click the button to generate an event handler for its Click event. Import the System.Data.SqlClient and use the following code for the handler.
1 private void button1_Click(object sender, EventArgs e) 2 { 3 SqlConnection connection = new SqlConnection(); 4 SqlCommand command = new SqlCommand(); 5 6 connection.ConnectionString = @"Data Source=.\SQLEXPRESS;" + 7 "Initial Catalog=University;Integrated Security=SSPI"; 8 command.Connection = connection; 9 command.CommandText = "INSERT INTO Students " + 10 "(FirstName, LastName, Gender, Age, Address) VALUES " + 11 "(@FirstName, @LastName, @Gender, @Age, @Address)"; 12 13 command.Parameters.AddWithValue("@FirstName", firstNameTextBox.Text); 14 command.Parameters.AddWithValue("@LastName", lastNameTextBox.Text); 15 command.Parameters.AddWithValue("@Gender", genderTextBox.Text); 16 command.Parameters.AddWithValue("@Age", ageTextBox.Text); 17 command.Parameters.AddWithValue("@Address", addressTextBox.Text); 18 19 try 20 { 21 connection.Open(); 22 int result = command.ExecuteNonQuery(); 23 if (result > 0) 24 MessageBox.Show("Student successfully added!"); 25 else 26 MessageBox.Show("Failed to add student!"); 27 } 28 catch (SqlException ex) 29 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

30 31 32 33 34 35 36}

MessageBox.Show("An error has occured!"); } finally { connection.Close(); }

Example 1 We only declared a Connection and a Command because they are sufficient to do our task for inserting records. We also assign an INSERT statement as the CommandText for our command (lines 9-11). As you can see, the command has several command parameters which starts with @ symbol. Also notice that we didn't specify the StudentID in the list of parameters becuase it is an identity field and will automatically be assigned with a value. Lines 13-17 adds values to each parameter using the AddWithValue() method of the DbCommand's Parameters property. This method accepts the command parameter name, and the actual value that will replace it. For example, we are going to change the @FirstName parameter with whatever the text of firstNameTextBox. Inside a try block, we open the connection and execute the command using the DbCommand.ExecuteNonQuery() method (line 22). This method is used to execute nonquery SQL statements such as INSERT, DELETE, UPDATE, and CREATE which are statements that doesn't return result sets. The method returns an integer value which represents the number of rows affected. Since we insert a record, we are expecting the value 1 to be returned. We placed the returned value in a variable. Using an if statement in line 23, we tested if the rows affected is not 0 to confirm that the the row was successfully updated. The catch block catches all the SqlException that will be thrown inside the try block. We simply write a code that will show an error message when a database-related error occured such as wrong connection string. The finally block contains the code to close the connection. Execute our program and add text values that will be inserted to the Students table.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 2 Click the add button to insert the record. If nothing is wrong, then a success message will show up.

Figure 3 The next lesson will take a look at adding records using the disconnected approach.

Inserting Records: Disconnected Approach


Inserting records using the disconnected approach is a little different compared to doing it using the connected approach. We need to use the DataAdapter and the DataSet classes. When modifying records using the disconnected approach, what we modify is the contents of the DataTable, then after the modification, we submit the changes to the database. So if we want to insert a new records, then we add a DataRow in the Rows property of the DataTable. After that, we invoke the Update() method which will submit the inserted row to the actual database table. The INSERT command used for it is generated by a CommandBuilder object which is available

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

for each data provider. For example, for SQL provider, you can use the SqlCommandBuilder class. The following are the basic steps for inserting a record using the disconnected approach. 1. Create a Connection 2. Create a Command 3. Create a DataAdapter 4. Create a CommandBuilder and associate it to the DataAdapter 5. Create a DataSet 6. Specify connection string for the connection 7. Specify Connection to be used by the Command 8. Specify CommandText for the Command 9. Add values to command parameters if any 10. Specify the SelectCommand for the DataAdapter 11. Fill the DataSet with the result set from the database table 12. Create a new DataRow object 13. Assign values for each of it's field 14. Add the DataRow object to the specified DataTable of the DataRow 15. Send the changes to the database We need to retrieve the contents of a database table that we wan't to add a record. That is why we still need to specify the SelectCommand for the DataAdapter. After that, we can make any changes to the DataTable containing the results. We can add a new DataRow representing the new record in it's Rows property. To demonstrate the steps above, create a new Windows Forms Application and name it InsertingRecordsDisconnected. Add labels and text boxes for FirstName, LastName, Gender, Age, and Address fields. Name the textboxes firstNameTextBox, lastNameTextBox, genderTextBox, ageTextBox, and addressTextBox. Also add a button and name it addButton.

Figure 1
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

Double click the button to generate an event handler for its Click event. Import the System.Data and System.Data.SqlClient. Use the following code for the handler.
1 private void addButton_Click(object sender, EventArgs e) 2 { 3 SqlConnection connection = new SqlConnection(); 4 SqlCommand command = new SqlCommand(); 5 SqlDataAdapter adapter = new SqlDataAdapter(); 6 SqlCommandBuilder builder = new SqlCommandBuilder(adapter); 7 DataSet dataset = new DataSet(); 8 9 connection.ConnectionString = @"Data Source=.\SQLEXPRESS;" + 10 "Initial Catalog=University;Integrated Security=SSPI"; 11 command.Connection = connection; 12 command.CommandText = "SELECT * FROM Students"; 13 adapter.SelectCommand = command; 14 adapter.Fill(dataset, "Students"); 15 16 DataRow row = dataset.Tables["Students"].NewRow(); 17 row["FirstName"] = firstNameTextBox.Text; 18 row["LastName"] = lastNameTextBox.Text; 19 row["Gender"] = genderTextBox.Text; 20 row["Age"] = Int32.Parse(ageTextBox.Text); 21 row["Address"] = addressTextBox.Text; 22 23 dataset.Tables["Students"].Rows.Add(row); 24 25 try 26 { 27 int result = adapter.Update(dataset, "Students"); 28 29 if (result > 0) 30 MessageBox.Show("Success!"); 31 else 32 MessageBox.Show("Failed!"); 33 } 34 catch (SqlException ex) 35 { 36 MessageBox.Show(ex.Message); 37 } 38}

Example 2 We created the necessary objects in lines 3-7. Note the create of SqlCommandBuilder in line 6. In its constructor, we pass the created DataAdapter object to associate the CommandBuilder to it. Lines 12-14 fills the DataSet of values from the Student table and adds the result to the DataTable named Students inside the DataSet. Now that we have the values of the table from the database, we can now insert values to that DataTable. Line 16 creates a new DataRow object which represents the row of a DataTable. We specify which Table the row will be added and used the DataTable's NewRow() method. Doing this instead of intializing a DataRow using a constructor saves automatically provides the necessary columns for the DataRow together with their associated column names. Lines 17-21 accesses each column using the DataRow's indexer

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

that accepts the name of the column. We assigned each of the value of every text box. In line 23, we added the row to the Rows property of the DataTable that contains the records. We have now modifies the DataTable because we added a new record, but the record is only added to the DataTable, not the actual database table. Line 27 calls the DataAdapter's Update() method and we passed the DataSet and the name of the DataTable. When Update() is called, the CommandBuilder generates the required SQL statements for every changes or modification it detects. Those SQL commands are then executed to the database. In our case, since we added a new row to the DataTable, CommandBuilder generates an INSERT Statement together with parameters filled with the values you specified. After the execution of the command, the values is then added to the actual database table. The Update() method returns an integer value representing the number of row affected. Since we inserted 1 row, then we are expecting a return value of 1. We test if the result is greater than 0 in line 29. If it is, then we show a success message. Otherwise, we tell the user that the insertion has failed. Execute the program and provide a value to be added to the database table.

Clicking the Add Student button will add the values to the DataTable and the changes will be sent to the database where a new row will be added to the actual database table.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Deleting Records: Connected Approach


We will now delete a database record using the connected approach. The steps are the same as inserting a record while connected to a database which uses the DbCommand.ExecuteNonQuery() method. 1. 2. 3. 4. 5. 6. 7. 8. 9. Create a Connection Create a Command Specify connection string to Connection Specify Connection that the Command will use Specify the DELETE Statement for the CommandText of the Command Add values to command parameters if any Open Connection Execute the command Close Connection

Let's create a simple application that allows you to specify the StudentId and delete the corresponding record having that ID. Create a new Windows Forms Application and name it DeletingRecordsConnected. Add a label and text box for the StudentID and a button that will execute the commands. Name the text box studentIdTextBox and the button as deleteButton.

Figure 1 Double click the button to generate an event handler for its Click event. Be sure to import the System.Data.SqlClient namespace. Use the following code for the event handler.
1 private void button1_Click(object sender, EventArgs e) 2 { 3 SqlConnection connection = new SqlConnection(); 4 SqlCommand command = new SqlCommand(); 5 6 connection.ConnectionString = @"Data Source=.\SQLEXPRESS;" + 7 "Initial Catalog=University;Integrated Security=SSPI"; 8 command.Connection = connection; 9 command.CommandText = "DELETE FROM Students WHERE 10StudentID=@StudentID"; 11 command.Parameters.AddWithValue("@StudentID", studentIdTextBox.Text); 12 13 try 14 {

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 }

connection.Open(); int result = command.ExecuteNonQuery(); if (result > 0) MessageBox.Show("Student was removed!"); else MessageBox.Show("Can't find student."); } catch (SqlException ex) { MessageBox.Show("An error has occured."); } finally { connection.Close(); }

Example 2 Line 9 specified a DELETE SQL Statement which has 1 command parameter, the StudentID to be deleted. Line 10 add's the text of the studentIdTextBox as a value to that command parameter. Inside the try block, we opened the connection and Line 15 uses the ExecuteNonQuery() method to execute the DELETE command. The method returns an integer which is the number of rows affected. Line 16 tested if at least 1 row was affected since we delete 1 record. If so, we show a message showing that the deletion was successful. If no records were affected, it simply means the record was not found and no records where deleted. Run the program and type a StudentId that exist in the Students table.

If a matching row is found, it is removed from the table.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Deleting Records: Disconnected Approach


Deleting database using the disconnected approach is simillar to inserting a row using the DataSet and the DataAdapter classes. But instead of adding a new DataRow object, you will delete it from the DataTable of the DataSet. The following are the basic steps to delete a row using disconnected approach. 1. Create a Connection 2. Create a Command 3. Create a DataAdapter 4. Create a CommandBuilder and associate it to the DataAdapter 5. Create a DataSet 6. Specify connection string for the connection 7. Specify Connection to be used by the Command 8. Specify CommandText for the Command 9. Add values to command parameters if any 10. Specify the SelectCommand for the DataAdapter 11. Fill the DataSet with the result set from the database table 12. Find the row to delete. 13. Delete the row from the DataTable if found. 14. Send the changes to the database Let's create a simple application that allows you to specify the StudentId and delete the corresponding record having that ID. Create a new Windows Forms Application and name it DeletingRecordDisconnected. Add a label and text box for the StudentID and a button that will execute the commands. Name the text box studentIdTextBox and the button as deleteButton.

Figure 1 Double click the button to generate an event handler for its Click event. Be sure to import the System.Data.SqlClient namespace. Use the following code for the event handler.
1 private void deleteButton_Click(object sender, EventArgs e) 2 { 3 4 SqlConnection connection = new SqlConnection(); 5 SqlCommand command = new SqlCommand(); 6 SqlDataAdapter adapter = new SqlDataAdapter(); 7 SqlCommandBuilder builder = new SqlCommandBuilder(adapter);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39}

DataSet dataset = new DataSet(); connection.ConnectionString = @"Data Source=.\SQLEXPRESS;" + "Initial Catalog=University;Integrated Security=SSPI"; command.Connection = connection; command.CommandText = "SELECT * FROM Students"; adapter.SelectCommand = command; adapter.Fill(dataset, "Students"); foreach (DataRow row in dataset.Tables["Students"].Rows) { if (row["StudentID"].ToString() == studentIdTextBox.Text) { row.Delete(); } } try { int result = adapter.Update(dataset, "Students"); if (result > 0) MessageBox.Show("Success!"); else MessageBox.Show("Failed!"); } catch (SqlException ex) { MessageBox.Show(ex.Message); }

Example 1 We created the necessary objects in lines 4-8. Note the create of SqlCommandBuilder in line 7. In its constructor, we pass the created DataAdapter object to associate the CommandBuilder to it. Lines 13-15 fills the DataSet of values from the Student table and adds the result to the DataTable named Students inside the DataSet. Now that we have the values of the table from the database, we can now delete a row from that DataTable. We first need to search which record to delete. We used a foreach loop (line 17-24) to iterate through each record in the DataSet. Line 19 tests whether the content of the StudentID field of the current row is equal to what the user specified in the studentIdTextBox. If it matches, we use the DataRow.Delete() method to delete that row from the table. Line 28 calls the DataAdapter's Update() method and we passed the DataSet and the name of the DataTable. When Update() is called, the CommandBuilder generates the required SQL statements for every changes of modification it detects. Those SQL commands are then executed to the database. In our case, since we deleate a row from the DataTable, CommandBuilder generates a DELETE Statement together with parameters filled with the values you specified. After the execution of the command, the row or rows are deleted from the actual database table. The Update() method returns an integer value representing the number of row affected. Since we

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

1 row was deleted, we are expecting a return value of 1. We test if the result is greater than 0 in line 30. If it is, then we show a success message. Otherwise, we tell the user that the deletion of the row has failed. Run the program and type a StudentId that exist in the Students table.

Figure 2 If a matching row is found, it is removed from the table.

Figure 3

Updating Records: Connected Approach


We will now take a look at updating fields of records in a database table. Like inserting and deleting records, updating also uses the DbCommand.ExecuteNonQuery() method. The steps is pretty much similar when updating a record using the connected approach. 1. 2. 3. 4. 5. 6. 7. 8. 9. Create a Connection Create a Command Specify connection string to Connection Specify Connection that the Command will use Specify the UPDATE statement for the CommandText of the Command Add values to command parameters if any Open Connection Execute the Command Close Connection

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The steps above are used for updating a record. Let's take a look at an example application. You type the StudentID and the new values for the fields corresponding to the ID. In a more realistic program, the current values will be shown first to you. But for simplicity, we will only show Therefore, we need to query values from the database. After the details are shown, the user can then edit details and send the changes to the database. Create a new Windows Forms Application and name it UpdatingRecordsConnected.

Label 1 2 3 4 5 6 7 Figure 1

Name textBoxStudentID textBoxFirstName textBoxLastName textBoxGender textBoxAge textBoxAddress buttonUpdate

Double click the Update button to generate an event handler for its Click event. Use the following code:
1 private void buttonUpdate_Click(object sender, EventArgs e) 2 { 3 SqlConnection connection = new SqlConnection(); 4 SqlCommand command = new SqlCommand(); 5 6 connection.ConnectionString = @"Data Source=.\SQLEXPRESS;" +

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39}

"Initial Catalog=University;Integrated Security=SSPI"; command.Connection = connection; command.CommandText = "UPDATE Students SET FirstName=@FirstName, " + "LastName=@LastName, Gender=@Gender, Age=@Age, Address=@Address " + "WHERE StudentID=@StudentID"; command.Parameters.Clear(); command.Parameters.AddWithValue("@FirstName", textBoxFirstName.Text); command.Parameters.AddWithValue("@LastName", textBoxLastName.Text); command.Parameters.AddWithValue("@Gender", textBoxGender.Text); command.Parameters.AddWithValue("@Age", textBoxAge.Text); command.Parameters.AddWithValue("@Address", textBoxAddress.Text); command.Parameters.AddWithValue("@StudentID", textBoxStudentID.Text); try { connection.Open(); int result = command.ExecuteNonQuery(); if (result > 0) MessageBox.Show("Update Successful!"); else MessageBox.Show("Update Failed!"); } catch (SqlException ex) { MessageBox.Show("An error occured."); } finally { connection.Close(); }

Example 1 Lines 9-11 specifies the UPDATE SQL command that will be used to update the row specified by the StudentID of its WHERE clause. We used command parameters on the command. Line 13 first clears any content of the Parameters property of our command because it may still contain the parameters of previous operation. Lines 14-19 uses the DbParameter.AddWithValue() method to add values to corresponding command parameters in our SQL command string. Since an SQL UPDATE is a non-query command (it doesn't return any records or results), line 24 uses the DbCommand.ExecuteNonQuery() method to update the specified record. The return value of this method is the number of rows affected. To confirm that a record was successfully updated, we checked if the result is 1 or above (line 26) and then we showed a success message. Run the program and type the StudentID you wan't to edit along with the new values it will contain.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

If no error is found, then a success message will pop out and the record in the database table will be modified.

The program in this lesson simple shows how to update a record. But it will be hard to update a record without knowing the current values first. A seperate tutorial will apply everything we have learned (querying, inserting, deleting, updating). But first, let's take a look at how to update records using the disconnected approach.

Updating Records: Disconnected Approach


We will now take a look at updating records using the disconnected approach. Like inserting and deleting records using the disconnected approach, updating records also uses the DataAdapter, DataSet, and CommandBuilder classes to do it's job. The following are the basic steps for updating a record using the said classes. 1. 2. 3. 4. 5. 6. Create a Connection Create a Command Create a DataAdapter Create a CommandBuilder and associate it to the DataAdapter Create a DataSet Specify connection string for the connection
Bsc ABDULRAHIM ALI ATHUMAN

COMPILED BY:

7. Specify Connection to be used by the Command 8. Specify the SELECT statement for the CommandText of the Command 9. Add values to command parameters if any 10. Specify the SelectCommand for the DataAdapter 11. Fill the DataSet with the result set from the database table 12. Find the row to update. 13. Edit the fields you want to update 14. Send the changes to the database The following example application allows you to update a certain record of a student based on the StudentID. A typical application like this would normally show the current values of the record first, but for simplicity, we will go straight to the updating. You will simply need to type the StudentID and then the new values for the corresponding record. Create a new Windows Forms Application and create a form similar to the following one.

Label Name 1 textBoxStudentId 2 textBoxFirstName 3 textBoxLastName 4 textBoxGender 5 textBoxAge 6 textBoxAddress 7 buttonUpdate Figure 1

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

After creating the GUI, double click buttonUpdate and use the following event handler for its Click event.
1 private void buttonUpdate_Click(object sender, EventArgs e) 2 { 3 SqlConnection connection = new SqlConnection(); 4 SqlCommand command = new SqlCommand(); 5 SqlDataAdapter adapter = new SqlDataAdapter(); 6 SqlCommandBuilder builder = new SqlCommandBuilder(adapter); 7 DataSet dataset = new DataSet(); 8 9 connection.ConnectionString = @"Data Source=.\SQLEXPRESS;" + 10 "Initial Catalog=University;Integrated Security=SSPI"; 11 command.Connection = connection; 12 command.CommandText = "SELECT * FROM Students"; 13 14 adapter.SelectCommand = command; 15 adapter.Fill(dataset, "Students"); 16 17 foreach (DataRow row in dataset.Tables["Students"].Rows) 18 { 19 if (row["StudentID"].ToString() == textBoxStudentID.Text) 20 { 21 row["FirstName"] = textBoxFirstName.Text; 22 row["LastName"] = textBoxLastName.Text; 23 row["Gender"] = textBoxGender.Text; 24 row["Age"] = textBoxAge.Text; 25 row["Address"] = textBoxAddress.Text; 26 } 27 } 28 29 try 30 { 31 int result = adapter.Update(dataset, "Students"); 32 33 if (result > 0) 34 MessageBox.Show("Update Successful."); 35 else 36 MessageBox.Show("Update Failed."); 37 } 38 catch (SqlException ex) 39 { 40 MessageBox.Show(ex.Message); 41 } 42}

Example 1 After initializing the required variables, we first need to transfer the contents of the table in a dataset so we will have an in-memory database that we can work with. That's why, we use the SELECT command and used the DbDataAdapter.Fill() method to retrieve all the records from the Students table. Updating using disconnected approach does not require an UPDATE Sql command. The UPDATE command will be generated by the SqlCommandBuilder object. The update will be done using searching and simple value assignment with C#.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Line 17 uses a foreach loop to check each row. We used the appropriate table from the dataset as the source. Remember that each row in a DataTable is of type DataRow. Line 19 checks if the StudentID field of the current DataRow is equal to the specified StudentID in the textboxStudentID. If so, then inside the if statement, we update each of the field of that DataRow to the new values from the textboxes. After that, we simply need to call the DbDataAdapter.Update() method to send the changes to the database (line 31). This method accepts two arguments, the dataset where the updated row is contained, and the name of the table in that dataset (not the database table). If the method is successful at updating the actual database table, then the number of rows updated is returned. We simply assign the value returned in a variable so we can test if the update was successful, that is, if the value returned is not 0. Run the program and type the StudentID of an existing student. Type new values for each text box.

Click the update button to initiate the update process. If everything is working properly, then you will be presented with a success message.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The program in this lesson simple shows how to update a record. But it will be hard to update a record without knowing the current values first. A seperate tutorial will apply everything we have learned (querying, inserting, deleting, updating).

Simple Student Enrollment System - Connected Approach


We will create a Simple Enrollment System that allows you to search for an student in the database using a specified StudentID. It will also allow you to add or remove a student from the database or update his/her student information. We will use the connected approach for querying, inserting, removing, and updating records. The next tutorial will show another version showing how to create the same project using the disconnected version. Create a new windows forms application and create a user interface similar to the one shown in Figure 1.

Figure 1 Label Name Properties 1 textBoxStudentId 2 textBoxFirstName Enabled: False 3 textBoxLastName Enabled: False 4 textBoxGender Enabled: False

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Label Name 5 textBoxAge 6 textBoxAddress 7 buttonDelete 8 buttonEdit 9 buttonAddNew 10 buttonShow Figure 2

Properties Enabled: False Enabled: False Text: Delete Text: Edit Text: Add New Text: Show

Go to the Code Editor by pressing F7 and be sure to first import the two neccessary namespaces for this database connection.
using System.Data; using System.Data.SqlClient;

Add the following private fields into the Form1 class:


private private private private private SqlConnection connection; SqlCommand command; SqlDataReader reader; bool updateReady; bool insertReady;

We declared the fields that will be used for connecting and issuing commands to the database. We declared them as class fields instead of as local variables so they will be shared by all database operations (For example, no need to declare Connection objects for querying and another one for inserting records). The updateReady and inserReady field will be used later for updating and inserting new students. On the Form's constructor add the codes in lines 5-11.
1 public Form1() 2 { 3 InitializeComponent(); 4 5 connection = new SqlConnection(); 6 command = connection.CreateCommand(); 7 connection.ConnectionString = @"Data Source=.\SQLEXPRESS;" + 8 "Initial Catalog=University; Integrated Security=SSPI"; 9 10 updateReady = false; 11 insertReady = false; 12}

Example 1 Line 5 initializes our Connection object. Line 6 uses the DbConnection.CreateCommand() method which returns an DbCommand object that is already connected to the DbConnection object that calls that method. In this case, calling the CreateCommand() method returns an

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

SqlCommand object with its Connection property already referring to the SqlConnection object. Line 7-8 indicates the connection string for the connection. Lines 10-11 sets the updateReady and insertReady flags to false. This simply means that the program is initially not allowing an update or addition of new students. The text fields except the StudentID are initially disabled so no updates or insertions can be made. The program for now can only do queries to the database by typing the StudentId in textBoxStudentId and clicking the buttonShow. The code for the Click event of buttonShow is as follows:
private void buttonShow_Click(object sender, EventArgs e) 1 { 2 command.CommandText = "SELECT * FROM Students WHERE 3 StudentID=@StudentID"; 4 command.Parameters.Clear(); 5 command.Parameters.AddWithValue("@StudentID", textBoxStudentID.Text); 6 7 try 8 { 9 connection.Open(); 10 reader = command.ExecuteReader(CommandBehavior.SingleRow); 11 12 if (reader.Read()) 13 { 14 textBoxFirstName.Text = reader["FirstName"].ToString(); 15 textBoxLastName.Text = reader["LastName"].ToString(); 16 textBoxGender.Text = reader["Gender"].ToString(); 17 textBoxAge.Text = reader["Age"].ToString(); 18 textBoxAddress.Text = reader["Address"].ToString(); 19 } 20 else 21 MessageBox.Show("StudentID does not exist."); 22 } 23 catch (SqlException ex) 24 { 25 MessageBox.Show(ex.Message); 26 } 27 finally 28 { 29 connection.Close(); 30 } 31 }

Example 2 Since we declared our Connection and Command objects as class fields, we can simply change the properties of them depending on the operation to be made. Line 3 changes the CommandText property of our Command object to a SELECT statement the retrieves everything from the Students table that has a StudentID specified. The command text has one command parameter for StudentID which will be replaced by the value typed by the user in textBoxStudentID as shown in line 5. Note that before that, we cleared the Parameters property first because it might already contain some values from other operation. We do that using the Clear() method (line 4). Inside a try block, we first open the connection and create a SqlDataReader using the DbCommand.ExecuteReader() method. We passed CommandBehavior.SingleRow value as an

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

argument to that method so the reader will only return one record which is the record of the student we are searching. Line 12 uses the Read() method to retrieve that single record from the database. If it is successful, then the method will return true, and inside the if statement, we show the values of each column of that record to their respective text boxes. The rest of the code are used when no record is found and when an SqlException is thrown. Don't forget to close the connection as shown in Line 29. Next in the list is the buttonAddNew which is responsible for adding or "enrolling" new students to the database. The following is the event handler for the buttonAddNew's Click event.
1 private void buttonAddNew_Click(object sender, EventArgs e) 2 { 3 if (!insertReady) 4 { 5 buttonAddNew.Text = "Enroll"; 6 ClearFields(); 7 textBoxStudentID.Text = GetNextStudentID().ToString(); 8 9 textBoxStudentID.Enabled = false; 10 textBoxFirstName.Enabled = true; 11 textBoxLastName.Enabled = true; 12 textBoxGender.Enabled = true; 13 textBoxAge.Enabled = true; 14 textBoxAddress.Enabled = true; 15 buttonShow.Enabled = false; 16 buttonEdit.Enabled = false; 17 buttonDelete.Enabled = false; 18 insertReady = true; 19 } 20 else 21 { 22 buttonAddNew.Text = "Add New"; 23 24 command.CommandText = "INSERT INTO Students " + 25 "(FirstName, LastName, Gender, Age, Address) VALUES " + 26 "(@FirstName, @LastName, @Gender, @Age, @Address)"; 27 command.Parameters.Clear(); 28 command.Parameters.AddWithValue("@FirstName", 29textBoxFirstName.Text); 30 command.Parameters.AddWithValue("@LastName", textBoxLastName.Text); 31 command.Parameters.AddWithValue("@Gender", textBoxGender.Text); 32 command.Parameters.AddWithValue("@Age", textBoxAge.Text); 33 command.Parameters.AddWithValue("@Address", textBoxAddress.Text); 34 35 try 36 { 37 connection.Open(); 38 39 int result = command.ExecuteNonQuery(); 40 41 if (result > 0) 42 MessageBox.Show("Student successfully enrolled."); 43 else 44 MessageBox.Show("Failed to enroll student.");

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 }

} catch (SqlException ex) { MessageBox.Show(ex.Message); } finally { connection.Close(); } textBoxStudentID.Enabled = true; textBoxFirstName.Enabled = false; textBoxLastName.Enabled = false; textBoxGender.Enabled = false; textBoxAge.Enabled = false; textBoxAddress.Enabled = false; buttonShow.Enabled = true; buttonEdit.Enabled = true; buttonDelete.Enabled = true; insertReady = false; }

Example 3 The buttonAddNew will serve as a toggle button. The insertReady field will determine the action that this button will perform. Since insertReady is initially false, lines 5-18 will be executed. Line 5 changes the text of the button to "Enroll" simply to notify the user that this button should be clicked once the details are entered. Line 6 calls a method that will clear all the fields if so it will be ready to accept new details from the user. The definition for the ClearFields() method is as follows:
private void ClearFields() { textBoxFirstName.Text = String.Empty; textBoxLastName.Text = String.Empty; textBoxGender.Text = String.Empty; textBoxAge.Text = String.Empty; textBoxAddress.Text = String.Empty; }

Example 4 Since we need will be adding a new student, we need to generate the next unique StudentID. We can't simply type a new student ID because the same student ID may already be in the database. That's why, line 7 calls another utility method called GetNextStudentID(). The defnition for this method is as follows:
1 private int GetNextStudentID() 2 { 3 command.CommandText = "SELECT IDENT_CURRENT('Students') + 4 IDENT_INCR('Students')"; 5

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 }

try { connection.Open(); int nextID = Convert.ToInt32(command.ExecuteScalar()); return nextID; } catch (SqlException ex) { MessageBox.Show(ex.Message); } finally { connection.Close(); } return 0;

Example 5 Line 3 creates an SQL Server command that will get the next Identity field value. Remember that the StudentID field of the Students table is an Identity field which auto increments when new records are added. The thing is, we can't simply get the last StudentID and add 1 because SQL server saves the last Identity value used so if we delete a record with StudentID 5, making the new last StudentID is 4, the next StudentID that will be generated will be 6. There is an SQL Server function called IDENT_CURRENT() which returns the current identity field and IDENT_INCR() which returns the increment value of the identity field. We passed the name of the table to these functions and added their return values to get the latest StudentID. We open the connection in line 7 and line 8 uses the DbCommand.ExecuteScalar() since we are expecting a single value (not record) to be returned. The value is the generated last StudentID but we need to convert it first to integer. Finally, wer returned that value to the caller of the method (line 9). Back to the code in Example 3, after getting a new StudentID, we simply display it using textBoxStudentID. Lines 9-14 enables the text boxes so the user can enter the details for the new student and lines 15-17 disables buttonShow, buttonInsert, and buttonDelete so the user can only click the "Enroll" button. Finally, line 18 changes the value of insertReady to true so the next time the user clicks this button, lines 22-63 will be executed instead. The first time the user clicks the buttonAddNew, the program is now ready to accept the information for the new student. After the user types the information for each field, the user should now then click the buttonAddNew again to execute the SQL INSERT command to the database. Let's now discuss lines 22-63 of Example 3 which does the actual communication to the database. Line 22 reverts back the label of the button to "Add New". Lines 24-26 changes the CommandText property of the Command object to an SQL INSERT statement. The command has 5 command properties for each field. Note that the StudentID was not included because it will automatically generated by SQL Server. Line 27 ensures that no existing command parameter values are in the Parameters collection of the Command object by using the Clear() method. Lines 28-32 assigns the value of each text box to their corresponding command parameter. After everything is set and the connection is openned, Line 38 uses the DbCommand.ExecuteNonQuery() method to execute the command to the database. Lines 54-63

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

disables the text boxes again and reenables the disabled buttons. The insertReady fields was also set a value of false to indicate the insertion process is complete and the user is required to click this button again if he/she will be adding another student. The buttonEdit also acts as a toggle button and most of the code is similar to the code of buttonAddNew.
1 private void buttonEdit_Click(object sender, EventArgs e) 2 { 3 if (!updateReady) 4 { 5 buttonEdit.Text = "Update"; 6 textBoxStudentID.Enabled = false; 7 textBoxFirstName.Enabled = true; 8 textBoxLastName.Enabled = true; 9 textBoxGender.Enabled = true; 10 textBoxAge.Enabled = true; 11 textBoxAddress.Enabled = true; 12 buttonShow.Enabled = false; 13 buttonAddNew.Enabled = false; 14 buttonDelete.Enabled = false; 15 updateReady = true; 16 } 17 else 18 { 19 buttonEdit.Text = "Edit"; 20 21 command.CommandText = "UPDATE Students SET FirstName=@FirstName, " 22+ 23 "LastName=@LastName, Gender=@Gender, Age=@Age, Address=@Address 24" + 25 "WHERE StudentID=@StudentID"; 26 command.Parameters.Clear(); 27 command.Parameters.AddWithValue("@FirstName", 28textBoxFirstName.Text); 29 command.Parameters.AddWithValue("@LastName", textBoxLastName.Text); 30 command.Parameters.AddWithValue("@Gender", textBoxGender.Text); 31 command.Parameters.AddWithValue("@Age", textBoxAge.Text); 32 command.Parameters.AddWithValue("@Address", textBoxAddress.Text); 33 command.Parameters.AddWithValue("@StudentID", 34textBoxStudentID.Text); 35 36 try 37 { 38 connection.Open(); 39 int result = command.ExecuteNonQuery(); 40 41 if (result > 0) 42 MessageBox.Show("Student details successfully updated."); 43 else 44 MessageBox.Show("Update failed."); 45 } 46 catch (SqlException ex) 47 { 48 MessageBox.Show(ex.Message);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

49 50 51 52 53 54 55 56 57 58 59 60 61 62 } }

} finally { connection.Close(); } textBoxStudentID.Enabled = true; textBoxFirstName.Enabled = false; textBoxLastName.Enabled = false; textBoxGender.Enabled = false; textBoxAge.Enabled = false; textBoxAddress.Enabled = false; buttonShow.Enabled = true; buttonAddNew.Enabled = true; buttonDelete.Enabled = true; updateReady = false;

Example 6 Clicking the buttonEdit for the first time will enable the text boxes and disable the buttons except the buttonEdit itself. We used the updateReady field to make the button toggle its functionality. After the changes has been made to the current student, clicking the button the second time will send the changes to the database. Lines 19-60 does this and the codes you just need to edit are the SQL command and the parameter values. Finally, the buttonDelete's Click event handler is shown in Example 7.
1 private void buttonDelete_Click(object sender, EventArgs e) 2 { 3 command.CommandText = "DELETE FROM Students WHERE 4 StudentID=@StudentID"; 5 command.Parameters.Clear(); 6 command.Parameters.AddWithValue("@StudentID", textBoxStudentID.Text); 7 8 try 9 { 10 connection.Open(); 11 12 int result = command.ExecuteNonQuery(); 13 14 if (result > 0) 15 { 16 MessageBox.Show("Student successfully deleted."); 17 ClearFields(); 18 } 19 else 20 MessageBox.Show("Failed to delete student."); 21 } 22 catch (SqlException ex) 23 { 24 MessageBox.Show(ex.Message); 25 }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

26 27 28 29 }

finally { connection.Close(); }

Example 7 We just changed the CommandText property of the command into a SQL DELETE statement that contains one command parameter which is the StudentID to delete. After specifying the command, adding the value for the command parameter, and openning the connection, line 11 uses the ExecuteNonQuery() method to actually delete record with the specified StudentID fromt he database table. Our simple enrollment system is now complete. To test it, run the program and type an existing StudentID in the first text box. Click the show button to see the student's information. If you want to edit those information, you can click the buttonEdit, type the new values, and click buttonEdit again to save the changes. You can also delete that student by clicking buttonDelete. To add or enroll a new student, click the buttonAddNew and type the information of the new student into the fields. Click the buttonAddNew once more to add the student into the Students database table. Download Project: SimpleEnrollmentSystemConnected.rar

Simple Student Enrollment System - Disconnected Approach


We will create a Simple Enrollment System that allows you to search for an student in the database using a specified StudentID. It will also allow you to add or remove a student from the database or update his/her student information. This lesson will use the disconnected approach for querying, inserting, removing, and updating records. Create a new windows forms application and create a user interface similar to the one shown in Figure 1.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Figure 1 Label Name Properties 1 textBoxStudentId 2 textBoxFirstName Enabled: False 3 textBoxLastName Enabled: False 4 textBoxGender Enabled: False 5 textBoxAge Enabled: False 6 textBoxAddress Enabled: False 7 buttonDelete Text: Delete 8 buttonEdit Text: Edit 9 buttonAddNew Text: Add New 10 buttonShow Text: Show Figure 2 Go to the Code Editor by pressing F7 and be sure to first import the two neccessary namespaces for this database connection.
using System.Data; using System.Data.SqlClient;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Add the following private fields into the Form1 class:


private SqlConnection connection; private SqlCommand command; private SqlDataAdapter adapter; private SqlCommandBuilder builder; private DataSet dataSet; bool updateReady = false; bool insertReady = false;

We declared the fields that will be used for connecting and issuing commands to the database. We declared them as class fields instead of as local variables so they will be shared by all database operations (For example, no need to declare Connection objects for querying and another one for inserting records). The updateReady and inserReady field will be used later for updating and inserting new students. On the Form's constructor add the codes in lines 5-11.
1 public Form1() 2 { 3 InitializeComponent(); 4 5 connection = new SqlConnection(); 6 connection.ConnectionString = @"Data Source=.\SQLEXPRESS;" + 7 "Initial Catalog=University;Integrated Security=SSPI"; 8 9 command = connection.CreateCommand(); 10 adapter = new SqlDataAdapter(command); 11 builder = new SqlCommandBuilder(adapter); 12 dataSet = new DataSet(); 13}

Example 1 Line 5 initializes our Connection object. Line 6 specifies the connection string that will be used for connection. Line 9 creates the command using the DbCommand.CreateCommand() method which returns a Command object that is already assigned to the Connection object that called that method. Line 10 creates a DataAdapter object and we passed the Command object that will be used as the SelectCommand inside its constructor. Line 11 passes the created DataAdapter in the constructor of the CommandBuilder object which will be used to generate SQL commands when the Update() method is called later. Finally, line 12 creates a DataSet() object which will contain the result sets obtained from the database. The program for now can only do queries to the database by typing the StudentId in textBoxStudentId and clicking the buttonShow. The code for the Click event of buttonShow is as follows:
1 private void buttonShow_Click(object sender, EventArgs e) 2 { 3 command.CommandText = "SELECT * FROM Students WHERE 4 StudentID=@StudentID"; 5 command.Parameters.Clear(); 6 command.Parameters.AddWithValue("@StudentID", textBoxStudentID.Text); 7 8 dataSet.Tables.Clear(); 9

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 }

int result = adapter.Fill(dataSet, "Students"); if (result > 0) { DataRow student = dataSet.Tables["Students"].Rows[0]; textBoxFirstName.Text = student["FirstName"].ToString(); textBoxLastName.Text = student["LastName"].ToString(); textBoxGender.Text = student["Gender"].ToString(); textBoxAge.Text = student["Age"].ToString(); textBoxAddress.Text = student["Address"].ToString(); } else { ClearFields(); MessageBox.Show("Student does not exist."); }

Example 2 Since we declared our Connection and Command objects as class fields, we can simply change the properties of them depending on the operation to be made. Line 3 changes the CommandText property of our Command object to a SELECT statement the retrieves everything from the Students table that has a StudentID specified. The command text has one command parameter for StudentID which will be replaced by the value typed by the user in textBoxStudentID as shown in line 5. Note that before that, we cleared the Parameters property first because it might already contain some values from other operation. We do that using the Clear() method (line 4). Line 7 clears the Tables collection property of the dataset incase there are already tables stored in it. Line 9 calls the DbDataAdapter.Fill() method to query the student from the database table and add it to a table named "Students" in the dataSet. The Fill() method will return the number of rows or result sets returned and we are expecting at least 1 so line 11 tests if the value returned is greater than 0. If so line 13 first stores the first row of the Students table in the dataSet into a DataRow object for easier typing and readablity although it is optional. Lines 14-18 shows the values of individual columns of the retrieved student row into their respective text boxes. Lines 20-24 are codes to be executed if no student with the specified student number is returned or found. Next in the list is the buttonAddNew which is responsible for adding or "enrolling" new students to the database. The following is the event handler for the buttonAddNew's Click event.
1 private void buttonAddNew_Click(object sender, EventArgs e) 2 { 3 if (!insertReady) 4 { 5 buttonAddNew.Text = "Enroll"; 6 ClearFields(); 7 textBoxStudentID.Text = GetNextStudentID().ToString(); 8 9 textBoxStudentID.Enabled = false; 10 textBoxFirstName.Enabled = true; 11 textBoxLastName.Enabled = true; 12 textBoxGender.Enabled = true;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62}

textBoxAge.Enabled = true; textBoxAddress.Enabled = true; buttonShow.Enabled = false; buttonEdit.Enabled = false; buttonDelete.Enabled = false; insertReady = true; } else { buttonAddNew.Text = "Add New"; command.CommandText = "SELECT * FROM Students"; dataSet.Tables.Clear(); adapter.Fill(dataSet, "Students"); DataRow row = dataSet.Tables["Students"].NewRow(); row["FirstName"] = textBoxFirstName.Text; row["LastName"] = textBoxLastName.Text; row["Gender"] = textBoxGender.Text; row["Age"] = textBoxAge.Text; row["Address"] = textBoxAddress.Text; dataSet.Tables["Students"].Rows.Add(row); try { int result = adapter.Update(dataSet, "Students"); if (result > 0) MessageBox.Show("Student successfully enrolled."); else MessageBox.Show("Failed to enroll student."); } catch (SqlException ex) { MessageBox.Show(ex.Message); } textBoxStudentID.Enabled = true; textBoxFirstName.Enabled = false; textBoxLastName.Enabled = false; textBoxGender.Enabled = false; textBoxAge.Enabled = false; textBoxAddress.Enabled = false; buttonShow.Enabled = true; buttonEdit.Enabled = true; buttonDelete.Enabled = true; insertReady = false; }

Example 3 The buttonAddNew will serve as a toggle button. The insertReady field will determine the action that this button will perform. Since insertReady is initially false, lines 5-18 will be executed.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Line 5 changes the text of the button to "Enroll" simply to notify the user that this button should be clicked once the details are entered. Line 6 calls a method that will clear all the fields if so it will be ready to accept new details from the user. The definition for the ClearFields() method is as follows:
private void ClearFields() { textBoxFirstName.Text = String.Empty; textBoxLastName.Text = String.Empty; textBoxGender.Text = String.Empty; textBoxAge.Text = String.Empty; textBoxAddress.Text = String.Empty; }

Example 4 Since we need will be adding a new student, we need to generate the next unique StudentID. We can't simply type a new student ID because the same student ID may already be in the database. That's why, line 7 calls another utility method called GetNextStudentID(). The defnition for this method is as follows:
private int GetNextStudentID() 1 { 2 command.CommandText = "SELECT IDENT_CURRENT('Students') + 3 IDENT_INCR('Students')"; 4 5 try 6 { 7 connection.Open(); 8 int nextID = Convert.ToInt32(command.ExecuteScalar()); 9 return nextID; 10 } 11 catch (SqlException ex) 12 { 13 MessageBox.Show(ex.Message); 14 } 15 finally 16 { 17 connection.Close(); 18 } 19 return 0; 20 }

Example 5 Line 3 creates an SQL Server command that will get the next Identity field value. Remember that the StudentID field of the Students table is an Identity field which auto increments when new records are added. The thing is, we can't simply get the last StudentID and add 1 because SQL server saves the last Identity value used so if we delete a record with StudentID 5, making the new last StudentID is 4, the next StudentID that will be generated will be 6. There is an SQL Server function called IDENT_CURRENT() which returns the current identity field and IDENT_INCR() which returns the increment value of the identity field. We passed the name of
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

the table to these functions and added their return values to get the latest StudentID. We open the connection in line 7 and line 8 uses the DbCommand.ExecuteScalar() since we are expecting a single value (not record) to be returned. The value is the generated last StudentID but we need to convert it first to integer. Finally, wer returned that value to the caller of the method (line 9). Note that this method used the connected approach for obtaining a single value. You can also retrieve the value using the disconnected way. Back to the code in Example 3, after getting a new StudentID, we simply display it using textBoxStudentID. Lines 9-14 enables the text boxes so the user can enter the details for the new student and lines 15-17 disables buttonShow, buttonInsert, and buttonDelete so the user can only click the "Enroll" button. Finally, line 18 changes the value of insertReady to true so the next time the user clicks this button, lines 22-60 will be executed instead. The first time the user clicks the buttonAddNew, the program is now ready to accept the information for the new student. After the user types the information for each field, the user should now then click the buttonAddNew again to execute the SQL INSERT command to the database. Let's now discuss lines 22-63 of Example 3 which does the actual communication to the database. Line 22 reverts back the label of the button to "Add New". Lines 24 changes the CommandText property of our Command object into a SELECT Statement that queries all records form the database.Line 25 resets the Tables property to remove any tables that might be there. Line 26 Fills the dataSet with all the records from the database table. Line 28 uses the DataTable.NewRow() method to create a DataRow with the same number of columns and type as the Row found in the Students table of the dataSet. If you will not use NewRow(), then you will need to manually create each column witch would be tedious. Lines 29-33 simply assigns the values in the text box to each column of the new row to be added.Line 35 adds the new row to the Rows collection of the Students table of the dataSet.Now all that is left is to submit the changes to the database. Inside a try block, we called the DbAdapter.Update() method and passed the dataSet and the name of the DataTable that contains the updated results. By calling this method, the corresponding INSERT statement is generated by CommandBuilder and then it is executed to the database. It returns an integer which indicates the number of rows that were successfully updated. We check its values in line 41 to determine if the insertion is successfull. Lines 51-52 reverts the textboxes and the buttons to their previous states and we switch back the insertReady flag to false. The buttonEdit also acts as a toggle button and most of the code is similar to the code of buttonAddNew.
1 private void buttonEdit_Click(object sender, EventArgs e) 2 { 3 if (!updateReady) 4 { 5 buttonEdit.Text = "Update"; 6 textBoxStudentID.Enabled = false; 7 textBoxFirstName.Enabled = true; 8 textBoxLastName.Enabled = true; 9 textBoxGender.Enabled = true; 10 textBoxAge.Enabled = true; 11 textBoxAddress.Enabled = true; 12 buttonShow.Enabled = false;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62}

buttonAddNew.Enabled = false; buttonDelete.Enabled = false; updateReady = true; } else { buttonEdit.Text = "Edit"; command.CommandText = "SELECT * FROM Students"; dataSet.Tables.Clear(); adapter.Fill(dataSet, "Students"); foreach (DataRow student in dataSet.Tables["Students"].Rows) { if (student["StudentID"].ToString() == textBoxStudentID.Text) { student["FirstName"] = textBoxFirstName.Text; student["LastName"] = textBoxLastName.Text; student["Gender"] = textBoxGender.Text; student["Age"] = textBoxAge.Text; student["Address"] = textBoxAddress.Text; } } try { int result = adapter.Update(dataSet, "Students"); if (result > 0) MessageBox.Show("Update successful."); else MessageBox.Show("Failed to update."); } catch (SqlException ex) { MessageBox.Show(ex.Message); } textBoxStudentID.Enabled = true; textBoxFirstName.Enabled = false; textBoxLastName.Enabled = false; textBoxGender.Enabled = false; textBoxAge.Enabled = false; textBoxAddress.Enabled = false; buttonShow.Enabled = true; buttonAddNew.Enabled = true; buttonDelete.Enabled = true; updateReady = false; }

Example 6 Clicking the buttonEdit for the first time will enable the text boxes and disable the buttons except the buttonEdit itself. We used the updateReady field to make the button toggle its functionality.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

After the changes has been made to the current student, clicking the button the second time will send the changes to the database. Lines 25-35 searches the student with the StudentID indicated in the textBoxStudentID. We did this using a foreach loop and we retrieve every row from the Students table of the dataSet. If the current retrieve row has a StudentID equal to the one in the textbox, then we update every field to whatever new value typed by the user in the text boxes. Finally, the buttonDelete's Click event handler is shown in Example 7.
private void buttonDelete_Click(object sender, EventArgs e) 111111111111111{ 2 command.CommandText = "SELECT * FROM Students"; 3 dataSet.Tables.Clear(); 4 adapter.Fill(dataSet, "Students"); 5 6 7 foreach (DataRow student in 8 dataSet.Tables["Students"].Rows) 9 { 10 if (student["StudentID"].ToString() == 11 textBoxStudentID.Text) 12 { 13 student.Delete(); 14 break; 15 } 16 } 17 18 try 19 { 20 int result = adapter.Update(dataSet, "Students"); 21 22 if (result > 0) 23 MessageBox.Show("Student successfully deleted."); 24 else 25 MessageBox.Show("Failed to delete student."); 26 } 27 catch (SqlException ex) 28 { 29 MessageBox.Show(ex.Message); 30 } 31 32 command.CommandText = "SELECT * FROM Students"; 33 adapter.Fill(dataSet, "Students"); }

Example 7 The code for deleting a row is simillar to updating in which we simply used a foreach loop to find the student to delete. If the row has a StudentID equal to the one indicated in the textBoxStudentID, then line 12 deletes that row using the Delete() method. We then exit the loop by using the break statement. Our simple enrollment system is now complete. To test it, run the program and type an existing StudentID in the first text box. Click the show button to see the student's information. If you
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

want to edit those information, you can click the buttonEdit, type the new values, and click buttonEdit again to save the changes. You can also delete that student by clicking buttonDelete. To add or enroll a new student, click the buttonAddNew and type the information of the new student into the fields. Click the buttonAddNew once more to add the student into the Students database table. Download Project: SimpleEnrollmentSystemDisconnected.rar

Connecting to an Access Database


You can use the classes in ADO.NET to connect to a Microsoft Access Database. We use the OLE DB data provider and the System.Data.OleDb namespace for an Access database. This tutorial shows you the steps in creating an access database and creating an application that connects to it. We will be using Microsoft Access 2007 version of Access. Open Access 2007, and in the home screen, click the Blank Database Icon. On the right side, you will be prompted to name the new database and indicate the location to where the database will be located. Name your database Members.accdb and you can choose any location you want, but for the sake of simplicity, this tutorial will place the file in the C:\ root directory. Click the Create button and you will be brought to Access' Datasheet View with a new table. You can start adding columns here, but it is easier to switch to Design View and add the columns/fields there so in the ribbon, click View and then Design View. Access will prompt you to name your table, name it Members. Once you are in the Design view, you can now add each fields. The default field you will see is the ID field and the data type is AutoNumber. Data types indicate the type of data that the field will store. You will also notice a key beside it. It means that this field will serve as the primary key. Primary key simply means that values in this field should be unique. The AutoNumber data type means that this field will be automatically filled by access as new records are added. An optional column, Description, simply shows the use of a certain field. You can leave it blank or add a usefull description about the purpose of the field. Now add the following fields to our table. Field Name Data Type FirstName Text LastName Text Age Number The Text data type indicates that the field is expected to hold a string or text while the Number data type holds numeric data (integers and floating-points). Once you added the fields, return to Datasheet View by going to View > DataSheet View. If you are prompted to save the table, do so. Add the following values to their respective fields. Note that the ID field will automatically be filled by Access. FirstName LastName Age
COMPILED BY: Bsc ABDULRAHIM ALI ATHUMAN

FirstName LastName Age John Smith 21 Mark Mayer 23 Alvin Minsky 27 Vince Roster 22 Ben Marcus 18 Ellise Fisher 25 Now that we have some records in our database, we can now create an Application that connects and gets the data from this database. But first, close Microsoft Access 2007 and be sure to save the data.

Querying Data From an Access Database


In this lesson, we create a simple form that queries and shows data of individual record from the Access database created in the last lesson. Open Visual Studio and create a new Windows Application. Name the project AccessConnection. Add three labels and three textboxes. Change the Text property of the labels to First Name, Last Name, and Age. Change the Name property of the TextBoxes to txtFirstName, txtLastName, and txtAge respectively. Add four buttons and change their text to First, Prev, Next, and Last. Change their Name property to btnFirst, btnPrev, btnNext, and btnLast. Your form should look like this:

Double click the actual form to generate an event handler for the form's Load event. The load event will contain the code that queries the values to the database and show the field values of the first record to their respective text boxes.
1 2 3 4 using using using using System; System.Windows.Forms; System.Data; System.Data.OleDb;

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

5 6 namespace AccessConnection 7 { 8 public partial class Form1 : Form 9 { 10 private OleDbConnection connection; 11 private OleDbCommand command; 12 private OleDbDataAdapter adapter; 13 private DataSet dataset; 14 private string firstname; 15 private string lastname; 16 private int age; 17 private int position; 18 19 public Form1() 20 { 21 InitializeComponent(); 22 } 23 24 private void Form1_Load(object sender, EventArgs e) 25 { 26 connection = new OleDbConnection(); 27 command = new OleDbCommand(); 28 adapter = new OleDbDataAdapter(); 29 dataset = new DataSet(); 30 31 connection.ConnectionString = 32 @"Provider=Microsoft.ACE.OLEDB.12.0;Data 33Source=C:\Members.accdb;" + 34 "Persist Security Info=False"; 35 36 command.Connection = connection; 37 command.CommandText = "SELECT * FROM Members"; 38 39 adapter.SelectCommand = command; 40 41 try 42 { 43 adapter.Fill(dataset, "Members"); 44 } 45 catch (OleDbException) 46 { 47 MessageBox.Show("Error occured while connecting to 48database."); 49 Application.Exit(); 50 } 51 52 ShowValuesOfRow(0); 53 } 54 55 private void ShowValuesOfRow(int pos) 56 { 57 DataRow row = dataset.Tables["Members"].Rows[pos]; 58 position = pos; 59 60 firstname = row["FirstName"].ToString(); 61 lastname = row["LastName"].ToString();

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

62 63 64 65 66 67 } }

age = (int)row["Age"]; txtFirstName.Text = firstname; txtLastName.Text = lastname; txtAge.Text = age.ToString(); }

Example 1 Notice that we use the System.Data.OleDb namespace. This namespace contains the classes that we will be needing to connect to our Access Database. The namespace System.Data contains the DataSet class which will holds the data retrieved from the database. We declared objects for the OleDbConnection (used for connecting to database), OleDbCommand (handles the sql command), OleDbDataAdapter (used to communicate to the database and retrive its values), the DataSet, and some fields to hold the values from the database. The position field will be used to monitor which record to show in the textbox. Inside the Load event handler of the Form, we initialized the objects neccessary to connect to the data source. We then set the ConnectionString property of the OleDbConnection class to the connection string of Access 2007. The connection string parameter Data Source specifies the path of the Access 2007 file in your system. We connect the OleDbConnection instance to the OleDbCommand through its Connection property. We also specified the SQL command through its CommandText property. The SQL command specifies the we should get all the rows and fields from the Members table. We set the SelectCommand property of the OleDbDataAdapter instance. We used the OleDbDataAdapter.Fill() method that executes the command in the SelectCommand property and put the data into the dataset with the specified table name. Enclosing the Fill() method in a try..catch handles any exception that might occur. We called the ShowValuesOfRow() method to show the values of the specified row or index. We passed 0 as an argument to show the values of the first row. Inside the method, we retrieve the specified row by accessing the Rows property of the Tables property of the DataSet object. We passed the name of the table(in this case "Members") as the key to the Tables property and the value of pos parameter as the index of the Rows property to get a specific row from the Members table. The result is stored to a DataRow object which represents a single row in a DataTable. The position is then adjusted. The values of each columns of the retrieved row is placed to their respective fields and the fields are placed to their respective text boxes. When you run the program, the form should display the first record.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Let's add functionality to the four buttons. Lets start with btnFirst. Double click the button the add an event handler to its Click event.
private void btnFirst_Click(object sender, EventArgs e) { ShowValuesOfRow(0); }

Example 2 The code simply calls the ShowValuesOfRow() method and passes 0 as an argument to display the first row. Double click btnLast and add the following code.
private void btnLast_Click(object sender, EventArgs e) { int lastIndex = dataset.Tables["Members"].Rows.Count - 1; ShowValuesOfRow(lastIndex); }

Example 3 The first line determines the index of the last record from the Members table. We called the ShowValuesOfRow() method and passed the last index to the method to display the last row's data. Double click the btnPrev button and add the following code.
private void btnPrev_Click(object sender, EventArgs e) { if (position > 0) { position--; ShowValuesOfRow(position); }

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Example 4 We first check if the position is greater than 0. This will prevent the program from querying a row located at an invalid index such as -1. Inside the if structure, we decrement the position and called the ShowValuesOfRow() passing the new position as the argument. Double click the btnNext button and add the following code.
private void btnNext_Click(object sender, EventArgs e) { int lastIndex = dataset.Tables["Members"].Rows.Count - 1; if (position < lastIndex) { position++; ShowValuesOfRow(position); } }

Example 5 We retrieve the last index of the rows and check if the position is less than the last index. This is also to prevent the program on retrieving an invalid index that will cause an IndexOutOfRange exception to be thrown. The position is incremented by 1 and the values of the new row is displayed. Now run the program. Clicking the First button displays the first record. Clicking the Last button displays the last record. Clicking the prev and next buttons will display the previous and next records. We can use the codes in this lesson to connect to an SQL Data Source. All we need to do is change the type of Provider. You also need to change the connection string to an SQL Server connection string.

Code to navigate between records


If you debugged your code you'll know the error. But first thing you should modify this
1. string cs = "user id=scott;password=tiger"; 2. cn = new OracleConnection(cs); 3. cn.Open(); 4. // MessageBox.Show("Oracle connection opened sucessfully"); 5. OracleDataAdapter da = null; 6. OracleCommandBuilder cmb = null; 7. da = new OracleDataAdapter("select * from dept", cn);

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

8. cmb = new OracleCommandBuilder(da); 9. ds = new DataSet(); 10. da.Fill(ds, "deptx"); 11. Rec_Max = ds.Tables["deptx"].Rows.Count; 12. NavigateRecords(inc); 13. cn.Close(); 14. cn.Dispose();

to
1. if(!Page.IsPostBack) 2. { 3. string cs = "user id=scott;password=tiger"; 4. cn = new OracleConnection(cs); 5. cn.Open(); 6. // MessageBox.Show("Oracle connection opened sucessfully"); 7. OracleDataAdapter da = null; 8. OracleCommandBuilder cmb = null; 9. da = new OracleDataAdapter("select * from dept", cn); 10. cmb = new OracleCommandBuilder(da); 11. ds = new DataSet(); 12. da.Fill(ds, "deptx"); 13. Rec_Max = ds.Tables["deptx"].Rows.Count; 14. NavigateRecords(inc); 15. cn.Close(); 16. cn.Dispose(); 17. }

MORE TUTORIALS COMING SOON

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

REFERENCE List of Reserved Keywords


The C# language has many reserved keywords that you cannot use as identifiers. The following is the full list of those reserved key words: abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual void volatile while The following are contextual keywords that are only treated as keywords at special events and locations. add alias ascending by descending equals from get global group into join let on orderby partial remove select set value var where yield

Operator Precedence Chart


Operator precedence determines which operators and expressions should be caculated first. The following is the full operator precedence chart of C#. Operators in the same row have the same

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

precedence. The associativity determines how to evaluate expressions having multiple operators with the same level of precedence. Operator Type Associativity . member access () method call [] element access ++ postfix increment -postfix decrement left-to-right new object creation typeof get the type of object sizeof get the size in bytes of a type checked checked evaluation unchecked unchecked evaluation + unary plus unary minus ! logical negation ~ bitwise not operator right-to-left ++ prefix increment -prefix decrement (type) casting * multiplication / division left-to-right % modulus/remainder + addition subtraction left-to-right << left shift operator >> right shift operator < less than > greater than <= less than or equal to left-to-right >= greater than or equal to is type comparison as type conversion != is not equal to left-to-right == is equal to & bitwise AND left-to-right ^ bitwise XOR left-to-right | bitwise OR left-to-right && logical AND left-to-right || logical OR left-to-right ?? null coalescing right-to-left ?: conditional right-to-left

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Operator = *= /= %= += -= <<= >>= &= ^= |=

Type assignment multiplication assignment division assignment modulus assignment addition assignment subtraction assignment left shift assignment right shift assignment bitwise AND assignment bitwise XOR assignment bitwise OR assignment

Associativity

right-to-left

Casing Styles in .NET


Three capitalization styles are used in C# and .NET. The PascalCasing , camelCasing and UPPERCASE. Pascal Casing starts with a capital letter followed by small letters. All succeeding words in Pascal Casing should also start with capital letters. Examples are TheNumber, MyCar, AnimalFarm. Camel Casing is simillar to Pascal Casing only that it starts its name with a small letter. Examples are theNumber, myCar, animalFarm. Uppercase means every character is written in uppercase such as PI or PRICE. Pascal Casing is used for:

Methods. All the methods in the .NET Framework are named using the Pascal Casing. If you are creating methods, use Pascal Casing as well. Although there is one exception. When naming event handlers for controls on a form in C#, the method usually starts with the name of the control (which starts with lower case) followed by an underscore and then the name of the event. Property. When naming a property, we usually follow the name of the private data member it references. For example, if you have a member called myName, we name the corresponding property with MyName. Class. Classes are also named using Pascal Casing. It is apparent on all the classes of the .NET Framework. Interface. When naming an interface, always precede it with a capital I followed by the name of the interface starting also with a capital letter. For example, If I want to make an interface named Clickable, I will name it IClickable. Namespaces. When you write your namespace, you should use Pascal Casing as well.

Camel Casing is used for:


Fields Method Variables Names of Controls in Windows Forms


Bsc ABDULRAHIM ALI ATHUMAN

COMPILED BY:

Method Parameters

Uppercase is used when writing constants.

Decimal to Binary Conversion


Binary numbers in the computer world are often grouped by 8 digits or bits to form 1 byte. To start converting a decimal number to binary, the first step is to reserve 8 blank slots and we will put binary numbers on each slot as we progress. Suppose that we want to convert the number 54 to binary:

Now, we need to remember a simple sequence. Binaries are base 2, so we use 2 as a base and raise it to a power starting with 0.

By getting the answer for each 1, we get the following.

Notice that we start with 1 and the next one is double its value which is 2. The following ones are just doubled values of their preceding values. With this values we can now get the binary equivalent of our decimal number. To start, find the highest number that does not exceed our current value whic is 54. In this case, 32. We place a 1 in the position where the 32 is located.

We now subtract 32 from 54 (54 - 32 = 22). Our current value is now 22. Repeat the step of finding the highest value that does not exceed our current value which is 22. The number 16 qualifies our condition so again, place a 1 where 16 is located.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

We then subtract 16 from 22 (22 - 16 = 6) making 6 our new current value. Find the largest number in the sequence that does not exceed six. 8 exceeds 6, so we should use 4 and place again a 1 in its position.

We subtract 4 from 6 (6 - 4 = 2) and we find the value that does not exceed our new current value 2. There's only one number in the sequence that does not exceed 2, and thats 2 itself. So place again 1 in its position. Subtracting 2 from our current value 2 results to 0. This time, we can now stop adding 1's.

The final process is placing 0's on all blank spaces.

We finally arrived to the binary equivalent of 54 which is 00110110. We can omit the leading 0's and write 110110 as the binary equivalent of 54. Please note that higher numbers require more bits (slots) for conversions. How can we know if a number fits 8 bits. Simply double the last number which is 128 and we get 256. All the number below 256 can be converted using 8 bits. If a decimal to convert is 256 or higher, then we need to add more bits when converting. For example, if we want to convert 312, then we will be needing 9 bits.

The value of the 9th bit is 28 or 256 which is simply a doubled value of its previous bit which is 128. 9 bits can only contain values below 512 which is twice the value of 256. Again, if you have a value equal or greater than 512, then you need to add again 1 more bits.

Binary to Decimal Conversion


Converting from binary to decimal is easy. You first need to know the positional values of each bit. Suppose we have a binary number 10100111 that we need to convert to decimal.

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Positional values starts from 20 which is 1 to 2n-1 where n is the number of bits or digits. Since we have 8 bits, the last positional value is 28-1 = 27 = 128. We write the positional values from right to left. Once we have determined the positional values, we simply add all the positional values that has 1 as its bit.

We now arrived at 167 as the final decimal answer for our binary number 10100111.

Converting Negative Numbers to Binary


Converting negative numbers to binary is not simple and can be confusing. C# and .NET uses Two's Complement Notation. To show how the Two's Complement Notation works, let's convert -7 to its binary equivalent. Suppose that -7 has given a type of int so it has 32-bits (32 binary digits).
int value = -7;

The first step is to convert a negative value to its positive value so -7 becomes +7 or simple 7. We then convert 7 to its binary representation.
7 = 00000000000000000000000000000111

The value 7 is equivalent to 111 in binary but assuming that we stored the value in an int variable, then it will have 32-bits that's why we add leading 0's to fill all 32 slots. After converting the negative number's positive equivalent to binary, we use one's complement to each bits. In C#, this is equivalent to using the bitwise NOT operator (~). Doing this operation simply reverses the value of each digit. So the binary representation of 7 when one's complement is used will become:
~7 = 11111111111111111111111111111000

To perform two's complement, simply add one the the new binary value.
11111111111111111111111111111000 + 00000000000000000000000000000001 ---------------------------------11111111111111111111111111111001

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

The result is the binary representation of -7. At first look, it won't seem like it realy is negative 7. That's why I said earlier that it can be confusing. I mean, if you will convert the final binary result to decimal using the techniques we have learned, you will arrive at value 4,294,967,289. But C# and .NET uses the leftmost bit as an indication of whether a number is positive or negative. It means, that if the leftmost bit is 1, then the number is considered negative, if it is 0, the number is considered positive. Therefore, when using int as the type, the 32nd bit is not included when calculating a values decimal value. After all 4,294,967,289 will not fit in an int variable. You should use long or uint instead. To prove that the final binary result is really -7. We can add it to the binary value of 7. The result should be 0 (-7 + 7 = 0).
11111111111111111111111111111001 + 00000000000000000000000000000111 ---------------------------------00000000000000000000000000000000

If you don't know how to add binaries, the following is the three possible combinations and their results.
1 + 0 = 1 0 + 1 = 1 1 + 1 = 0 carry 1

Since the first pair of digit is both 1, the first digit of the answer is 0 and 1 is carry over to the next column and so on until we reach the final column. In the final column there should still be one being carried over from the last column so the result is still 0 and we discard the 1 to be carried.

MORE TUTORIALS COMING SOON

COMPILED BY:

Bsc ABDULRAHIM ALI ATHUMAN

Você também pode gostar