Monday, August 25, 2008

Serialization

Before we begin with main program let us now see how to attach a menu to a blank form. Carry out the following steps:

  1. Drag in the 'MainMenu' control from the toolbox and release it on the blank form.

  2. Click on the control and type the menu item name as 'File'.

  3. Add the items 'New', 'Open', 'Save', 'Generate' and 'Exit' to the 'File' menu in a similar manner.

The resultant form is shown in the following figure.

Each menu item is governed by a control variable of the type MenuItem. We can change the names of these variables through the 'Properties' window. For the program that follows we have used the names as filemenu that will hold the other menu items, newmenu, openmenu, savemenu, generatemenu and exitmenu.

Let us now decide what should happen when these menu items are selected. When we select the �Generate� menu item, shapes like rectangle, ellipse and line should get generated at random and in random colors. On selecting the �Save� menu item these shapes should be saved in a file. We must be able to load this file and display the shapes again. This would be achieved through the �Open� menu item. When we click the �New� menu item the earlier shapes should vanish and we must get a new form to draw new shapes.

While saving the shapes we should not save the image of the shape. Instead we should save the relevant information of the shape using which we should be able to regenerate the shape again when the file is loaded. This means we must write the object onto the disk while saving it and load it back while opening the file. This process of writing the state of an object is called serialization and reading it back is called deserialization.

To make all these activities to happen we need to add handlers for these menu items. The Windows Forms programming model is event based. When we click on a menu item it raises an event. In order to handle an event, our application should register an event-handling method. For adding these handlers click on the menu item for which we wish to add the handler. Then go to the 'Properties' window and select the 'Events' tab (shown by a yellow lightening icon). From the list of events select 'Click'. As a result an event handler called say, openmenu_Click( ) would get added to our code. On similar lines rest of the handlers can be added. All these handlers will get added to the Form1 class, which is the default class name.

Before we add code to these menu handlers let us insert four new classes. The first amongst these is an abstract class called shapes. In this class we will store the color of the shape in variables r, g, b, representing red, green and blue components of the color. The other three classes that we would add are line, rectangle and ellipse. These classes are derived from the shapes class. In these classes we will store the coordinates of the shapes. Each of these three classes would have a constructor to initialize the data members. Each class would have a function draw( ) which would contain the logic to draw the respective shape. This function would be declared as abstract in the base class shapes. To make all the classes capable of carrying out serialization/deserialization we need to add the attribute Serializable as shown in the program listing given below.

using System ;
using System.Drawing ;
using System.Collections ;
using System.ComponentModel ;
using System.Windows.Forms ;
using System.Data ;
using System.IO ;
using System.Threading ;
using System.Runtime.Serialization ;
using System.Runtime.Serialization.Formatters.Binary;

