Sunday, January 30, 2011

SQL 2005 - Column Data Types to Store Date Time, Integers, Strings, Real Numbers and Images

1. Introduction

SQL server provides a different kind of data types. Sometimes, confusion may arrive while making a correct choice among them. In this article, I will just cover different data types available in SQLServer. You need to know the data types and that will help you in designing the database more efficiently.

2. To Store Characters

  1. Char data type stores maximum of 8000.
  2. Varchar(Num) data type stores a variable length of characters.  Here the "num" states how much maximum allowed. If you specify varchar(10) then the maximum size allowed is 10 characters. This data type also shrinks the allocated space based on actual data. Say if you store “Server” in the column, which has the varchar(10), then the remaining 5 are given to the pool of memory, as it is not used.
  3. Text data type is capable of storing a large number of characters which is almost 2 billion. 
  4. Varchar(Max) data type acts same as the text data type. This data type is introduced in SQL Server 2005. You may wonder why it is introduced when already Text is there? You cannot use text data type directly in the SQL statements. One should use corresponding text data type manipulation like readtext. But, with Varchar(max), you can use it as part of your query without depending on the built-in functions for text manipulation

To Support Unicode characters just append ‘n’ with the above data types. Say if you need Unicode support for the char data type, the data type of your choice is nChar.

3. Numeric datatypes - Whole numbers

  1. The bit data type is used for the Boolean stuff. It can hold either 0 or 1.
  2. TinyInt data type is capable of storing 0 to 255 numbers.
  3. SmallInt data type is capable of storing the numbers up to 32K both on a positive and negative side.
  4. Int data type is capable of storing 0 – 2 billion. To store more than 2 billion you can use Bigint data type.

4. Numeric datatypes - Real Numbers

  1. You can use Real or Float data types to store the fractional numbers. Real data type takes 4 bytes and Float takes 8 bytes.
  2. Money is the data type, which supports to very big numbers. It can store upto nine trillions.
  3. Numeric data type allows you to specify how many bytes should be allocated for the decimal portion. For example Numeric(8,2) tells that total digits allowed are eight and in which two digits are for the decimal portion.

5. Date DataTypes

  1. DateTime data type is used to store both the date and the time. 4 bytes allocated for the actual date and 4 bytes allocated for the time.
  2. SmallDateTime data type is useful for storing the date and time that spans for short range say just for example 1950 to 2200 like 100 to 200 years. Totally 4 bytes consumed by this data type.

6. Binary datatypes

These data types are useful for storing the binary information. It can be the entire crystal report file in the form of binary format or raw bits of a photo image or whatever it is.

  1. Binary data type is fixed in size, consumes 8KB of memory.
  2. VarBinary(n) stores the allocated storage for the binary data specified by n bytes. Maximum of n is 8000
  3. Image data type is specially designed to store the Images.

Note: With an addition to the above data types, SQL programming constructs can use the types like TABLE, Cursor and XML.

[C#] - Project Properties With Example

Source Code : Download

1. Introduction

Here, I will explain some important project properties with examples. I will show you the following in this article:

  1. How do you set the Output path for your binaries?
  2. How do you set version and other file information to your output binary?
  3. How do you set Icon to your project?
  4. How do you conditionally compile some piece of code?
  5. How do you ask the compiler to skip some warning or treat a warning as an error?
  6. How do you use Pre-Build and Post-build events?
  7. How do you debug a dll and get a hit to the break point when the when the dll project in not part of the solution in which exe resides?

Hope, most you know all or some part of it. You can jump to separate section if you need. Let me start one by one. Before that, we need some preparation. That is we need some projects and code to explore the above said stuff.

2. Prepare the Projects

First open two instances of the visual studio 2005 and create a new Visual C# windows application in one VS2005 and Visual C# Class Library In the Other Vs2005. Now we have two projects and they does not belong to the same solution as you created it two separate VS2005 instances.

  1. Go to the "Class Library" project
  2. Change the class name to SMath
  3. Add the following piece of code

//001: Function added to add to numbers and
// Return a value
public int add_two_Numbers(int first, int second)
    //002: To hit the break point added some local variables, performed
    // calculation on the local variables
    int n1, n2;
    n1 = first;
    n2 = second;
    return (n1 + n2);

If I explain the above function in a big paragraph, I know you will definitely beat me J

Anyhow, I can say, this function exposed by our dll and it is going to be used by the Windows application.  I purposefully kept the local variables just to show you debugging and get a hit on the breakpoint.

4) Go to the "Windows Application" now
5) Design the form as shown below and set the properties by referring the attached sample application

3. Setting Output for the Projects

Now we have two separate projects. One will deliver the dll and the other one will deliver the exe. But, our exe is going to use dll to calculate the addition of two numbers. In Real world scenario, these projects will be grouped under single solution and build order is set to dll first and exe next.

Now we will do that manually. That is, whenever you do build, first build the Class library project and then exe.

1) Create a folder called output in your C: using windows explorer
2) Go to the Class Library project, move to solution explorer and double-click the properties icon which is usually above the References Icon
3) Select the output path to the folder created by you in step 1 using the folder browser button. The screenshot below shows the default path and you are overriding that default path to C:\Output. Now build the project and make sure the dll is delivered to C:\Output folder

4) Go to the Windows application project
5) Click on the Project | Add reference
6) Click on the Browse tab on the displayed dialog
7) Select the Dll delivered by the Class Library project and press the OK button.
8) Now add the following piece of code:

A: Using statement for the form

//000: Using the Class Libraray Dll
using SampleMath;

B: Add the following code on the Button event handler:

//001: Use the class from our library
SMath obj = new SMath();
int n1, n2;
string result;

//002: Call the function and display the result
n1 = int.Parse(txtNumber1.Text);
n2 = int.Parse(txtNumber2.Text);
lblResult.Text = obj.add_two_Numbers(n1, n2).ToString();

In the above code, we are using the class SMath exposed by our class library and making the call to the add_two_numbers. However, this is not the purpose of this article. You now already know how to set the output path. So, set the same output path for this Project also. Build the project and make sure the Exe is delivered to the same output path. This is how large solutions with plenty of projects in it deliverers the binaries to a single location.

4. Set Version and Other File Information

In the previous section, we set the binary delivery path to a single location. And, both the projects deliver their output to the C:\Output. Now we will set the version information for the Dll that will be delivered by the Class library project. Follow the below steps for setting the version information for the dll. You can use the same steps to set the version information for the Exe project.

  1. Go to the solution explorer view of the class library project
  2. Double-click the Properties as we did previously
  3. Click the application tab on the left side
  4. Click the Assembly Information… Button
  5. From the dialog displayed fill the information as shown below:

There is no explanation required on the above dialog as displays basic information.

6) Now re-build the Class Library.
7) Place the cursor on the dll name from the output path. You will get tool tip of the information that was set in the dialog shown above. Below is the screen shot of the tool tip

Oops. The screen shot of the dialog is old. I do set Company as but taken an old screen shot. OK. You can also see more detailed information by viewing the file properties. The second tab (version) has all the information we assigned. Do the same steps for the exe application also.

5. Setting Icon to the Exe project

Let us set the icon for our windows application project. Given below the steps required for it:

  1. Bring up the Project properties
  2. Select the Application tab
  3. In the resources group, there is radio button called Icon. Check the radio button and select an icon file using the folder browser dialog.
  4. Rebuild the Exe project. The exe file in the output folder now has the selected icon.

6. Conditional Compilation

Conditional compilation means compiler makes a decision whether it needs to compile some set of code or not. This kind of compilation can be done by marking the piece of code with a tag. Consider our exe application. When we click the Get Result button we do get the addition of two numbers in the result. Let is add the exclamation symbol at the end of the result based compiler tag.

First, add the following piece of code in the button click event handler at the end:

//003: These statements are conditionally compiled
#if COND
lblResult.Text += " !!!";

The COND is the tag that we can specify as a project property to make the value of COND to true. When the compiler translates the code it sees the #if evaluates to true and translates the code lblResult.text += “!!!”

Follow the below steps to inform the compiler to translate all the code tagged by COND:

  1. Bring up the Project properties page
  2. Go to the build tab
  3. Type COND in the Conditional compilation text box as shown below:

  1. Rebuild the solution
  2. And double click the exe.
  3. Now the addition will give the result with three exclamation symbol added at the end
  4. Now remove the COND from the above-shown dialog and rebuild the project. Run the exe and make sure exclamation not appear when you test the result.

The “#if” statement can be used anywhere in the project source code in multiple places with a tag to perform conditional compilation.

7. Adjusting the Warning level