namespace myapp
{

[Serializable]
abstract class shapes

{

protected int r, g, b ;
Random rd = new Random( ) ;
public shapes( )
{

r = rd.Next ( 255 ) ;
g = rd.Next ( 255 ) ;
b = rd.Next ( 255 ) ;

// put the thread to sleep for next 5
// milliseconds to ensure proper color
// generation
Thread.Sleep ( 5 ) ;

}

public abstract void draw ( Graphics g ) ;

}

[Serializable]
class line : shapes
{

int x1, y1 ;
int x2, y2 ;

public line ( int i, int j, int k, int l )
{

x1 = i ;
y1 = j ;
x2 = k ;
y2 = l ;

}

public override void draw ( Graphics gg )
{

Color c = Color.FromArgb ( r, g, b ) ;
Pen p = new Pen ( c, 4 ) ;
gg.DrawLine ( p, x1, y1, x2, y2 ) ;

}

}

[Serializable]
class rectangle : shapes
{

int x1, y1 ;
int width, height ;

public rectangle ( int x, int y, int h, int w )
{

x1 = x ;
y1 = y ;
height = h ;
width = w ;

}

public override void draw ( Graphics gg )
{

Color c = Color.FromArgb ( r, g, b ) ;
Pen p = new Pen ( c, 4 ) ;
gg.DrawRectangle ( p, x1, y1, width, height ) ;

}

}

[Serializable]
class ellipse : shapes
{

int x1, y1 ;
int width, height ;

public ellipse ( int x, int y, int h, int w )
{

x1 = x ;
y1 = y ;
height = h ;
width = w ;

}

public override void draw ( Graphics gg )
{

Color c = Color.FromArgb ( r, g, b ) ;
Pen p = new Pen ( c, 4 ) ;
gg.DrawEllipse ( p, x1, y1, width, height ) ;

}

public class Form1 : System.Windows.Forms.Form
{

private System.Windows.Forms.MainMenu
mainMenu1 ;
private System.Windows.Forms.MenuItem
filemenu ;
private System.Windows.Forms.MenuItem
newmenu ;
private System.Windows.Forms.MenuItem
openmenu ;
private System.Windows.Forms.MenuItem
savemenu ;
private System.Windows.Forms.MenuItem
generatemenu ;
private System.Windows.Forms.MenuItem
exitmenu ;
private System.ComponentModel.Container
components = null ;
ArrayList s = new ArrayList( ) ;
BinaryFormatter b = new BinaryFormatter ( ) ;

public Form1( )

{

InitializeComponent( ) ;

}

protected override void Dispose ( bool disposing )

{

if( disposing )

{

if ( components != null )
{

components.Dispose( ) ;

}

}

base.Dispose( disposing ) ;

}

[STAThread]

static void Main( )

{

Application.Run ( new Form1 ( ) ) ;

}

private void openmenu_Click ( object sender, System.EventArgs e )
{

OpenFileDialog od = new
OpenFileDialog( ) ;
od.Filter = "dat files ( *.dat )|*.dat" ;

if ( od.ShowDialog( ) == DialogResult.OK )
{

FileInfo f=new FileInfo ( od.FileName);
Stream st = f.Open ( FileMode.Open );

while ( st.Position != st.Length )

s.Add ( b.Deserialize ( st ) ) ;

st.Close ( ) ;

}

Invalidate( ) ;

}

private void savemenu_Click ( object sender, System.EventArgs e )

{

SaveFileDialog sd = new
SaveFileDialog( );
sd.Filter = "dat files ( *.dat ) | *.dat" ;

if ( sd.ShowDialog( ) == DialogResult.OK )
{

FileInfo f = new FileInfo(sd.FileName);
Stream st = f.Open ( FileMode.Create,
FileAccess.ReadWrite ) ;
foreach ( shapes ss in s )
b.Serialize ( st, ss ) ;

st.Close ( ) ;

}

}

private void generatemenu_Click ( object sender, System.EventArgs e )
{

Size sz = ClientSize ;
Random rd = new Random( ) ;

for ( int i = 0 ; i < 10 ; i++ )
{

int shapeno = rd.Next ( 3 ) ;
int x1 = rd.Next ( sz.Width ) ;
int y1 = rd.Next ( sz.Height ) ;
int x2 = rd.Next ( sz.Height - y1 ) ;
int y2 = rd.Next ( sz.Width - x1 ) ;

switch ( shapeno )
{

case 0:

s.Add ( new line ( x1, y1, x2, y2 ) ) ;
break ;

case 1:

s.Add ( new rectangle ( x1, y1, x2, y2 ) ) ;
break ;

case 2:

s.Add ( new ellipse ( x1, y1, x2, y2 ) ) ;
break ;

}

}

Invalidate( ) ;

}

private void exitmenu_Click ( object sender, System.EventArgs e )

{

Dispose( ) ;

}

private void Form1_Paint ( object sender,
System.Windows.Forms.PaintEventArgs e )
{

Graphics g = e.Graphics ;
foreach ( shapes ss in s )
ss.draw ( g ) ;

}

private void newmenu_Click ( object sender, System.EventArgs e )
{

s.Clear( ) ;
Invalidate( ) ;

}

}

}

When we click the �Generate� menu item its handler gets called. In this handler an object of the Random class is created. The Next( ) method of this class generates a positive random number less than the specified number passed to it.

We have used this function to not only decide which shape should be generated but also the coordinates of this shape. Using these coordinates we have created an object of rectangle, ellipse or line class. While creating these objects the constructors of the respective classes get called. Since all these classes are derived from the shapes class, firstly the base class constructor gets called. This constructor selects a random color.

The references of objects of line, rectangle and ellipse are stored using a collection class called ArrayList. The object s of this class now consists of references of objects of the line, rectangle and ellipse classes. As these classes are derived from shapes, it is perfectly legitimate for a reference to shapes to be set up to point to either shapes or one of its derived classes.

Next we have called the Invalidate( ) method which results in the Form1_Paint( ) method getting called. Here we have collected back each reference from the array s into a reference ss of type shapes. Using this reference it has then called the draw( ) method. Depending upon which (line, rectangle or ellipse) reference is present in ss the draw( ) function of that class gets called. The resulting form is shown below.

If we wish to save the file we can click on �Save� menu item. When we do so savemenu_Click( ) gets called. We have created an object of the SaveFileDialog class and used a �*.dat� filter for it. When we type in a file name and click Ok, a FileInfo object gets created with the selected name. The Open( ) function returns a Stream object associated with the file. We have collected it in a Stream reference. We have used the BinaryFormatter object to serialize the objects. The BinaryFormatter serializes and deserializes an object, in binary format. We have added a BinaryFormatter object b to our class. The Serialize( ) method of this class serializes the object to the given stream. After serializing all the elements of the array we have closed the stream using the Close( ) method.

When we click �Open� menu item an OpenFileDialog is popped with the appropriate filter. Here also we have created a FileInfo object and collected the corresponding Stream of the specified file. Next we have used a while loop to deserialize the objects until the end of stream is reached. The Deserialize( ) method deserializes the specified stream into an object. We have collected these objects into our array, closed the stream and called Invalidate( ) function for painting these shapes.

When we click �New� menu item the array is cleared by deleting all the elements in the array. After this we have called Invalidate( ). This time the method Form1_Paint( ) draws nothing as the array is empty, thereby resulting a clean form.

On clicking the �Exit� menu item the Dispose( ) method gets called and the form is disposed.

Building Custom Controls

Besides the standard controls we may wish to create our own controls. For e.g. the existing controls might not fulfill our application�s needs. So these are nothing but user-defined controls.

We plan to make a user-defined timer control. The timer will just show the current date and time in six textboxes. Two functions will be provided to start and stop the timer.

To create a Custom Control, create a new Windows Control Library project in VS.NET:

Click on OK and a form will be created which would be derived from UserControl class.

Drag in 6 textboxes each for day, month, year, hour, minute and second and four labels two with text �/� and two with text �:�. This is how it should look after adding the controls.

All the text boxes should be made read-only. Intuitively name them as day, month, year, hour, min and sec. Also add one bool variable st, which denotes the status of timer, whether it is on or off. To stop the timer this variable is set to true and to start it this variable is set to false.

To this class we will add 3 functions viz: - settime( ), start( ) and stop( ).

To start the timer following code should be written

public void start ( )
{

Thread t = new Thread ( new ThreadStart ( settime ) ) ;
st = false ;
t.Start ( ) ;

}

Here a new Thread t is started whose delegate function is settimer( ). Before starting the Thread the st variable is set to false. Stopping the timer is as simple as:

public void stop ( )
{

st = true ;

}

In the settimer( ) function we set the Text properties of all the textboxes to Current Date and Time using the DateTime class. We made the thread wait for 100 milliseconds and kept on updating the textboxes with the appropriate values until st was made to be true, This could happen only if the stop function was called.

public void settime ( )
{

while ( ! st )
{

day.Text = DateTime.Now.Day.ToString ( ) ;
month.Text = DateTime.Now.Month.ToString ( );
year.Text = DateTime.Now.Year.ToString ( ) ;
hour.Text = DateTime.Now.Hour.ToString ( ) ;
min.Text = DateTime.Now.Minute.ToString ( ) ;
sec.Text = DateTime.Now.Second.ToString ( ) ;
Thread.Sleep ( 100 ) ;

}

}

Now we need to build and not compile the code. This will create the mycontrol.dll file.


Client

To use this control we have to create a client for it. To make a client, create a Windows Application project and name it as client. To add the custom control to the toolbox right click in the Toolbox area, and select Customize Toolbox. Select the .Net Framework Components tab, and then the browse button. Add in the dll we just created. After this gets added, we can drag and drop it in our form. We will add two buttons to start and stop the timer.

The start_click( ) and stop_click( ) look like this:

private void start_Click (object sender, System.EventArgs e )
{

mytimer.start ( ) ;

}

private void stop_Click ( object sender, System.EventArgs e )
{

mytimer.stop ( ) ;

}

And at any instance of time when we press start we should get the current time and date as shown:

Image Explorer

In this program we have used 4 controls viz: a TreeView Control, a ListView Control, a Panel, and a PictureBox. The TreeView Control is used to explore directories and files. The ListView control is used to display the list of all the �.bmp�, �.jpg�, and �.gif� files. The PictureBox is used to display the file selected in the ListView. The Panel is used to make the PictureBox scrollable.

We also plan to add a status bar with two panels in it to display the Path and Size of the selected file.

To start with, we have dragged the TreeView, ListView and the Panel into our form. Next we have dragged in the PictureBox. We have dragged the PictureBox into the panel and not in the Form. Here we should take care that our PictureBox should be larger in size than our Panel. This will make the whole thing scrollable. If the Picture is not big enough to fit in the Panel the Panel will automatically be provided with vertical and horizontal scroll bars. The PictureBox control is non-scrollable and it clips the regions of the picture, which do not fit in it.

We then have dragged in 3 GroupBoxes to enclose these three controls. We should make sure to right click on the GroupBox and select �Send to back�, to have the GroupBoxes in background.

Next we have dragged in a StatusBar in our Form. Next we clicked the StatusBar properties window, clicked on Panels (Collection) and added two panels by clicking the �Add� button with names: - myspanel1 and myspanel2 We then made the following changes in the properties window of the corresponding controls

Control Change To
TreeView Name tree
ListView Name list
Panel Name mypanel
Panel BorderStyle FixedSingle
PictureBox Name pic
1st GroupBox Name List
2nd GroupBox Name Files
3rd GroupBox Name Image
StatusBar Name Mysbar

Next we have added the following events to our program.

Control Event Meaning
TreeView AfterExpand Occurs when a node has been expanded
TreeView AfterSelect Occurs when selection has been changed
ListView SelectedIndexChanged Occurs when an selected index is changed

We have also manually added the following method:- getpath( ), adddrives( ), and check( ).We will look at these events and methods one by one.

We have first called the adddrives( ) method in the Form1 constructor after the InitializeComponent( ) call.

public Form1( )
{

InitializeComponent ( ) ;
adddrives ( ) ;

}

adddrives( ) function looks like this:

public void adddrives ( )
{

string [ ] drives = Directory.GetLogicalDrives ( ) ;
foreach ( string i in drives )
{

TreeNode t = new TreeNode ( ) ;
t = tree.Nodes.Add ( i ) ;
t.Nodes.Add ( " " ) ;

}

}

The static function GetLogicalDrives( ) retrieves the names of the logical drives on the machine in the form of strings. We have collected them in a string array called drives. We have added a node for every drive present in the machine. To do this we have created a new TreeNode every time and added it to the tree using the Nodes.Add( ) method. The last t.Nodes.Add( ) is used to display the �+� sign, and it adds a blank node .We should now add events to our program.

When we executed this program on our machine we got this

Lets look at the events we added for the TreeView control.

protected void tree_AfterExpand ( object sender, System.WinForms.TreeViewEventArgs e )
{

TreeNode t = e.node ;
DirectoryInfo d = null ;
if ( t.Parent == null )
{

t.Nodes.Remove( 0 ) ;
d = new DirectoryInfo ( e.node.Text ) ;
Check ( d, t ) ;

}

}

This event is fired when a node is expanded. We have collected the reference of the node to be expanded in t. Then we have created a directory referencing a null value. We have then checked if it�s a parent node or not. If it is, we have deleted the first blank node we had added using the Remove( ) method. We have stored the reference of this directory in d and have called the Check( ) method. The Check( ) method is shown below

public static void Check ( Directory d, TreeNode t )
{

FileSystemInfo [ ] f = d.GetFileSystemInfos ( ) ;
foreach ( FileSystemInfo i in f )
{

if ( i.GetType ( ).ToString ( ) == "System.IO.DirectoryInfo" )
{

DirectoryInfo d1 = new DirectoryInfo ( i.FullName ) ;
TreeNode t1 = t.Nodes.Add ( i.Name ) ;
Check ( d1, t1 ) ;

}


}

}

This is a recursive method. In this method we wish to explore all the directories and sub-directories. We have passed a directory object and a node to this function. We have collected them in d and t respectively. The GetFileSystemEntries( ) method returns all �Entries� in that particular directory, be it a file or a sub directory. We have used an array of the FileSystemEntry class to store them. We have then used a foreach loop to iterate through all the elements in the array. If the element happened to be a file, we neglected it. But if was a directory we added it as a node to the tree and called the Check( ) function on this directory to explore any sub directories, any sub-sub directories and so on within it. At the end of the function we have all the directories, sub-directories and so on, added to the tree.

If we select any of the directories in the TreeView we should get a list of .bmp, .jpg and .gif files, contained in that directory, in the ListView. For this the code added to the tree_AfterSelect( ) event handler is

protected void tree_AfterSelect ( object sender, System.WinForms.TreeViewEventArgs e )
{

selpath = getpath ( e.node ) ;
DirectoryInfo d = new DirectoryInfo ( selpath ) ;
FileInfo [ ] f = d.GetFiles ( ) ;
int n = 0 ;
list.Clear( ) ;
list.Invalidate( ) ;
foreach ( FileInfo i in f )
{

string str = i.Extension ;
if ( str == ".bmp" || str == ".jpg" || str == ".gif" )
{

list.Items.Add ( i.Name,n ) ;
n++ ;

}

}

}

We have added the string variable selpath as a private data member to the Form1 class, because we have to use it in the method list_ItemActivated( ) event. It stores the path. The getpath( ) method returns the full path of that particular node (selected directory) which we have collected in selpath. We will look at this method in a moment. After obtaining the complete path we have created a new directory object with this path. The call d.GetFiles( ) returns an array of all the files present in that particular directory. The Clear( ) and Invalidate( ) methods help in repainting and clearing the ListView. We have then used a foreach loop on all the files in the array. The .bmp, .jpg, and .gif files are filtered out and added to the ListView using the InsertItem( ) method. We have passed the index and Name of the file to this method. Let�s now look at the getpath( ) method

string getpath ( TreeNode h )
{

string result = h.Text ;
TreeNode hparent ;
while ( ( hparent = h.Parent ) != null )
{

string str = hparent.Text ;
if ( !str.EndsWith ( "\\" ) )
str += "\\" ;
result = str + result ;
h = hparent ;

}

return result ;

}

We have first stored the Text of the node (directory), which gives the name of the node in the string variable result. The logic here is, we have to create a path for the directory chosen. What we have in hand is only the name of the node and not the full path. We have to keep on prefixing the name with its parent�s name until we don�t get the topmost node, which will obviously be the drive name and then finally we will get the full path. We have collected the parent�s name in variable str. To do this we have used a while loop until we reached the drive (highest node). The statement, result = str + result, keeps on prefixing the parent�s name to result. h = hparent keeps on iterating from a node to its parent. When we come across a directory we have added a �\� to str. So, eventually the path is stored in result and returned back to the calling function.

Now if we double click on any item present in the ListView we should get the image in the PictureBox. For this the following code should be added to the list_ItemActivate( ) method.

protected void list_ItemActivate (object sender, System.EventArgs e)
{

string str = list.FocusedItem.Text;

if ( !selpath.EndsWith("\\" ) )

selpath += "\\" ;

str = selpath + str ;
Image img = Image.FromFile ( str ) ;
FileInfo f = new FileInfo(str) ;
myspanel1.Text = "Path: " + f.FullName ;
myspanel2.Text = "Size in bytes: " + f.Length ;
pic.Width = img.Width ;
pic.Height = img.Height ;
pic.Image = img;

}

We have first completed the full path of the file chosen by concatenating selpath with the selected Item�s text (nothing but the file name). Next we have created an object of the Image class. The FromFile( ) method creates an image from the specified file. We have displayed the File Path and Size of the selected file on the StatusBar. To do so we have to set the Text properties of both the StatusBars to FullName and Length as shown in the following snippet.

myspanel1.Text = "Path: " + f.FullName ;
myspanel2.Text = "Size in bytes: " + f.Length ;

FullName and Length are properties of the FileInfo class. The only thing left is to display the image in the PictureBox, which is accomplished by using the following statements.

pic.Width = img.Width ;
pic.Height = img.Height ;
pic.Image = img;

The Width and Height properties of the PictureBox are set to the Width and Height properties of the Image object. Last but not the least we have set the Image property of the PictureBox to our image object. This will display our image in the PicturBox. Following should be the output when we compile it:

Simple Winform

Lets look at a better program now, which takes in some information about an employee and displays out the same. We plan to add the following Controls in our program.
  1. Lables