When you compile the projects you may see some warning reported by the compilers. Warnings are not Errors. The compilers still do their job even though a warning is reported. So there is a way to inform the compiler to say, “You can skip this warning. I am not interested in it” or  “Hey. Treat this warning as an error. I (Developer) pay more interests to this kind of warnings”.

Consider the below piece of code which is taken from the button click event of our windows application:

//001: Use the class from our library
SMath obj = new SMath();
int n1, n2;
string result;

//002: Call the function and display the result
n1 = int.Parse(txtNumber1.Text);
n2 = int.Parse(txtNumber2.Text);
lblResult.Text = obj.add_two_Numbers(n1, n2).ToString();

Here, the variable result is declared and not used.  The compiler will give a warning on this as shown below:

The issues warning number is 168. Once you have this, you can inform compiler either to skip this warning or treat this warning as an error. Follow the steps below to treat this warning as error:

1) Open the project properties
2) In the build page, Under "Treat Warning as Error" group, Select "Specific Warning" radio button and place the number 168 in the input box.

3) Rebuild the project and see what happens. The compiler will inform variable not used as an error.

4) You skip this warning by placing the same number 168 in the text box "Suppress Warnings"

8. Pre-build and Post-build events

These are kind informing what should happen before the build starts and what should happen when it ends. People usually go ahead do some file copies on these events. To explain the usage of these events, we will display a notepad before the build starts and display the calculator when the build is finished. But, in the real world, it should the commands that help the build process.

  1. Bring up the project properties for the windows application project and click the build events tab.
  2. Type notepad in the pre-build text box and calc in the post build text box. 
  3. Start the rebuild and see what happens. Also, note that the build process waits until the notepad is closed. So in real world, if you perform some file copy in the pre-build, the build will wait for the operation to be completed. Once the build process is completed a calculator is displayed.

9. Debugging the Dll

Do you remember? We created the class library as a separate project. We can easily debug the dll when the exe project and the consumed dll both are in the same solution. If the dll is a separate project, like that in our case, we need a hosting exe to debug the dll.
  1. Go to the class library project. You cannot directly run this project, as the output is not an executable.
  2. Open the Project properties page
  3. Under the start, action browse and select our Windows Application project exe to populate the start external program text box. This tells that the exe uses the dll and the exe can be used to load the translated for the dll.
  4. Put a break point on the add_two_Numbers function and click the run button to get a hit on the break point.

Note: The sample is created in the VS 2005 IDE. If you have the latest version say yes to the conversion dialog box

Source Code : Download

Thursday, January 20, 2011

[ Dot Net Remoting ] - Serialization Explained

1. Introduction

In this article, we will explore the importance of the Serialisation and its attributes. For basic example on how to create dot net remoting read the previous article on dot net remoting. Here, we will explore the serialisation by creating two-console application one for the server and the other one is for the client. OK. Let us start.

2. IPurchase Interface for Server

First, start a console application and then provide a reference to the System.Runtime.Remoting reference to your application. Once this is done, right-click the project and select the Add|New Item from the context menu. Select the interface Icon, name the file as IPurchase.cs and click ok.

Add the following piece of code:

//Server_001: Interface on the Server
public interface IPurchase
    PurchaseInfo GetPurchaseInfo();

Here, the interface has a function called GetPurchaseInfo, which return an object PurchaseInfo to the caller. The purchase that we will implement is a serializable object. Also, we will set some attributes to it, which we will see later when we implement it. The remote object will implement this interface. So we have three parts. An interface, implemented by the remote object returns the serialised object to the remote client.

3. The PurchaseRem remote class for Server

Now add a class PurchaseRem to your Server project. This class is derived from MarshalByRefObject as well as the previously created interface. The implemented interface function just creates an object of PurchaseInfo and returns it back to the remote client. Below is the code for it:

//Server_002: Remote object on the Server side.
public class PurchaseRem : MarshalByRefObject , IPurchase 
    //Server_003: Constructor
    public PurchaseRem()
        Console.WriteLine("Remote Object Created");
    //Server_004: Implement the IPurchase Contract.
    public PurchaseInfo GetPurchaseInfo()
        return new PurchaseInfo();

4. Hosting the remote object on Server

I will cover implementing the PurchaseInfo class in the next section. Before that, we will go ahead and host our remote object on the server. This portion also already explained in the previous article and I do not want to repeat everything here once again.

Below is the code for required namespace inclusion:

//Server_005: Remoting Namespaces required for the Server
using System.Runtime;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

The code below registers the remote object and waits for servicing the client:

//Server_006: Allocate the TCP channel 12000
TcpServerChannel channel = new TcpServerChannel(12000);
ChannelServices.RegisterChannel(channel, false);

//Server_007: Register the class that implements IPurchase
RemotingConfiguration.RegisterWellKnownServiceType(typeof(PurchaseRem), "IPurchase", WellKnownObjectMode.SingleCall);

//Server_008: Break the Server from Exit
System.Console.WriteLine("Press Any Key to Halt the server");

Note that at tag 007: We registered the Remote object with the name of the interface.

5. Implementation PurchaseInfo class on server

1) Add a class called PurchaseInfo to your project. Then include the namespace required for the serialisation. As you know, this is the class we are going to implement serialisation and its attributes. Below is the code:

//Server 017: Namespace for Serialization
using System.Runtime.Serialization;

2) Mark the class serializable by defining the first attribute Serializable. Below is code change:

//Server 009: Make Purchaseinfo class serializable
public class PurchaseInfo

3) Next set of private variables is declared. To avoid database, I kept these variables (Too many you may think) so that the information is retrieved from the server based on the given id. Below is the declaration:

//Server 010: Private Variables
private string Customer_id1;
private string Customer_Name1;
private string Purchase_Made1;
private string Customer_country1;

private string Customer_id2;
private string Customer_Name2;
private string Purchase_Made2;
private string Customer_country2;

4) The constructor sets hard coded values for these variables. The aim is to explore the serialisation technique and so do not worry about the coding standard. Below is the code:

//Server 011: Constructor to hard code variables.
public PurchaseInfo()
    Customer_id1 = "100";
    Customer_Name1 = "Peter John";
    Purchase_Made1 = "120";
    Customer_country1 = "USA";
    Customer_id2 = "101";
    Customer_Name2 = "Susie Marie";
    Purchase_Made2 = "110";
    Customer_country2 = "Englang";

    Console.WriteLine("Purchase Info Initialized...");

5) The function GetPrchaseInfo takes customer id as a string and then compares the id with the hard coded value (in the previous step) to retrieve the required information. The information is returned as a string. Below is the code for this function:

//Server 012: Get the Purchase information for the customer based on the customer id supplied
public string GetPurchaseInfo(string CustId)
    string return_str;
    if (CustId == Customer_id1)
        return_str = Customer_Name1 + " Purchased " + Purchase_Made1 + " Books from " + Customer_country1;
    else if (CustId == Customer_id2)
        return_str = Customer_Name2 + " Purchased " + Purchase_Made2 + " Books from " + Customer_country2;
        return_str = "Customer with that id does not exists";
    Console.WriteLine("Purchase Info Retrieved for {0}", CustId);
    return return_str;

By looking the above code you may say the Id is passed from the client to server and the server returns the information that corresponds to the supplied id.  If you say that then you are wrong. Note that the class is not a remote class. It is a serializable class. From the previous two statements, the class object is sent as a stream to the client. The process of converting the object into bit stream is called Serializing. The process of converting the bit stream to a meaningful object back is de-serializing.

If you remember the GetPurchaseInfo method (Don’t remember J. OK. Look at section 3) of our remote object returns the class that we are implementing now. This function call will perform serialisation at the server and de-serialization at the client end. So the client gets the object back and the call to GetPurchaseInfo (Serializable class. I kept the same function name. ) method of PurchaseInfo class is going to happen in the object in the client itself. Hope, you got the justification that passed in customer id and the return value does not need to be transmitted between server and client. This is explained in the below picture:

6) There are four attributes, which provides you with the way to make changes on the data member of the serialised class. These attributes are: [OnDeserializing()],[OnDeserialized()],[OnSerializing()],[OnSerialized()]

The attribute names are self-explained. For example, OnSerializing means when serialising is going on.. that is, when packing the class object into bit streams. OnSerialized means, after the serialisation (Packing into bit stream), is completed. These attributes can be applied to a function so that the function acts as an event handler. If you mark the function say abc() with an attribute OnSerialized, the function will get called after the sterilisation of the class is completed.

Below is the four functions applied with the above said four serialising attributes.