  2. TextBoxes

  3. ComboBox

  4. GroupBoxes

  5. RadioButons

  6. ListBox

  7. Button

These Controls are available in the Toolbox. If u don�t see the Toolbox just press Ctrl+Alt+X .We now have to drag the controls onto the form. When we do this VS.Net will automatically add some code to the InitializeComponent( ) method. Whenever we drag a control in the form, its reference is created first. Next the Location, Size, Text and TabIndex properties of the corresponding controls also get initialized.

In all we will have to drag 2 TextBoxes, 3 Lables, 1 ComboBox, 2 GroupBoxes, 2 RadioButtons, 1 ListBox, and 1 Button.

Open the �Properties� window and keep it pinned. Pinning the window down prevents auto hiding of the window, i.e. the window does not slide back when mouse pointer is not on it. To Pin the window down click the small pin present on the top right corner of the window. Whenever we click a control to highlight it, the Properties window shows that control�s properties.

We lhave made the following changes in the properties window

Control Change To
Form1 Text Employee
1st label Name lname
1st label Text Name
2nd label Name lage
2nd label Text Age
3rd label Name lsal
3rd label Text Salary
1st Text Box Name name
1st Text Box Name age
Combo Box Name sal
1st Group Box Name grpgenr
1st Group Box Text Gender
2nd Group Box Name grpexp
2nd Group Box Text Experience
List Box Name exp
1st Radio Button Name male
1st Radio Button Text Male
2nd Radio Button Name female
2nd Radio Button Text Female
Button Text OK
Button Name ok

We have kept the Text fields of both TextBoxes to null. This is because when we start the application nothing should be already written in the text boxes.

This is how our Form should look now


But then we have not yet added any items to the ListBox and ComboBox ! To do so, click on the small button near the Items (Collection) property in the Properties window of the ListBox and add the strings separated by paragraphs (or Enters).

This will make the VS.Net to add the following code in Form1.cs

this.exp.Items.AddRange ( new object [ ] { "Less than a year", "1 - 2 yrs",

"2 - 5 yrs", "more than 5 yrs" } ) ;

In the same manner, add items for the ComboBox. The following code gets added

this.sal.Items.AddRange ( new object [ ]

{"2500","3500","5000","10000","20000" }) ;

We can see that the items �2500� and �Less than a year� are already selected. This is because of the following Code

sal.SelectedIndex = 0 ;
exp.SelectedIndex = 0;

We should add these statements in the constructor after the call to the InitializeComponent( ) method.

Next we have added an event for the Button �OK�. To add an event, open the Properties window of this Button. Click on the button, which has an icon of a yellow lightning on it. This gives us a list of Events we can add for that control. Double click on the �Click� entry. This adds an event �ok_Click( )� to our application., and the following gets added in the InitializeComponent( ) method.

ok.Click += new System.EventHandler ( this.ok_Click ) ;

Such code gets added for each event we add. In this event we plan to display the information entered by our user.

protected void ok_Click (object sender, System.EventArgs e)
{

string str1,str = "Name: " + name.Text +"\n" ;
str += "Age: " + age.Text + "\n" ;
str += "Salary: " + sal.Text + "\n" ;
str += "Experience: " + exp.Text+ "\n" ;
if( male.Checked == true )

str1 = "male" ;

else

str1 = "female" ;

str += "Gender: " + str1 ;
MessageBox.Show( str,"Emp Information" ) ;

}

The code is pretty much self-explanatory. What we are doing here is nothing but concatenating our string object str every time with the information. The Text field will contain text entered by the user. In the end we display the whole string using the static Show( ) method of the class MessageBox . The first parameter is the text to be displayed while the second gives the caption of the message box.

Introduction to Winforms

WinForms is a programming model used to create Windows Applications. .NET framework offers base classes for building Windows applications. Most of the functionality for these classes is in the System.Windows.Forms namespace. The Visual Studio is used to design these applications visually, and to automatically generate the code.

Hello World

Lets look at the simplest traditional �hello world� example which will help us create our first Windows application in C#.

Click on the File menu and select New | Project. Now select Windows Application from the Templates and click OK. You are now presented with an empty form.

We can now drag in controls in our form. But we will not drag controls in our program. Rather we will only change the title of the form.

To do so, right click on the form and select Properties. A Window named Properties pops up from the right. This will be a very useful window all the way long. Just change the Text field to �hello world�.

When we open the code part, we see the following:

using System ;
using System.Drawing ;
using System.Collections ;
using System.ComponentModel ;
using System.Windows.Forms ;
using System.Data ;

namespace Hello_world
{

public class myform : System.Windows.Forms.Form
{

private System.ComponentModel.Container components = null;

public myform ( )
{

InitializeComponent ( ) ;

}

protected override void Dispose( bool disposing )
{

if ( disposing )
{

if ( components != null )
{

components.Dispose ( ) ;

}

}

base.Dispose( disposing ) ;

}

#region Windows Form Designer generated code
private void InitializeComponent ( )
{

this.AutoScaleBaseSize = new System.Drawing.Size ( 5, 13 ) ;
this.ClientSize = new System.Drawing.Size ( 160, 85 ) ;
this.Name = "myform" ;
this.Text = "Hello World" ;//change the form title

}

#endregion

[STAThread]
static void Main ( )
{

Application.Run ( new myform ( ) ) ;

}

}

}

We have removed the comments for clarity.

The form class is derived form the System.Windows.Forms.Form class. In the constructor of this class a function called InitializeComponents( ) is called. Whatever changes we make in the Properties Window are reflected in form of code in this function. This code is written by the Windows Form Designer and is hence defined in a separate region.

If we add controls, they are also initialized in this function with corresponding changed properties. So in our form only the text and name have been changed.

In Main( ) the Run( ) method from the Application class is called. To this method an instance of the form has been passed. The Application class provides static methods and properties to manage an application, such as methods to start and stop an application, to process Windows messages, and properties to get information about an application. The Run( ) method begins running a standard application message loop on the current thread.

When we press Ctrl+F5 to compile and run the program We get the following output.