//Server 013: This routine is called when server is on the way of deserializing [Unpacking]
public void OnDeserializing(StreamingContext cont)
    Console.WriteLine("Un-Packing the data to process");

//Server 014: This routine is called when the Server finished Unpacking.
public void OnDeserialized(StreamingContext cont)
    Console.WriteLine("Data un-packed");

//Server 015: This routine is called when the Server is doing the Serialisation [Packing]
public void OnSerializing(StreamingContext cont)
    Console.WriteLine("Packing the data to deliver");

//Server 016: Routine called when the server finished packing the data.
public void OnSerialized(StreamingContext cont)
    Console.WriteLine("Data packed");

6. Preparing the Client Application

Now let us start the client application. Add new Visual C# Console application to our existing server console project. Then add the server project as a reference. If you are a beginner, you can see the steps for this in my previous article on remoting. Once the project is added place the following code on the application startup. Again, this is the same step discussed in the previous article. Read it Here

//Client_002: Get hold of remote object reference through interface
ChannelServices.RegisterChannel(new TcpClientChannel(), false);
IPurchase purchase = (IPurchase)(Activator.GetObject(

//Client_003: Get the Serialized Object.
PurchaseInfo pinfo = purchase.GetPurchaseInfo();
Console.WriteLine("Press Any key to close the client..");

Note the usage of the interface IPurchase. Remember that the remote object also implements the IPurchase interface. Once we have the interface for the remote object, we use that to get the serialised object PurchaseInfo using the call to the interface function GetPurchaseInfo.
 Let us explore the function calls purchase.GetPurchaseInfo(); and pinfo.GetPurchaseInfo("101").

The interface reference purchase is a proxy on the client for the actual object created and resides on the server. The call through the proxy interface reference, ( Call GetPurchaseInfo) triggers the remote object to create an instance of PurchaseInfo. And this PurchaseInfo will be sent to the Client. Note the object is serialised on the server, the bit stream is sent to the client, and the client deserializes the bit stream to get the actual object. In our case, we got the object referred by pinfo like that.  Then, the call to the function GetPurchaseInfo happens in the client itself as we have the object in the client.

In Summary, from the above client code:
1) The object PurchaseRem resides on the server
2) Based on the interface function, the server creates PurchaseInfo object, Packs it as a bit stream, sent it to the client.
3) Client unpacks the bit stream to get the object. So PurchaseInfo resides on client before making a call to GetPurchaseInfo(Id)
4) The serialisation process takes place on Server
5) The DeSerialization process takes place on the client machine.

7) Running the Application

1) From your build output, run the Server executable first
2) Then run the client application exe
3) You will see the following output

Note the output marked by numbers 1,2,3,4. All the Console.Writeline statement is kept in the PurchaseInfo serialised object. But 1 and 2 displayed in the server and 3,4 displayed at the statement. Watch those statements in the Server application and you will get clear knowledge on how serialisation is performed and the usage of the serialising attributes discussed in this article.

Note: The App is developed in VS2005 IDE. If you have the latest version of IDE, say OK to the conversion dialog. Read the Basic Article on Dot net remoting by following the link through in the sidebar labels.

Source Code : Download

[ASP.Net] - Use SQlDataSource on pages

1. Introduction

In this article, we are going to see how we use the SQLDataSource server side control. Also, we will have a look at Grid that displays the table rows. Have a look at the below page:

The combo box is displaying the publisher's name from publishers table of the pubs database. The grid displays the employee names of the selected publishers. We are going to do that without writing any single piece of code. Download the videos which visually describes the steps and you if have enough experience those videos are not required.

2. Pubs and NorthWnd Db [Video: 001_SetupDB.avi]

The downloaded source code has two SQL scripts one for the Pubs database and the other one for NorthWnd Database. Launch your SQL Server 2005 and run these scripts in the query editor window. One you are done, you had both Pubs and NorthWnd database with you. This example uses the Pubs database.

Beginners: Watch the video 001 for the first step.

3. Create a New Website [Video: 002_NewSolution.avi]

Create a new website and name it DataSource. I hope almost everybody knows this step. However, this step also captured as video and you can refer it to know how to create a new Website.

4. Add DataSource control and Configure [Video: 003_AddDataSource.avi]

1) First, we need a way to connect to the pubs database. We can do that by using the SQLDatasource control. From the toolbox expand the data group. You will find SQLDatasource from the expanded node. Drag and drop the control in the Design area of the web form. This is an invisible control. Once placed access the Quick Task menu by clicking the small arrow button at the top and the select the link Configure Data Source. The below Picture is shown for guiding.

2) This will bring chose you data connection. Click the New Connection button as we are going to create a connection to the SQL Server database to connect the Pubs database. In the Add Connection dialog type the server name where the database pubs are running. In my case it is localhost. Then after giving the SQL authentication username and password (sa account) select the pubs database from the database list. Click OK once you selected the Pubs database.

3) Once this done, move to the next step in the wizard by clicking the Next button. Change the connection string to ConnectionStr and click the next button. The check mark allows you to save the connection string to the web configuration file. Click next to proceed.

4) Now you are in Configure Select Statement step. First, select the Publishers table from the Name Combobox. This is the table that will populate the publishers’ name in the combo box of our example. Once the publishers table is selected the list of columns is displayed in the below list box below the combo box. Select pubid and pubname in the columns then click on the finish button.

Now we configured the SQLDataSource to get the required information for the combobox from the Publishers table of the pubs database. All these steps are visually covered in the Step 003 video.

5. Combobox with Publishers [Video: 004_AddCombobox.avi]

Here, we will add a ComboBox to our web form and link that combo box to the previously created Datasource control. Expand the standard toolbox and drag and drop the Dropdown list control to the Web form. Then from the Quick Task select the Auto Post back option. The combo box will inform the grid to show the list of employees those belongs to the selected publishers. So when we make a change in the Combo box selection the changed data is sent to the Server from the client machine and server will take the appropriate action.

Select Chose datasource from the quick task. From the dialog displayed select the datasource created in the previous step and select the fields as shown in the below picture. So, now the combo box displays the publishers name and sends the publisher id to the server.

6. Adding Grid view for Employee display [Video: 005_AddDataGrid.avi, 005a]

1) Our combobox is ready! We need to set up the Grid view control for the Employee table. From the view, menu brings up the server explorer. If the data connection is not available in the server explorer create the one to our Pubs database. Once the connection is created expand the table folder and drag&drop the employee table to the design surface. Using the quick text menu set the auto format style that you like

2) From the Quick task menu, select the "Configure DataSource" menu option.   From the displayed dialog select the connection string that was already configured by us. That means, Select ConnectionStr. Click next, select the employee table and select the columns except job_id and job_lvl.

3) Click the where clause button. The dialog shown below is displayed:

Perform all the six steps shown in the dialog box. Here we have added the where condition to the Employee selection used by the grid view. Here, the where condition is dynamically changed by the combo box item publisher. Look at the SQL Expression: [Pub_id] = @pub_id. The @pub_id is the value passed to the server by the combo as it has the auto box set already. Remember, the display field of the combo box is Publisher name. But, actual value it stored along with that is publisher id. So when we select a different publisher name in the combo box, the publisher id is sent to the server. Here, @pud_id has referred such an id.

4) From the Quick list select Edit Columns options, and from the displayed dialog select the fields from the available fields list and add it to the Selected field list box. The dialog is shown below. Selected fields are the one that displayed in the Grid view.

7) Run the Web page [Video: 006_RunApp.avi]

1) Right-Click the default.aspx (if the name is not changed) and right click on it.
2) Select View in Browser option.
3) From the displayed page, select different publishers.

1) The application is created on VS 2005 IDE if you have latest version say OK to the conversion dialog.
2) The video is attached to the external source. Click here to download the videos. The download is RAR archive; unzip it to get all the videos. You need WinRAR application to unzip the files. I do have a version downloaded from 4shared.
3) View the videos in Windows media player with the full-screen option and 1024x768 resolution.

Supporting videos for this article: Download

Source Code : Download

[C#] - Stream Reader, Stream Writer and OpenFileDialog, FolderBrowserDialog

1. Introduction

Here you will see how to use File open dialog and folder select dialogs. Also, you will see how do we use "StreamReader" and "StreamWriter" class. We also are going to use Path utility class, which has a static function to phrase the string that comes in the form of a file path.

Before we start have look at the picture below which was taken when the form is running:

How it Works

When you click the … button, a file open dialog is displayed asking you to select Bmp or Jpg image file or a text file. If you select a file other than the above-specified three formats, an error will be displayed and file open dialog still stays to select a different file. When a text file is selected it will displayed in the top portion of the dialog. This is shown in the above screen shot. When you select a bmp or jpg file the selected image is displayed instead of the text.

The Save File button will save whatever text content displayed in the multiple line textbox. It takes the file name from the Save File Name textbox and saves that in the text format. Before saving, it will ask you select the folder by displaying the Folder Select dialog. Once the file is saved, the saved location shown below in a label. Save in Temp Path saves the file in the system temporary path.

OK. Let us start developing it.

2. Design the Form

Start a Visual C# Windows application. Then design the form by taking the guidance from the previous section. From the downloaded solution (Visual studio 2005) have a look at each control’s properties changed from the default (The bold values in the property window).

Below is the short guidance:

The "OpenFileDialog" and "FolderBrowserdialog" are available under the dialogs group in your toolbox. Drag and drop those controls to the form. And these controls are shown below the form on you dropped it. As it is not a visual control it will not appear in the form.

Place text box as shown in the picture, set the multiline property to true then resize the text box. Place a PictureBox control on top of the text box control and resize it to the same size of the text box. I hope all other control and its placement can be done easily. Let us go to the coding part: You can explore coding steps by searching the tag: //File 0

3. The System.IO namespace

This name space is used to access all the functionality packed towards the Windows file system. This article makes use of "FileStream", "StreamReader", "StreamWriter" and Path class from the IO name space.

So first include this Name space in the form code:

//File 000: Name space required for accessing the Path utility and other file related
// classes.
using System.IO;

4. File open Event Handler

In this event handler, first, the filters to the File open dialog is set using the "filter property". This property controls what file type a user can select. In our case, it is a bitmap, jpg and text files. However, a just kept all files as also as an option. Once the filter is set, the dialog can be opened using the "Showdialog method". And the return value constant tells whether the user selected a file and clicked ok or not. In the filter property, we set the supported file types in pairs. For example for text files: Text Files(*.txt) | *.txt

//File 001: Use File open dialog to get the file name
private void btnFileOpen_Click(object sender, EventArgs e)
    //001: Check the user selected a file and pressed ok button. Before opening the dialog
    //      set the filters
    dlgFileOpen.Filter = "Bitmap Files(*.bmp)|*.bmp|Other Image Files(*.jpg)|*.jpg|" +
        "Text Files(*.txt) | *.txt|All Files(*.*)|*.*";
    if (dlgFileOpen.ShowDialog() == DialogResult.OK)

Note: All file in the filter is intentional to explain you one of the important event on the FileOpen dialog.

Then using the Path utility class’s GetExtension method, the extension of the selected file is extracted. When the extension is not txt we are loading the image file using the "Picturebox control". The Filename property of the file open dialog will have the selected file name. And that property is referred in the picture box’s load method call.  The code is shown below:
if (dlgFileOpen.ShowDialog() == DialogResult.OK)
txtSelectedFile.Text = dlgFileOpen.FileName;
string ext = Path.GetExtension(dlgFileOpen.FileName);

if (ext != ".txt")
    //002: If the extension is Bmp or Jpg display it in the Picture box
    txtFileContent.Visible = false;
    pict.Visible = true;
    pict.SizeMode = PictureBoxSizeMode.StretchImage;

The else portion clearly says that the selected file is a text file. And, here, construct the StreamReader object by passing the FileStream to the selected text file to the constructor of the stream reader object. The stream object has the ability to read the stream in the form of the text strings. Once we have the stream reader, we read each line of text and display it the multi-select text box. Below is the code:

    //003: The extension is txt. Read the file and display the content
    txtFileContent.Visible = true;
    pict.Visible = false;
    FileStream fstream = new FileStream(dlgFileOpen.FileName, FileMode.Open);
    StreamReader reader = new StreamReader(fstream);
    while (reader.EndOfStream != true)

5. FileOk event handler

I can read some of your minds thinking, “In the previous step this guy sets all files as part of the filter option… and what happens if I select a file that does not fall on any of bmp, txt or jpg file type category?”. It will fall in the first portion of if statement and tries to load the file in the picture box getting exception complaints on not a valid image file.

So how do we avoid it? It is simple; remove that last pair in the filter. OK. Anyhow, I kept it to explain the "FileOK handler". The FileOK event will be raised once you select the file using the file open dialog. To have a handler on it, select the OpenFileDialog component:

Then using the property window, double click on the FileOK event (Select the event Icon button first in the Property window). The code the handler is can be easily understood and it is shown below:

//File 002: Use the Path object to determine the selected file has the
// required extension.
private void dlgFileOpen_FileOk(object sender, CancelEventArgs e)
    //001: Get the File extension and test that it falls on required extension
    string Required_Ext = ".txt .bmp .jpg";
    string selected_ext = Path.GetExtension(dlgFileOpen.FileName);
    int index = Required_Ext.IndexOf(selected_ext);
    //002: Inform the user to select correct extension
    if (index < 0)
        MessageBox.Show("Extension Maaaan... Extension! Open only txt or bmp or jpg");
        e.Cancel = true;

6. Stream Writer

In the previous part we saw how to use FileOpen dialog and then read the text content using the StreamReader object. Also we saw an important FileOK event handler where we can to validation for the selected file. This article is the continuation of the previous article, but you can still read it and know the usage of the Folder open dialog and StreamWriter object.

The screen shot is shown here for the continuation.

7. Save File button Handler

1) First, drag and drop the FolderBrowserDialog component (Control) from the toolbox to the form. Set the properties for the control by referring the downloaded application. This component can be found under the dialogs group in your toolbox. Once this is done provide the handler for Save File button.

The description property of the FolderBrowserDialog set the heading for the dialog. You can place an informative text to help the user to make their folder selection. As we are going to save the text file under the selected folder, I kept the text relevant to that. The "RootFolder property" is used to set the topmost node of tree display of the directory. Below is the code:

//001: Setup the Folder dialog properties before the display
string selected_path = "";
dlgFolder.Description = "Select a Folder for Saving the text file";
dlgFolder.RootFolder = Environment.SpecialFolder.MyComputer;

2) Once the RootFolder for the Folder dialog is set, display the dialog using the "ShowDialog() method". The return value is tested to tell, how the dialog closed by the end user. Once we make sure a folder is selected and clicking the OK button closed the dialog, we store the selected folder under a local variable using the "SelectedPath property" of the FolderBrowserDialog.

//002: Display the dialog for folder selection
if (dlgFolder.ShowDialog() == DialogResult.OK)
    selected_path = dlgFolder.SelectedPath;
    if (string.IsNullOrEmpty(selected_path) == true)
        MessageBox.Show("Unable to save. No Folder Selected.");

3) Finally, we make sure the displayed content is text. And make a call to the SaveFile function written for this form. The function accepts the path as parameter and then saves the file in the specified path by taking the file name from the relevant text box.

//003: Perform the File saving operation. Make sure text file is displayed before saving.
if (txtFileContent.Visible == true)
    MessageBox.Show("This form saves only text files");

4) The SaveFile() function first checks the selected path is a root folder (Partition itself. Ex: C:\ or D:\). And based on the test appends a slash at the end of the path. (Debug it to see why?). Then a FileStream object for the given file is created with the path selected by the folder dialog. Note that, this time in the constructor for the FileStream we asked to create a new file using FileMode.CreateNew enumerated constant. Once the FileStream is ready is connected to the StreamWriter for the writing the text content displayed in the multi-select text box. Using the "Write() method" on the StreamWriter entire content of the Multi-line textbox is written in the Specified text file. The saved path is displayed in the Label at the bottom of the form.

//File 005: Save the File to Disk
private void SaveFile(string selected_path)
    string Save_File;
    if (selected_path.Length > 3)
        Save_File = selected_path + "\\" + txtSaveFile.Text + ".txt";
        Save_File = selected_path + txtSaveFile.Text + ".txt";
    FileStream fstream = new FileStream(Save_File, FileMode.CreateNew);
    StreamWriter writer = new StreamWriter(fstream);
    lblSavedLocation.Text = "Text File Saved in " + Save_File;

8. Save in Temp Path Handler

This button handler just makes a call to the SaveFile function by passing the system’s temporary path. The "GetTempPath() method" of the utility class Path will return the temporary path. Hope, no more explanation is required for this simple function.

//File 004: Save the File in System Temporary path
private void btnTempPath_Click(object sender, EventArgs e)
    if (txtFileContent.Visible == true)
        MessageBox.Show("This form saves only text files");

Note: The application is created in Visual Studio 2005. If you have latest IDE say “Yes” conversion Wizard/Dialog that appears. To know how the Form works read the previous part also.

Source Code : Download
Like this site? Tell it to your Firend :)