Friday 19 September 2014

C# .Net[version 4.5]-Beginner And Advanced:
Basic:1
1)What is .Net ?
Ans:It is product of Microsoft design to be platform independent(portable) and object oriented(means have more security and re-usability) which can used in the development of various kind of applications Like-
1)Windows (or Desktop) applications
2)Web applications.
3)Mobile application.



IF/ELSE  Based:
Q1 )Check Wether it is Even Number Or Not ?

Ans:
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication21
{
    class Program
    {
        static void Main(string[] args)
        {
         Console.WriteLine("Enter your number to know whether it is Even number or not:");
            int i = int.Parse(Console.ReadLine());
            if (i % 2 == 0)
                Console.WriteLine(i + " is an Even number");
            else
                Console.WriteLine(i + " is not an Even number");
            Console.ReadLine();
        }

    }
}

Q2 )Check For the Number is ODD Or Not ?
Ans:
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
           Console.WriteLine("Enter your number to know whether it is Odd number or not:");
            int i = int.Parse(Console.ReadLine());
            if (i % 2 == 1)
                Console.WriteLine(i + " is a Odd number");
            else
                Console.WriteLine(i + " is not a Odd number");
                Console.ReadLine();
        }

    }
}

Q2 )Check For the Number is Vowel Or Not ?

Ans:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter any character: ");
            char c = char.Parse(Console.ReadLine());
            if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
                Console.WriteLine(c + " is a vowel\n");
            else
                Console.WriteLine(c + " is not a vowel\n");
                Console.ReadLine();
        }


    }
}

Q2 )Comarision For 3 Numbers that which no is Greater ?
Ans:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter any there numbers to compare:\nEnter ur 1st number:");
            int a = int.Parse(Console.ReadLine());
            Console.WriteLine("Enter ur 2nd number:");
            int b = int.Parse(Console.ReadLine());
            Console.WriteLine("Enter ur 3rd number:");
            int c = int.Parse(Console.ReadLine());
            if (a > b & a > c)
                Console.WriteLine(a + " is greater");
            else if (b > c)
                Console.WriteLine(b + " is greater");
            else
                Console.WriteLine(c + " is greater");
                Console.ReadLine();
        }



    }
}

Q2 ) Division Findout accound to Marks of a student ?
Ans:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter a student marks:\nPlease enter marks in English:");
            byte eng = byte.Parse(Console.ReadLine());
            Console.WriteLine("Please enter marks in Maths:");
            byte mat = byte.Parse(Console.ReadLine());
            Console.WriteLine("Please enter marks in Physics:");
            byte phy = byte.Parse(Console.ReadLine());
            Console.WriteLine("Please enter marks in chemistry:");
            byte chem = byte.Parse(Console.ReadLine());
            ushort sum = Convert.ToUInt16((eng + mat + phy + chem) / 4);
            if (eng < 35 | mat < 35 | phy < 35 | chem < 35)
                Console.WriteLine("The student has failed in some subjects:");
            else if (sum > 70)
                Console.WriteLine("The student has passed in distinction");
            else if (sum > 60 && sum < 70)
                Console.WriteLine("The student has passed in 1st class:");
            else if (sum > 50 && sum < 60)
                Console.WriteLine("The student has passed in 2nd class:");
            else
                Console.WriteLine("The student has passed in 3rd class");

                Console.ReadLine();
        }




    }
}


For Loop Based:

1)Check Prime number or not
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
Console.WriteLine("Enter your number to know whether it is Prime number
or not:"); 
         int i, count =0, j = int.Parse(Console.ReadLine());

            for (i = 1; i<= j; i++)
                if (j % i ==0)
count =count 
if (count == 2)
Console.WriteLine(j + " is  aprime number");
else
Console.WriteLine(j + " is not a prime number");
Console.ReadLine();
}
}
}
2)The number to print the  Table
Ans:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter any number to print its table:");
            short a = short.Parse(Console.ReadLine());
            for (sbyte i = 0; i <= 10; i++)
                Console.WriteLine(a + " x " + i + " = " + a * i);
                Console.ReadLine();
        }
    }
}




3) Power use
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication22
{
    class Program
        {
           static void Main(string[] args)
              {
           Console.WriteLine("To find x to the power of y, (x^y)\nEnter ur x value:");
            int x = int.Parse(Console.ReadLine());
            Console.WriteLine("Enter the exponent or y value:");
            int value = 1, y = int.Parse(Console.ReadLine());
            for (int i = 1; i <= y; i++)
                value = value * x;
            Console.WriteLine(x + "^" + y + " is : " + value);
            Console.ReadLine();
        }
    }
}
 
4) Reverse The string
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter Ur name: ");
            string name = Console.ReadLine();
            Console.WriteLine("Reverse of ur Name is: ");
            for (int i = name.Length - 1; i >= 0; i--)
                Console.Write(name[i]);
                Console.ReadLine();
        }
     }
}
 
5)Addition upto given number
Ans:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Please enter any number:");
            uint k, i = uint.Parse(Console.ReadLine());
            ulong sum = 0;
            for (k = 0; k <= i; k++)
                sum = sum + k;
            Console.WriteLine("The sum of the numbers upto given no " + i + " is :" + sum);
            Console.ReadLine();
        }
     }
}
 
6)To Find the matching Character
Ans:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication22
{
    class Program
      {
        static void Main(string[] args)
          {
          Console.WriteLine("Enter Ur name: ");
            string name = Console.ReadLine();
        Console.WriteLine("Enter any character to find its matching index with ur name: ");
            char c = char.Parse(Console.ReadLine());
            int count = 0;
            for (sbyte i = 0; i <= (name.Length - 1); i++)
            {
                if (name[i] == c)
                    Console.Write(i + " ,");
                else
                    count = count + 1;
            }


            if (count == name.Length)
            Console.WriteLine("Matching for the given character is not found:");
            Console.ReadLine();
        }

    }
}
 
7)Find the greatest number among three numbers.
Ans:
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
        Console.WriteLine("Enter any two numbers to find GCD:\nEnter ur 1st number: ");
            int a = int.Parse(Console.ReadLine());
            Console.WriteLine("Enter ur 2nd number");
            int b = int.Parse(Console.ReadLine());
            int gcd = 1, greteast = a > b ? a : b;
            for (int i = 1; i <= greteast; i++)
                if (a % i == 0 && b % i == 0)
                    gcd = i;
            Console.WriteLine("GCD of the given two numbers is: " + gcd);
            Console.ReadLine();
        }
 
 
    }
}
 
WHILE LOOP USE:
1) reverse numbers
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter your number:");
            int m = 0, n = int.Parse(Console.ReadLine());
            while (n > 0)
            {
                m = m * 10 + n % 10;
                n = n / 10;
            }
            Console.WriteLine("Reverse of the given no is : " + m);
            Console.ReadLine();
        }
     }
}
2) Sum of the digits
Ans:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter your number to know its sum of the digits:");
            int m = 0, n = int.Parse(Console.ReadLine());
            while (n > 0)
            {
                m = m + n % 10;
                n = n / 10;
            }
            Console.WriteLine("Sum of the digits of the given number is: " + m);
            Console.ReadLine();
        }
     }
}
 
3)Check it is a pollindrom or not.
Ans:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
      Console.WriteLine("Enter your number to know Whether it is a pollindrome or not:");

          int m = 0, n = int.Parse(Console.ReadLine());
          int preno = n;
            while (n > 0)
            {
                m = m * 10 + n % 10;
                n = n / 10;
            }
            if (preno == m)
            Console.WriteLine(preno + " C");
            else
              Console.WriteLine(preno + " is not a pollindrome");
              Console.ReadLine();
        }
    }
}
 
4)Check it is a Amestrong Number or not
 
Ans:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
   Console.WriteLine("Enter your number to know whether it is amestrong number or not?:");
            int m = 0, n = int.Parse(Console.ReadLine());
            int preno = n;
            while (n > 0)
            { 
                m = m + ((n % 10) * (n % 10) * (n % 10));
                n = n / 10;
            }
            if (preno == m)
                Console.WriteLine(preno + " is a Amestrong Number");
            else
                Console.WriteLine(preno + " is not a Amestrong number");
            Console.ReadLine();
        }
     }
}
 
 
5) Display fibonacci sequence
Ans:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication26
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter any no:");
            int i = 0, j = 1, k,n = int.Parse(Console.ReadLine());
            Console.WriteLine("Your fibonacci sequence is: ");
            while (i <= n)
            {
                k = j;
                j = i;
                Console.Write(i + " ");
                i = i + k;
            }
            Console.ReadLine();
        }
    }
}




SWITCH CASE USE:


1) Performing Add,Sum,Mul,Div


Ans:
static void Main(string[] args)
        { 
            Console.WriteLine("Enter ur 1st number:");
            int a = int.Parse(Console.ReadLine());
            Console.WriteLine("Enter ur 2nd number:");
            int b = int.Parse(Console.ReadLine());
            Console.WriteLine("Select any option from the below:");
            Console.WriteLine("1.Addition\t2.Substraction\n3.Multiplication\t4.Divison");
            sbyte i = sbyte.Parse(Console.ReadLine());
            switch(i)
            {
                case 1:
                    Console.WriteLine("Addition of given two numbers is :"+ (a+b));
                    break;
                case 2:
                    Console.WriteLine("Substraction of given two numbers is :" + (a - b));
                    break;
                case 3:
                    Console.WriteLine("Multiplication of given two numbers is :" + (a*b));
                    break;
                case 4:
                    Console.WriteLine("Divison of given two numbers is :" + (a / b));
                    break;
                default:
                    Console.WriteLine("Please enter a valid choice:");
                    break;
           }
            Console.ReadLine();
}
 
2)Max,,Min  Values of DataType
Ans:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Select any to know its maximum and minimum sizes:\nEnter ur Option:");
            Console.WriteLine("1.sbyte 2.short 3.int 4.long");
            sbyte a = sbyte.Parse(Console.ReadLine());
            switch (a)
            {
                case 1:
                    Console.WriteLine("The Maximum value of the sbyte is:" + sbyte.MaxValue);
                    Console.WriteLine("The Minimum value of the sbyte is:" + sbyte.MinValue);
                    break;

                case 2:
                    Console.WriteLine("The Maximum value of the short is:" + short.MaxValue);
                    Console.WriteLine("The Minimum value of the short is:" + short.MinValue);
                    break;
                case 3:
                    Console.WriteLine("The Maximum value of the int is:" + int.MaxValue);
                    Console.WriteLine("The Minimum value of the int is:" + int.MinValue);
                    break;
                case 4:
                    Console.WriteLine("The Maximum value of the Long is:" + long.MaxValue);
                    Console.WriteLine("The Minimum value of the long is:" + long.MinValue);
                    break;
                default:
                    Console.WriteLine("Enter valid choice:");
                    break;
            }
            Console.ReadLine();
        }






    }
}

3) General program

Ans:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication22
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Choose any one of the Option from below to know its price: ");
            Console.WriteLine("1.Idea 3G Netsetter \n2.Intex 3G Netsetter\n3.Airtel 3G Netsetter");
            sbyte a = sbyte.Parse(Console.ReadLine());
            switch (a)
            {
                case 1:
                    Console.WriteLine("Cost of the Idea 3G Netsetter is Rs 1650/-.");
                    break;
                case 2:
                    Console.WriteLine("Cost of the Intex 3G Netsetter is Rs 1350/-.");
                    break;
                case 3:
                    Console.WriteLine("Cost of the Airtel 3G Netsetter is Rs 1550/-.");
                    break;
                default:
                    Console.WriteLine("Please enter a valid choice:");
                    break;
            }
            Console.ReadLine();
        }







    }
}


...........................................................................................



ADO.Net
                Pretty much every application deals with data in some manner, whether that data comes from memory, databases, XML files, text files, or something else. The location where we store the data can be called as a Data Source or Data Store where a Data Source can be a file, database, or indexing server etc.
Programming Languages cannot communicate with Data Sources directly because each Data Source adopts a different Protocol (set of rules) for communication, so to overcome this problem long back Microsoft has introduced intermediate technologies like JET, Odbc and Oledb which works like bridge between the Applications and Data Sources to communicate with each other.
               
The Microsoft Jet Database Engine is a database engine on which several Microsoft products have been built. A database engine is the underlying component of a database, a collection of information stored on a computer in a systematic way. The first version of Jet was developed in 1992, consisting of three modules which could be used to manipulate a database. JET stands for Joint Engine Technology, sometimes being referred to as Microsoft JET Engine or simply Jet. Microsoft Access and Excel uses Jet as their underlying database engine. Over the years, Jet has become almost synonymous with Microsoft Access, to the extent where many people refer to a Jet database as an "Access database". MS developed Jet database system, a C-based interface allowing applications to access that data, and a selection of driver DLLs that allowed the same C interface to redirect input and output to databases. However, Jet did not use SQL; the interface was in C and consisted of data structures and function calls.
               
ODBC (Open Database Connectivity) is a standard C programming language middleware API for accessing database management systems (DBMS). ODBC accomplishes DBMS independence by using an ODBC driver as a translation layer between the application and the DBMS. The application uses ODBC functions through an ODBC driver manager with which it is linked, and the driver passes the query to the DBMS. An ODBC driver will be providing a standard set of functions for the application to use, and implementing DBMS-specific functionality. An application that can use ODBC is referred to as "ODBC-compliant". Any ODBC-compliant application can access any DBMS for which a driver is installed. Drivers exist for all major DBMSs as well as for many other data sources like Microsoft Excel, and even for text or CSV files. ODBC was originally developed by Microsoft during the early 1990s.
               
OLE DB (Object Linking and Embedding, Database, sometimes written as OLEDB or OLE-DB), an API designed by Microsoft, allows accessing data from a variety of sources in a uniform manner. The API provides a set of interfaces implemented using the Component Object Model (COM). Microsoft originally intended OLE DB as a higher-level replacement for, and successor to, ODBC, extending its feature set to support a wider variety of non-relational databases, such as object databases and spreadsheets that do not necessarily implement SQL. OLE DB is conceptually divided into consumers and providers. The consumers are the applications that need access to the data, and the providers are the software components that implement the interface and thereby provide the data to the consumer. An OLE DB provider is a software component enabling an OLE DB consumer to interact with a data source. OLE DB providers are alike to ODBC drivers or JDBC drivers for Java. OLE DB providers can be created to access such simple data stores as a text file and spreadsheet, through to such complex databases as Oracle, Microsoft SQL Server, and many others. It can also provide access to hierarchical data stores.
DAO’s, RDO’s and ADO’s in Visual Basic Language:
                Visual Basic Language used DAO’s, RDO’s and ADO’s for data source communication without having to deal with the comparatively complex JET or ODBC or OLEDB API.











Data Access Objects is a deprecated general programming interface for database access on Microsoft Windows systems using Joint Engine Technology.
               
Remote Data Objects (abbreviated RDO) is the name of an obsolete data access application programming interface primarily used in Microsoft Visual Basic applications on Windows 95 and later operating systems. This includes database connection, queries, stored procedures, result manipulation, and change commits. It allowed developers to create interfaces that can directly interact with Open Database Connectivity (ODBC) data sources on remote machines.
               
Microsoft's ActiveX Data Objects (ADO) is a set of Component Object Model (COM) objects for accessing data sources. It provides a middleware layer between programming languages and OLE DB (a means of accessing data stores, whether they be databases or otherwise, in a uniform manner). ADO allows a developer to write programs that access data without knowing how the database is implemented; developers must be aware of the database for connection only. ADO is positioned as a successor to Microsoft's earlier object layers for accessing data sources, including RDO (Remote Data Objects) and DAO (Data Access Objects). ADO was introduced by Microsoft in October 1996.
ADO.NET Providers:
                ADO.NET providers can be created to access such simple data stores as a text file and spreadsheet, through to such complex databases as Oracle, Microsoft SQL Server, MySQL, PostgreSQL, SQLite, DB2, Sybase ASE, and many others. They can also provide access to hierarchical data stores such as email systems. However, because different data store technologies can have different capabilities, every ADO.NET provider cannot implement every possible interface available in the ADO.NET standard.
ADO.Net:
It is a set of classes that expose data access services to the .NET programmer. ADO.NET provides functionality to developers writing managed code similar to the functionality provided to native COM developers by ADO. ADO.NET provides consistent access to data sources such as Microsoft SQL Server, as well as data sources exposed through OLE DB and XML. Data-sharing consumer applications can use ADO.NET to connect to these data sources and retrieve, manipulate, and update data. It is an integral part of the .NET Framework, providing access to relational data, XML, and application data. ADO.NET supports a variety of development needs, including the creation of front-end database clients and middle-tier business objects used by applications or Internet browsers. ADO.Net provides libraries for Data Source communication under the following namespaces:
·         System.Data
·         System.Data.Odbc
·         System.Data.Oledb
·         System.Data.SqlClient
·         System.Data.OracleClient
Note: System.Data, System.Data.Oledb, System.Data.SqlClient and System.Data.Odbc namespaces are under the assembly System.Data.dll whereas System.Data.OracleClient is under System.Data.OracleClient.dll assembly.
System.Data: types of this namespace are used for holding and managing of data on client machines. This namespace contains following set of classes in it:  DataSet, DataTable, DataColumn, DataRow, DataView, DataRelation etc.
System.Data.Odbc: types of this namespace can communicate with any Data Source like files, databases, and indexing servers etc. using Un-Managed Odbc Drivers.
System.Data.Oledb: types of this namespace can communicate with any Data Source like files, databases, and indexing servers etc. using Oledb Providers (Un-Managed COM Provider).
System.Data.SqlClient: types of this namespace can purely communicate with Sql Server database only using SqlClient Provider (Managed ADO.Net Provider).
System.Data.OracleClient: types of this namespace can purely communicate with Oracle database only using OracleClient Provider (Managed ADO.Net Provider).
All the above 4 namespaces contains same set of types as following: Connection, Command, DataReader, DataAdapter, CommandBuilder etc, but here each class is referred by prefixing with their namespace before the class name to discriminate between each other as following:
OledbConnection                      OledbCommand      OledbDataReader         OledbDataAdapter      OledbCommandBuilder
SqlConnection            SqlCommand             SqlDataReader               SqlDataAdapter           SqlCommandBuilder
OracleConnection     OracleCommand     OracleDataReader      OracleDataAdapter     OracleCommandBuilder
OdbcConnection        OdbcCommand       OdbcDataReader            OdbcDataAdapter       OdbcCommandBuilder
Performing Operations on a DataSource: Each and every operation we perform on a Data Source involves in 3 steps, like:
  • Establishing a connection with data source.
  • Sending request to data source as a sql statement.
  • Capturing the results given by data source.
Establishing a Connection with Data Source:
It's a process of opening a channel for communication between Application and Data Source that is present on a local or remote machine to perform any operations. To open the channel for communication we can use the Connection class.
Constructors of the Class:                 
Connection()                                        
Connection(string ConnectionString)
Note: ConnectionString is a collection of attributes that are used for connecting with a DataSource, those are:
  • Provider
  • Data Source
  • User Id and Password
  • Database or Initial Catalog
  • Trusted_Connection or Integrated Security
  • DSN
Provider: as discussed earlier provider is required for connecting with any data source's, we have a different provider available for each data source.
                Oracle                                    Msdaora                                                Sql Server                              SqlOledb
MS-Access or MS-Excel      Microsoft.Jet.Oledb.4.0                      MS-Indexing Server             Msidxs
Data Source: it is the name of target machine to which we want to connect with but it is optional when the data source is on a local machine.
User Id and Password: as db's are secured places for storing data, to connect with them we require a valid user id and password.
                Oracle: Scott/tiger                                                                               Sql Server: Sa/<pwd>
Database or Initial Catalog: these attributes are used while connecting with Sql Server Database to specify the name of database we want to connect with.
Trusted_Connection or Integrated Security: these attributes are also used while connecting with Sql Server Database only to specify that we want to connect with the Server using Windows Authentication. In this case we should not again use User Id and Password attributes.
DSN: this attribute is used to connect with data sources by using Odbc Drivers.
Connection String for Oracle: "Provider=Msdaora;User Id=Scott;Password=tiger[;Data Source=<server>]"
Connection String for Sql Server: "Provider=SqlOledb;User Id=Sa;Password=<pwd>;Database=<db name>[;Data Source=<server>]"
Note: in case of Windows Authentication in place of User Id and Password attributes we need to use Integrated Security = SSPI (Security Support Provider Interface) or Trusted_Connection = True.
Members of Connection class:
  1. Open(): a method which opens a connection with data source.
  2. Close(): a method which closes the connection that is open.
  3. State: an enumerated property which is used to get the status of connection.
  4. ConnectionString: a property with is used to get or set a connection string which is associated with the connection object.
The Object of class Connection can be created in any of the following ways:
                Connnection con = new Connection(); con.ConnectionString = "<connection string>";
                                                                or
Connection con = new Connection("<connection string>");
Testing the process of establishing a connection: open a new project of type Windows Forms Application and name it as DBOperations. Place 2 buttons on the form and set their caption as “Connect with Oracle using OLEDB Provider” and “Connect with Sql Server using OLEDB Provider”. Now go to code view and write the following code:
using System.Data.OleDb;
Declarations: OledbConnection ocon, scon;
Under Connect with Oracle using OLEDB Provider:
ocon = new OleDbConnection(“Provider=Msdaora;User Id=Scott;Password=tiger;Data Source=<server>");
ocon.Open(); MessageBox.Show(ocon.State.ToString()); ocon.Close(); MessageBox.Show(ocon.State.ToString());
Under Connect with Sql Server using Oledb Provider:
scon = new OleDbConnection(); scon.ConnectionString =
"Provider=SqlOledb;User Id=Sa;Password=<pwd>;Database=Master;Data Source=<server>";
scon.Open(); MessageBox.Show(scon.State.ToString()); scon.Close(); MessageBox.Show(scon.State.ToString());
Sending request to Data Source as a Sql Statement: In this process we send a request to Data Source by specifying the type of action we want to perform using a Sql Statement like Select, Insert, Update, and Delete or by calling a Stored Procedure. To send and execute those statements on data source we use the class Command.
Constructors of the class:                 Command()                           Command(string CommandText, Connection con)
Note: CommandText means it can be any Sql Stmt like Select or Insert or Update or Delete Stmts or Stored Procedure Name.
Properties of Command Class:
  1. Connection: sets or gets the connection object associated with command object.
  2. CommandText: sets or gets the sql statement or SP name associated with command object.
The object of class Command can be created in any of the following ways:
Command cmd = new Command(); cmd.Connection = <con>; cmd.CommandText = "<sql stmt or SP Name>";
or
Command cmd = new Command("<sql stmt or SP Name>", con);
Methods of Command class:
·         ExecuteReader()                  ->            DataReader
·         ExecuteScalar()                    ->            object
·         ExecuteNonQuery()            ->            int
Note: after creating object of Command class we need to call any of these 3 methods to execute that statement.
Use ExecuteReader() method when we want to execute a Select Statement that returns data as rows and columns. The method returns an object of class DataReader which holds data that is retrieved from data source in the form of rows and columns.
                Use ExecuteScalar() method when we want to execute a Select Statement that returns a single value result. The method returns result of the query in the form of an object.
                Use ExecuteNonQuery() method when we want to execute any SQL statement other than select, like Insert or Update or Delete etc. The method returns an integer that tells the no. of rows affected by the statement.
Note: The above process of calling a suitable method to capture the results is our third step i.e. capturing the results given by data source.
Accessing data from a DataReader: DataReader is a class which can hold data in the form of rows and columns, to access data from DataReader it provides the following methods:
  1. GetName(int columnindex)                ->            string
Returns name of the column for given index position.
  1. Read()                                                    ->            bool
Moves record pointer from the current location to next row and returns a bool value which tells whether the row to which we have moved contains data in it or not, that will be true if data is present or false if data is not present.
  1. GetValue(int coloumnindex)              ->            object
Used for retrieving column values from the row to which pointer was pointing by specifying the column index position. We can also access the row pointed by pointer in the form of a single dimensional array also, either by specifying column index position or name, as following:
<DR>[column index]                           ->            object
                <DR>[column name]                           ->            object
Add a new Windows Form under the project and design it as following:



using System.Data.OleDb;
Declarations: OleDbConnection con; OleDbCommand cmd; OleDbDataReader dr;
Under Form Load: con=new OleDbConnection("Provider=Msdaora;User Id=Scott;Password=tiger");
cmd = new OleDbCommand("Select Deptno, Dname, Loc From Dept", con); con.Open(); dr = cmd.ExecuteReader();
label1.Text = dr.GetName(0); label2.Text = dr.GetName(1); label3.Text = dr.GetName(2); ShowData();
private void ShowData() {
 if(dr.Read()) {
  textBox1.Text = dr.GetValue(0).ToString(); textBox2.Text = dr[1].ToString(); textBox3.Text = dr["Loc"].ToString();
 }
 else        MessageBox.Show("Last Record");
}
Under Next Button: ShowData();
Under Close Button: if(con.State != ConnectionState.Closed) { con.Close(); } this.Close();
Working with Sql Server
Sql Server is a collection of databases, where a database is again collection of various objects like tables, views, procedures etc.; users of Sql Server can be owner of 1 or more databases at a time, so while connecting with sql server from a .net application within the connection string we need to specify name of the database we want to connect either by using Database or Initial Catalog attributes.
Sql Server provides 2 different modes of authentication for connecting with the DB Server those are:                                                           1. Windows Authentication                  
2. Sql Server Authentication
When a user connects through windows authentication, Sql Server validates the account name and password using the windows principal token in the operating system; this means that the user identity is confirmed by windows, Sql Server does not ask for the password and does not perform the identity validation. When using Sql Server authentication, logins are created in sql server that is not based on windows user accounts, both the user name and password are created by using sql server and stored in sql server database. Users connecting with sql server authentication must provide their credentials every time they connect with DB Server.

Note: if we want to connect using windows authentication mode, within the connection string in the place of User Id and Password attributes use “Trusted_Connection=True” or “Integrated Security=SSPI” attributes.

Connecting String for Sql Server Authentication:
“Provider=SqlOledb;User Id=Sa;Password=<pwd>;Database=<dbname>[;Data Source=<server name>]”

Connecting String for Windows Authentication:
“Provider=SqlOledb;Trusted_Connection=True;Database=<dbname>[;Data Source=<server name>]”
                                                                                                Or
“Provider=SqlOledb;Integrated Security=SSPI;Database=<dbname>[;Data Source=<server name>]”
Creating a database on Sql Server:
Go to Start Menu -> Programs -> MS Sql Server -> Sql Server Management Studio, open it and provide the authentication details to login. Once the studio is opened in the LHS we find a window “Object Explorer”, in that right click on the node Databases, select “New Database” that opens a window asking for the name, enter the name as: <DB Name>, click ok which adds the database under databases node. Now expand the database node, right click on Tables node and select “New Table” which opens a window asking for column names and data types enter the following:
Eno (Int), Ename (Varchar), Job (Varchar), Salary (Money), Photo (Image), Status (Bit)
Now select Eno Column, right click on it and select the option “Set Primary Key” and make it as an identity or key column of the table. Select Status column, go to its properties in the bottom and set “Default value or Binding” property as 1, which takes the default value for status column as true. Click on the save button at top of the studio which will prompt for table name enter name as “Employee” and click Ok which adds the table under tables node. Now right click on the table created and select “Edit” which opens a window, in that enter the data we want ignoring Photo and Status columns. Close the studio.

Note: We can connect with Sql Server from .net applications either by using Oledb or SqlClient classes also. If use SqlConnection or OracleConnection classes to connect with databases then connection string doesn’t require Provider attribute to be specified as these classes are designed specific for those databases.
Add a new form in the project and design it as following:






using System.Data.SqlClient;
Declarations: SqlConnection con; SqlCommand cmd; SqlDataReader dr; string SqlStr;
Under Form Load: con = new SqlConnection("User Id=Sa;Password=<Pwd>;Database=<DB Name>;Data Source=<Server Name>"); cmd = new SqlCommand(); cmd.Connection = con; con.Open(); LoadData();
private void LoadData() {  
  cmd.CommandText = "Select Eno, Ename, Job, Salary From Employee Order By Eno";
  dr = cmd.ExecuteReader(); ShowData();
}
private void ShowData() {
  if (dr.Read()) {
    textBox1.Text = dr[0].ToString(); textBox2.Text = dr[1].ToString();
    textBox3.Text = dr[2].ToString(); textBox4.Text = dr[3].ToString();
  }
  else       { MessageBox.Show("No data exists."); }
}
Under Next Button: Show Data();
Under New Button:
textBox1.Text = textBox2.Text = textBox3.Text = textBox4.Text = "";
dr.Close(); cmd.CommandText = "Select IsNull(Max(Eno), 1000) + 1 From Employee";
textBox1.Text = cmd.ExecuteScalar().ToString(); btnInsert.Enabled = true; textBox2.Focus();
private void ExecuteDML() {
DialogResult d = MessageBox.Show(“Are you sure of executing the below Sql Statement?\n\n" + SqlStr,
"Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
  if (d == DialogResult.Yes) {
    cmd.CommandText = SqlStr; int count = cmd.ExecuteNonQuery();
    if (count > 0)     MessageBox.Show("Statement executed successfully");
    else                     MessageBox.Show("Statement failed execution");
    LoadData();
}               }
Under Insert Button:
SqlStr = "Insert Into Employee (Eno, Ename, Job, Salary) Values(" + textBox1.Text + ", '" + textBox2.Text + "', '" + textBox3.Text + "', " + textBox4.Text + ")"; ExecuteDML(); btnInsert.Enabled = false;
                                                                                                                or
SqlStr = String.Format("Insert Into Employee (Eno, Ename, Job, Salary) Values({0}, '{1}', '{2}', {3})", textBox1.Text, textBox2.Text, textBox3.Text, textBox4.Text); ExecuteDML(); btnInsert.Enabled = false;
Under Update Button:
SqlStr = "Update Employee Set Ename='" + textBox2.Text + "', Job='" + textBox3.Text + "', Salary=" + textBox4.Text + " Where Eno=" + textBox1.Text; dr.Close(); ExecuteDML();                       or
SqlStr = String.Format("Update Employee Set Ename='{0}', Job='{1}', Salary={2} Where Eno={3}", textBox2.Text, textBox3.Text, textBox4.Text, textBox1.Text); dr.Close(); ExecuteDML();
Under Delete Button:
SqlStr = "Delete From Employee Where Eno=" + textBox1.Text; dr.Close(); ExecuteDML();                or
SqlStr = String.Format("Delete From Employee Where Eno={0}", textBox1.Text); dr.Close(); ExecuteDML();
Under Close Button: if (con.State != ConnectionState.Closed) { con.Close(); } this.Close();
DataReader: it's a class designed for holding the data on client machines in the form of Rows and Columns.

Features of DataReader:
  1. Faster access to data from the data source as it is connection oriented.
  2. Can hold multiple tables in it at a time. To load multiple tables into a DataReader pass multiple select statements as arguments to command separated by a semi-colon.
E.g.: Command cmd = new Command("Select * From Student;Select * From Teacher", con);
DataReader dr = cmd.ExecuteReader();

Note: use NextResult() method on data reader object to navigate from current table to next table.
E.g.: dr.NextResult();

Drawbacks of DataReader:
  1. As it is connection oriented requires a continuous connection with data source while we are accessing the data, so there are chances of performance degradation if there are more no. of clients accessing data at the same time.
  2. It gives forward only access to the data i.e. allows going either to next record or table but not to previous record or table.





  3. It is a read only object which will not allow any changes to data that is present in it.

Dis-Connected Architecture: ADO.Net provides 2 different models for accessing data from Data Sources:
1.       Connection Oriented Architecture                                                               2. Disconnected Architecture
In the first case we require a continuous connection with the data source for accessing data from it, in this case we use DataReader class for holding the data on client machines, where as in the 2nd case we don’t require a continuous connection with data source for accessing of the data from it, we require the connection only for loading the data from data source and here DataSet class is used for holding the data on client machines.
Working with DataSet
DataSet: It's a class present under System.Data namespace designed for holding and managing of data on client machines apart from DataReader. DataSet class provides the following features:
  1. It is designed in disconnected architecture which doesn't require any permanent connection with the data source for holding of data.
  2. It provides scrollable navigation to data which allows us to move in any direction i.e. either top to bottom or bottom to top.
  3. It is updatable i.e. changes can be made to data present in it and those changes can be sent back to DB.
  4. DataSet is also capable of holding multiple tables in it.
  5. It provides options for searching and sorting of data that is present under it.





  6. It provides options for establishing relations between the tables that are present under it.
Using DataSet's: The class which is responsible for loading data into DataReader from a DataSource is Command, in the same way DataAdapter class is used for communication between DataSource and DataSet.

DataReader <- Command -> DataSource
DataSet <-> DataAdapter <-> DataSource

Constructors of DataAdapter class:
DataAdapter(string selectcommand, Connection con) DataAdapter(Command cmd)
Note: selectcommand means it can be a select statement or a Stored Procedure which contains a select statement.

Methods of DataAdapter:
                Fill(DataSet ds, string tableName)                                     Update(DataSet ds, string tableName)

DataAdapter’s can internally contain 4 Commands under them associated with a single table, those are:
-Select Command                 -Insert Command                 -Update Command               -Delete Command

When we call Fill method on DataAdapter following actions takes place internally:
·         Opens a connection with the Data Source.
·         Executes the SelectCommand present under it on the DataSource and loads data from table to DataSet.
·         Closes the connection.

As we are discussing DataSet is updatable, we can make changes to the data that is loaded into it like adding, modifying and deleting of records, after making changes to data in DataSet if we want to send those changes back to DataSource we need to call Update method on DataAdapter, which performs the following:
  • Re-opens a connection with the Data Source.
  • Changes that are made to data in DataSet will be sent back to corresponding table, where in this process it will make use of Insert, Update and Delete commands of DataAdapter.
  • Closes the connection.





Accessing data from DataSet: Data Reader’s provides pointer based access to the data, so we can get data only in a sequential order whereas DataSet provides index based access to the data, so we can get data from any location randomly. DataSet is a collection of tables where each table is represented as a class DataTable and identified by its index position or name. Every DataTable is again collection of Rows and collection of Columns where each row is represented as a class DataRow and identified by its index position and each column is represented as a class DataColumn and identified by its index position or name.

  • Accessing a DataTable from DataSet:  <dataset>.Tables[index] or <dataset>.Tables[name]
E.g.: ds.Tables[0] or ds.Tables["Employee"]
  • Accessing a DataRow from DataTable: <datatable>.Rows[index]
                E.g.: ds.Tables[0].Rows[0]
  • Accessing a DataColumn from DataTable: <datatable>.Columns[index] or <datatable>.Columns[name]
E.g.: ds.Tables[0].Columns[0] or ds.Tables[0].Columns["Eno"]
  • Accessing a Cell from DataTable: <datatable>.Rows[row][col]
                E.g.: ds.Tables[0].Rows[0][0] or ds.Tables[0].Rows[0]["Eno"]
Add a new form in the project design it as below, then add reference of Microsoft.VisualBasic assembly from .Net tab of add reference window and write the code:








using System.Data.SqlClient; using Microsoft.VisualBasic;
Declarations:  SqlConnection con; SqlDataAdapter da; sqlCommandBuilder cb; DataSet ds; int rno = 0;
Under Form Load:
con = new SqlConnection("User Id=Sa;Password=<pwd>;Database=<DB Name>;Data Source=<Server Name>");
da = new SqlDataAdapter("Select Eno, Ename, Job, Salary From Employee Order By Eno", con);
ds = new DataSet();  da.MissingSchemaAction = MissingSchemaAction.AddWithKey;
da.Fill(ds, "Employee"); ShowData();
private void ShowData() {
textBox1.Text=ds.Tables[0].Rows[rno][0].ToString(); textBox2.Text=ds.Tables[0].Rows[rno][1].ToString();
textBox3.Text=ds.Tables[0].Rows[rno][2].ToString(); textBox4.Text=ds.Tables[0].Rows[rno][3].ToString();
}
Under First Button: rno = 0; ShowData();
Under Prev Button:
if (rno > 0) {
   rno -= 1; if (ds.Tables[0].Rows[rno].RowState == DataRowState.Deleted) {
     MessageBox.Show("Deleted row data cannot be accessed."); return;
   }
  ShowData();
} else
   MessageBox.Show("First record of the table.");
Under Next Button:
if (rno < ds.Tables[0].Rows.Count - 1) {
   rno += 1; if (ds.Tables[0].Rows[rno].RowState == DataRowState.Deleted) {
     MessageBox.Show("Deleted row data cannot be accessed."); return;
   }
  ShowData();
}
 else
  MessageBox.Show("Last record of the table.");
Under Last Button: rno = ds.Tables[0].Rows.Count – 1; ShowData();
Under New Button:
textBox1.Text  =  textBox2.Text  =  textBox3.Text  =  textBox4.Text  = “”;
int index = ds.Tables[0].Rows.Count  –  1;
int eno = Convert.ToInt32(ds.Tables[0].Rows[index][0]) + 1;
textBox1.Text = eno.ToString(); textBox2.Focus();
Adding a DataRow to DataTable of DataSet:
To add a DataRow to the DataTable of DataSet adopt the following process:
1.       Create a new row by calling the NewRow() method on DataTable.
2.       Assign values to the new row by treating it as a single dimensional array.
  1. Call the Rows.Add method on DataTable and add the row to DataRowCollection.

Under Insert Button:
DataRow dr = ds.Tables[0].NewRow();
dr[0] = textBox1.Text; dr[1] = textBox2.Text; dr[2] = textBox3.Text; dr[3] = textBox4.Text;
ds.Tables[0].Rows.Add(dr); rno = ds.Tables[0].Rows.Count – 1;
MessageBox.Show("DataRow added to DataTable of DataSet.");
Updating a DataRow in DataTable of DataSet:
To update an existing DataRow in DataTable of DataSet we need to re-assign the modified values back to the DataRow in data table, so that the old values get modified with new values.
Under Update Button:
ds.Tables[0].Rows[rno][1] = textBox2.Text; ds.Tables[0].Rows[rno][2] = textBox3.Text;
ds.Tables[0].Rows[rno][3] = textBox4.Text; MessageBox.Show("DataRow updated in DataTable.");
Deleting a DataRow in DataTable of DataSet: To delete an existing DataRow in DataTable of DataSet call Delete() method pointing to the row that has to be deleted on DataRowCollection.
Under Delete Button: 
ds.Tables[0].Rows[rno].Delete(); MessageBox.Show("DataRow deleted in DataTable of DataSet.");
Saving changes made in DataTable of DataSet back to DataBase:
If we want to save changes made in DataTable of DataSet back to Data Base we need to call Update method on DataAdapter by passing the DataSet which contains modified values as a parameter. If Update method of DataAdapter has to work it should contain the 3 commands under it i.e. Insert, Update and Delete, these 3 commands have to be written by the programmers explicitly or can be generated implicitly with the help of CommandBuilder class. CommandBuilder class constructor if given with DataAdapter that contains a SelectCommand in it will generate the required 3 commands. 
Note: CommandBuilder can generate update and delete commands for a given select command only if the table contains Primary Key Constraints on it.
Under Save To DB Button:
cb = new SqlCommandBuilder(da); da.Update(ds, "Employee"); MessageBox.Show("Data saved to DB Server");
Under Close Button: this.Close();
Searching for a DataRow in DataTable of DataSet:
                To search for a DataRow in DataTable of DataSet call Find method on DataRowCollection this searches for the DataRow on Primary Key Column(s) of table and returns a Row.                    
                                Find(Object key) -> DataRow                             Find(Object[] keys) -> DataRow
Use the first method if the primary key constraint is present on a single column or else use the second method if it is a composite primary key.
Note: if the Find method has to work we need to first load the Primary Key information of table into DataSet by setting the property value as “AddWithKey” for MissingSchemanAction of DataAdapter.
Under Search Button:
string value = Interaction.InputBox("Enter Employee No.", "Employee Search", "", 150, 150);
if (value.Trim().Length > 0) {
   int eno = int.Parse(value); DataRow dr = ds.Tables[0].Rows.Find(eno);
   if (dr != null) {
      textBox1.Text = dr[0].ToString(); textBox2.Text = dr[1].ToString();
      textBox3.Text = dr[2].ToString(); textBox4.Text = dr[3].ToString();
   }
  else     {  MessageBox.Show("Employee does not exists for given Employee No."); }
 }


-----------------------------------------------------------------------------------------------------------------------------------------------
______________________________________________________________________________________________________





Configuration Files
                While developing applications if there are any values in application which requires changes in future, should not be hard coded i.e. should not be maintained as static values within the application, because if any changes are required for those values in future client will not be able to make changes because they will not have the source code of application for modification. To overcome this problem we need to identify those values and put them under a special file known as Configuration File, it’s an XML file which stores values in it in the form of Key/Value pairs. The values that are present under configuration file can be read from applications in runtime. We store values like Company Name, Address, Phone No, Fax No, connection strings etc., in these files. When an application is installed on the client machines along with it the configuration file also will be installed there and because the configuration file is a text file clients can edit those files and make modification to the values under them at any time and those values will be taken into the application for execution.

Note: Name of configuration file will be “app.config”, and it will be available implicitly under the project. If working with below versions of VS 2012 it should be explicitly added under the project, but before adding a configuration file under a project verify the availability of it in the project and if not present then only add it. To add a configuration file in the project open the “Add New Item” window and select the option “Application Configuration File” which adds a file with the name as app.config.

Storing values under configuration file: By default the file comes with a tag <configuration></configuration>, all the values must be present under that tag only by maintaining them under different sections as following:
<appSettings>
    <add key="Cname" value="Naresh I Technologies"/>
    <add key="Address" value="Ameerpet, Hyderabad - 38"/>
    <add key="Phone" value="23746666"/>
    <add key="Email" value="m.bangarraju@gmail.com"/>
</appSettings>
Reading configuration file values from applications: to read configuration file values from applications we are provided with a class ConfigurationManager within the namespace System.Configuration present under the assembly System.Configuration.dll. To consume the class we need to first add reference of the assembly using the “Add Reference” window and we find the assemblies under .Net Tab, after adding the reference of assembly import the namespace and read the values as following:
ConfigurationManager.AppSettings.Get(“<key>”)             ->      string (returns the value for given key as string)
                To test the above process add a configuration file in the project and store values in it as shown above within the <configuration>/<configurations> tags. Now add a new form in the project place a button on it setting the Text as “Read Configuration Values” and write the following code in code view:
using System.Configuration;         
Under Read Configuration Values Button:
string cname = ConfigurationManager.AppSettings.Get("Cname");
string addr = ConfigurationManager.AppSettings.Get("Address");
string phone = ConfigurationManager.AppSettings.Get("Phone");
string email = ConfigurationManager.AppSettings.Get("Email");
MessageBox.Show(cname + “\n” + addr + “\n” + phone + “\n” + email);
Storing Connection Strings under configuration files:
We can store the connection string values also in configuration files so that we don’t require to specify the connection strings in all forms and whenever we want to change it we can make the change directly under the configuration file. To store connection strings in the configuration file we are provided with a tag <connectionStrings> same as <appSettings> tag, so we can maintain the connection string values in the configuration file under <configuration> tag as following:
<connectionStrings>
<add name="OConStr" connectionString="User Id=Scott;Password=tiger;Data Source=<Server Name>"
providerName="Msdaora"/>
   <add name="SConStr" connectionString ="User Id=Sa;Password=<your password>;
Database=<Your DB Name>;Data Source=<Server Name>" providerName="SqlOledb"/>
 </connectionStrings>       
Note: we can read the connection string values from our application as following and use them:
string oconstr = ConfigurationManager.ConnectionStrings["OConStr"].ConnectionString;
string oprovider = ConfigurationManager.ConnectionStrings["OConStr"].ProviderName;
string sconstr = ConfigurationManager.ConnectionStrings["SConStr"].ConnectionString;
string sprovider = ConfigurationManager.ConnectionStrings["SConStr"].ProviderName;
DataGridView: this control is used for displaying the data in the form of a table i.e. rows and columns. To display data in the control first we need to bind the DataTable of DataSet to the GridView control by using its DataSource property as following:                              dataGridView1.DataSource = <datatable>
DataGridView control has a specialty i.e. changes performed to data in it gets reflected directly to the data of DataTable to which it was bound, so that we can update dataset back to database directly.








To test this process add a new Form in the project and place a DataGridView control on it setting its dock property as top. Now place 2 buttons on the form setting the text as Save and Close and write the code:
using System.Data.SqlClient; using System.Configuration;
Declarations: SqlConnection con; SqlDataAdapter da; SqlCommandBuilder cb; DataSet ds;
Under Form Load:
string constr = ConfigurationManager.ConnectionStrings["SConStr"].ConnectionString;
con = new SqlConnection(constr); ds = new DataSet();
da = new SqlDataAdapter("Select Eno, Ename, Job, Salary From Employee Order By Eno", con);
da.Fill(ds, "Employee"); dataGridView1.DataSource = ds.Tables[0];
Under Save Button:
cb = new SqlCommandBuilder(da); da.Update(ds, "Employee"); MessageBox.Show("Data saved to DB Server.");
Connecting with Oracle Database using Classes of System.Data.OracleClient Namespace:
                If we want to connect with Oracle Database using classes of OracleClient namespace we need to first add the reference of System.Data.OracleClient.dll.
Note: In VS 2010 we will not find that assembly by default in the add reference window so to get it into add reference window first you need to change the “Target Framework” of our project to .Net Framework 4, default will be .Net Framework 4 Client Profile and in this we cannot consume all assemblies of .net, after changing the target framework we can access all .net assemblies. To change target framework of project open project properties window and under that we find a ComboBox Target Framework showing different framework’s in which we can develop an application, select .Net Framework 4 and select “Yes” in the confirmation window.
Loading multiple tables into DataSet:
A DataSet can hold any no. of tables in it; if we want to load multiple tables into a Dataset we have 2 different approaches.
  1. Using a single DataAdapter we can load any no. of tables into the DataSet by changing the SelectCommand of adapter each time after calling Fill and loading a table into DataSet. In this approach if we want to make any changes to the data of dataset and send it back to database we can do it on last table of the dataset only because an adapter can hold all the 4 commands only for a single table i.e. for the last SelectCommand we have given only the required insert, update and delete commands will be generated by CommandBuilder class.
  2. Using a separate DataAdapter for each table being loaded into DataSet we can load multiple tables. In this approach it will be possible to update all the tables data, back to the database because each table is using an individual DataAdapter that will hold the required insert, update and delete commands for a table and more over here each table can also be loaded from a different data source i.e. 1 table from Oracle 1 table from Sql Server etc.
DataView: Just like we have Views in SQL, we have DataView object in ADO.Net. A DataView object represents a customized view of DataTable object. Operations like Sorting; Searching can be performed on a DataView object. In scenarios like retrieval of a subset of data from a DataTable, we can make use of DataView to get this data. Note that the DefaultView property of a DataTable returns the default data view for the DataTable.
Using a DataView for filtering or sorting the data under DataTable:
Step1: Create an object of class DataView by calling DefaultView property on the DataTable which will return a DataView object with same structure of the table on which the property is called.
E.g:         DataView dv = ds.Tables[“Emp”].DefaultView;
Step2: Specify a condition for filter by making use of the RowFilter property or specify a column for sorting the data using Sort property of DataView class.
E.g:         dv.RowFilter = “Job = ‘Manager’”; dv.RowFilter = “Sal > 2500”;
               dv.RowFilter = “Job = ‘Manager’ And Sal > 2500”;dv.RowFilter = “Job = ‘Manager’ Or Sal > 2500”;
dv.Sort = “Sal”; or dv.Sort = “Sal Desc”; dv.Sort = “Sal, Comm”; or dv.Sort = “Sal, Comm Desc”;
Loading multiple tables into a DataSet using single DataAdapter and filtering the data using DataView: Add a new form in the project, place a ComboBox control at top center, place a DataGridView control below and write the following code after adding the reference of System.Data.OracleClient.dll assembly.
using System.Data.OracleClient; using System.Configuration;
Declarations: OracleConnection con; OracleDataAdapter da; DataSet ds; bool flag = false;
Under Form Load: string constr = ConfigurationManager.ConnectionStrings["OConStr"].ConnectionString;
con = new OracleConnection(OConStr); ds = new DataSet();
da = new OracleDataAdapter(“Select * from Dept”, con); da.Fill(ds, “Dept”);
da.SelectCommand.CommandText = “Select * From Emp”; da.Fill(ds, “Emp”);
comboBox1.DataSource = ds.Tables[“Dept”]; comboBox1.DisplayMember = “Dname”;
comboBox1.ValueMember = “Deptno”; comboBox1.SelectedIndex = -1; comboBox1.Text = “Select a Department”;
 dataGridView1.DataSource = ds.Tables[“Emp”]; flag = true;
Under ComboBox SelectedIndexChanged:
if(flag) {
   DataView dv = ds.Tables[“Emp”].DefaultView; dv.RowFilter = “Deptno=” + comboBox1.SelectedValue;
   dv.Sort = “Sal” or dv.Sort = “Sal Desc”; or dv.Sort = “Sal, Comm”; or dv.Sort = “Sal, Comm Desc”;
}
Note: Just like we can bind a DataTable to DataGridView control in the same way it can also be bound to ComboBox and ListBox controls using DataSource property but these controls even if bound with the table they can display only a single column. So using DisplayMember property of the controls we need to specify which column has to be displayed. We can also bind another column of the table using ValueMember property of the controls but that column values will not be visible to end user where as  we can access them in code using SelectedValue property of control for the selected DisplayMember.
Loading multiple tables into a DataSet from different DataSources using multiple DataAdapter’s:
Add a new form in the project, place a SplitContainer on it which comes with 2 panels in it. Now place a button on each panel and set the dock property of button as top. Set the caption of the first button as “Save Data to Sql Server” and caption of second button as “Save Data to Oracle”. Then add a DataGridView control on each panel and set their dock property as Fill. Then write the following code:
using System.Data.SqlClient; using System.Data.OracleClient; using System.Configuration;
Declarations:
SqlConnection scon; SqlDataAdapter sda; SqlCommandBuilder scb;
OracleConnection ocon; OracleDataAdapter oda; OracleCommandBuilder ocb; DataSet ds;
Under Form Load:
string sconstr = ConfigurationManager.ConnectionStrings["SConStr"].ConnectionString;
string oconstr = ConfigurationManager.ConnectionStrings["OConStr"].ConnectionString;
scon=new SqlConnection(sconstr);   sda=new SqlDataAdapter("Select Eno,Ename,Job,Salary From Employee", scon);
ocon = new OracleConnection(oconstr);   oda = new OracleDataAdapter("Select * From Salgrade", ocon);
ds = new DataSet(); sda.Fill(ds, "Employee"); oda.Fill(ds, "Salgrade");
dataGridView1.DataSource = ds.Tables["Employee"];dataGridView2.DataSource = ds.Tables["Salgrade"];
Under Save Data to Sql Server Button:
scb=new SqlCommandBuilder(sda);sda.Update(ds, "Employee");MessageBox.Show("Data saved to Sql Server DB.");
Under Save Data to Oracle Button:
ocb=new OracleCommandBuilder(oda);oda.Update(ds, "Salgrade");MessageBox.Show("Data saved to Oracle DB.");
DataRelation:
DataRelation is used to relate two DataTable objects to each other through DataColumn objects. For example, in a Dept/Emp relationship, the Dept table is the parent and the Emp table is the child of the relationship. This is similar to a primary key/foreign key relationship. Relationships are created between matching columns in the parent and child tables. That is, the DataType value for both columns must be identical.

To use foreign key constraint we need a parent table that contains master data and a child table that contains detailed data corresponding to master data. Parent table should contain a Reference Key Column with a Primary Key or Unique Key Constraints imposed on it, and child table should contain a Foreign Key Column with Foreign Key Constraint imposed on it which refers into the values of Reference Key Column. If relationships are established between tables following rules comes into picture:
  1. Cannot store a value in the foreign key column of child table, provided the given value is not present in reference key column of parent table.
  2. Cannot delete a row from parent table provided the given reference key value of the record being deleted has child records in the child table without addressing what to do with the corresponding child records.
  3. Cannot update reference key value of the parent table provided the given reference key value being updated has child records in the child table without addressing what to do with the corresponding child records.

If we want to establish same type of relations between tables of a DataSet also, we can do it with the help of DataRelation class.                 DataRelation (string name, DataColumn RKcol, DataColumn FKcol)

After creating object of DataRelation it has to be added explictly to the DataSet under which tables were present using Relations.Add method of DataSet.    <dataset>.Relations.Add(DataRelation dr)

For deleting or updating reference key values in parent table if the reference key value has an child records in the child table some rules comes into picture for delete and update known as DeleteRules and UpdateRules, those are:
1. None: Cannot delete or update reference key value of parent table when corresponding child records exists in child table, this rule is applied by default under DB's.
2. Cascade: In this case we can delete or update reference key values of parent table, but the corresponding child records in child table will also be deleted or updated, this rule is applied by default in case of DataSet's.
3. Set Null: In this case also we can delete or update reference key values of parent table but the corresponding child records foreign key value changes to null.
4. Set Default:  This is same as Set Null, but in this case the corresponding child records foreign key value changes to default value of the column.
Note: we need to apply required rule for delete or update on DataRelation using following statements:
<datarelation>.ChildKeyConstraint.DeleteRule = Rule.<rule>;
<datarelation>.ChildKeyConstraint.UpdateRule = Rule.<rule>;
To use SetDefault rule first we need to set a default value for foreign column using the following statement:                                <datatable>.Columns[name].DefaultValue=<value>
Loading multiple tables into a DataSet and establishing relation between the tables:
Add a new form in the project, place a SplitContainer on it and change the Orientation property of the control as Horizontal so that the panels under the SplitContainer will be horizontally aligned (default is vertical). Place a DataGridView control on each panel and set their Dock property as Fill. Now write the following code:
using System.Data.OracleClient; using System.Configuration;
Declarations: OracleConnection con; OracleDataAdapter da1, da2; DataSet ds; DataRelation dr;
Under Form Load: string constr = ConfigurationManager.ConnectionStrings[OSConStr"].ConnectionString;
con = new OracleConnection(constr); ds = new DataSet();
da1 = new OracleDataAdapter(“Select * From Dept”, con); da1.Fill(ds, "Dept");
da2 = new OracleDataAdapter(“Select * From Emp”, con); da2.Fill(ds, "Emp");
dr = new DataRelation("EmpDept", ds.Tables[“Dept”].Columns["Deptno"], ds.Tables[“Emp”].Columns["Deptno"]);
ds.Relations.Add(dr);
dr.ChildKeyConstraint.DeleteRule = Rule.None; dr.ChildKeyConstraint.UpdateRule = Rule.None; 
dataGridView1.DataSource = ds.Tables["Dept"]; dataGridView2.DataSource = ds.Tables["Emp"];
Note: Use the following statement if required for setting a default value to foreign key column:
ds.Tables["Emp"].Columns["Deptno"].DefaultValue = 40;
Establishing relations between tables of DataSet and displaying data in Parent/Child view:
It is possible to establish relations between tables of a DataSet and display the data in Parent/Child view with the help of a class known as BindingSource to test this add a new form in the project, place a SplitContainer on it and change the Orientation property as Horizontal. Place a DataGridView control on each panel and set their Dock property as Fill. Now write the following code:
using System.Data.OracleClient; using System.Configuration;
Declarations: OracleConnection con; OracleDataAdapter da1, da2; DataSet ds;
Under Form Load: string constr = ConfigurationManager.ConnectionStrings["OConStr"].ConnectionString;
con = new OracleConnection(constr);
da1=new OracleDataAdapter("Select * From Dept", con); da2=new OracleDataAdapter("Select * From Emp", con);
ds = new DataSet(); da1.Fill(ds, "Dept"); da2.Fill(ds, "Emp");
ds.Relations.Add("MasterDetail",ds.Tables[0].Columns["Deptno"],ds.Tables[1].Columns["Deptno"]);
BindingSource bsDept = new BindingSource(); bsDept.DataSource = ds; bsDept.DataMember = "Dept";
BindingSource bsEmp = new BindingSource(); bsEmp.DataSource = bsDept; bsEmp.DataMember = "MasterDetail";
dataGridView1.DataSource = bsDept; dataGridView2.DataSource = bsEmp;
Major Differences between DataSet and DataReader:                   
  • DataSet is disconnected architecture while DataReader has live connection while reading data.
  • If we want to cache data and pass to a different tier DataSet’s will be the best choice.
  • If we want to move back while reading records, DataReader does not support this functionality.




  • One of the biggest drawbacks of DataSet is speed as DataSet carry considerable overhead because of relations; multiple tables’ etc speed is slower than DataReader, so always try to use DataReader where ever possible as it’s meant especially for speed performance.
Communication with Data Sources using ODBC Drivers
In the case of Oledb, SqlClient and OracleClient classes we use providers for Data Source communication where as in case of Odbc classes we use drivers for Data Source communication. Providers will be on server side so within the connection string if we specify the provider name along with other details like server name, user id, password we can communication with data sources, whereas drivers will be sitting on client machines so to use them first we need to configure the appropriate driver with data source and then from our application using Odbc classes we should communicate with drivers which will in turn communicate with the data sources.
Odbc offers different drivers for connecting with different data sources which comes along with OS, to use them first we need to configure an appropriate driver to its specific data source by supplying all the required connection details and they are stored internally with a name known as DSN (Data Source Name), this should be specified by us only while configuring with the driver. After configuring the DSN, we can use that DSN in our .net app so that Odbc Classes can talk with the Data Source making use of the driver that has been configured as following:
OdbcConnection con = new OdbcConnection("Dsn=<name of the dsn we have created>");
Configuring a DSN: to configure DSN go to Control Panel -> Administrative Tools -> Data Sources (ODBC), click on it to open 'ODBC Data Source Administrator' window. In the window opened click on Add button -> choose a driver for Oracle or Sql Server or MS Excel etc., and click Finish, which opens a window in that first enter a name for DSN and then supply connection details like User Id, Password, Database, Server etc., and Click finish, which adds DSN in Data Source Administrator window.
Configuring a DSN with Sql Server and Oracle Databases:
Open ODBC Data Source Administrator window, click on Add button, select a driver for Sql Server and click Finish button, which opens a window, in it enter the following details, Name: SqlDsn, Description: Connects with Sql Server Database, Server: <Server Name>, click on Next button, select the RadioButton “Using Sql Server Authentication”, enter the Login ID: <User Name>, Password: <Pwd>, click on Next button, select the CheckBox “Change the default database to”, and select the Database to which we want to configure with below, click on Next button and Click on Finish button which displays a window showing the connection details, click on Ok button which adds the DSN under ODBC Data Source Administrator window.
Again click on Add button, select a driver for Oracle and click Finish button, which opens a window, in it enter the following details, Data Source Name: OraDsn, Description: Connects with Oracle Database, TNS Service Name: <Server Name>, User ID: Scott/tiger, click on Ok button which adds the DSN under ODBC Data Source Administrator window.
                Now add a new form in the Project place 2 buttons on it and set their caption as “Connect with Oracle using ODBC Driver” and “Connect with Sql Server using ODBC Driver”. Go to code view and write the following code:
using System.Data.Odbc;
Declarations: OdbcConnection ocon, scon;
Under Connect with Oracle using ODBC Driver: ocon = new OdbcConnection(“Dsn=OraDsn”);
ocon.Open(); MessageBox.Show(ocon.State.ToString()); ocon.Close(); MessageBox.Show(ocon.State.ToString());
Under Connect with Sql Server using ODBC Driver: scon = new OdbcConnection(“Dsn=SqlDsn”);
scon.Open(); MessageBox.Show(scon.State.ToString()); scon.Close(); MessageBox.Show(scon.State.ToString());
Accessing MS Excel data from .Net Application
MS Excel is a file system which stores data in the form of rows and columns same as a database table. An Excel document is referred as Work Book that contains Work Sheets in it, work books are considered as databases and work sheets are considered as tables. First row of work sheet can store column names. 
Creating an Excel document: 
Go to Start Menu -> Programs -> Microsoft Office -> Microsoft Office Excel, click on it to open, by default the document contains 3 work sheets in it. Now in the first row of the sheet1 enter column names for Student table as Sno, Sname, Class, Fees and from the second row enter few records in it.  Now in bottom of the document change the sheet name Sheet1 as Student and select ‘Save As’ choose ‘Excel 97 – 2003 Workbook’, name the document as School.xls in your desired location.
Connecting with Excel document from .Net Application:
We can connect with Excel documents from .Net application by using Drivers or Providers also. To connect with drivers first we need to configure ODBC driver for Excel. To configure driver go to Start Menu -> Control Panel -> Administrative Tools -> Data Sources (ODBC), click on it to open ODBC Data Source Administrator window, Click Add button, select Microsoft Excel (*.xls) driver, Click finish and Enter the following details, Data Source Name: ExcelDsn, Description: Connects with Excel document, and click on Select Workbook button to choose the School.xls document from it physical location and click on the Ok button which adds the DSN under ODBC Data Source Administrator window. Now add a new windows form in the project and design it as following:







using System.Data.ODBC;
Declarations:  ODBCConnection con; ODBCCommand cmd; ODBCDataReader dr; string SqlStr;
Under Form Load:
con = new ODBCConnection("Dsn=ExcelDsn;ReadOnly=0");
cmd = new ODBCCommand(); cmd.Connection = con; con.Open(); LoadData();
label1.Text=dr.GetName(0); label2.Text=dr.GetName(1); label3.Text=dr.GetName(2); label4.Text=dr.GetName(3);
private void LoadData() {
  cmd.CommandText = "Select * From [Student$]"; dr = cmd.ExecuteReader(); ShowData();
}
private void ShowData() {
  if (dr.Read()) {
    textBox1.Text = dr[0].ToString(); textBox2.Text = dr[1].ToString();
    textBox3.Text = dr[2].ToString(); textBox4.Text = dr[3].ToString();
  }
  else
    MessageBox.Show("No data exists.”);
}
Under Next Button: ShowData();
Under Clear Button: textBox1.Text=textBox2.Text=textBox3.Text=textBox4.Text = ""; textBox1.Focus();
private void ExecuteDML() {
dr.Close(); cmd.CommandText = SqlStr;
if (cmd.ExecuteNonQuery() > 0)                     MessageBox.Show("Insert Or Update operation was successful.");
else                                                                     MessageBox.Show("Insert or Update operation failed.");
LoadData();
}
Under Insert Button: sqlstr = String.Format(“Insert Into [Student$] Values ({0}, ‘{1}’ {2}, {3})”, textBox1.Text, textBox2.Text, textBox3.Text, textBox4.Text); dr.Close(); ExecuteDML();
Under Update Button: sqlstr = String.Format(“Update [Student$] Set Sname='{0}’, Class={1}, Fees={2} where Sno={3}”, textBox2.Text, textBox3.Text, textBox4.Text, textBox1.Text);  ExecuteDML();
Under Close Button: this.Close();
Connecting with Excel using OLEDB Provider:
To connect with Excel documents using OLEDB Provider, Connection String is should be as following:
"Provider=Microsoft.Jet.Oledb.4.0; Data Source=<path of excel file>; Extended Properties=Excel 8.0"

Note: OdbcConnection class opens connection with Excel Document in read only mode so if we want to perform any manipulations to data in the document we need to open it in read/write mode by setting the attribute “readonly=0” under the connection string, whereas OledbConnection will open the document in read/write mode only so no need of using readonly attribute there.
Stored Procedures
Whenever we want to interact with a database from an application we use sql stmts. When we use sql statements within the application we have a problem i.e. when the application runs sql Statements will be sent to db for execution where the stmts will be parsed (compile) and then executed. The process of parsing takes place each time we run the application, because of this performance of our application decreases. To overcome the above drawback write sql statements directly under db only, with in an object known as Stored Procedure and call them for execution. As a SP is a pre-compiled block of code that is ready for execution will directly execute the statements without parsing each time.







Syntax to define a Stored Procedure:
Create Procedure <Name> [ (<parameter definitions) ]
As
Begin
                <Stmts>
End
·         SP’s is similar to a method in our language. 
public void Test()                                                                  //Method
Create Procedure Test()                                                      //Stored Procedure
·         If required we can also define parameters but only optional. If we want to pass parameters to a Sql Server SP prefix the special character “@” before parameter name.
public void Test(int x)                                                          //CSharp
Create Procedure Test(x number)                                     //Oracle
Create Procedure Test(@x int)                                          //Sql Server
·         A SP can also return values, to return a value we use out clause in Oracle and Output clause in Sql Server.
public void Test(int x, ref int y)                                          //CSharp
Create Procedure Test(x number, y out number)          //Oracle
Create Procedure Test(@x int, @y int output)              //Sql Server
Creating a Stored Procedure:
We can create a SP in Sql Server either by using Sql Server Management Studio or Visual Studio.Net also. To create a SP from Visual Studio first we need to configure our Database under Server Explorer, to do this go to view menu, select Server Explorer which gets launched on LHS of the studio. To configure it right click on the node “Data Connections”, select “Add Connection” which opens a window asking to choose a Data Source select MS Sql Server, click ok, which opens “Add Connection” window and under it provide the following details:
1.       Server  Name: <Name of the Server>
2.       Authentication: Windows or Sql Server (provide User Name and Password)
3.       Database: <DB Name>
Click on the OK button which adds the DB under Server Explorer, expand it, and right click on the node Stored Procedures, select “Add New Stored Procedure” which opens a window and write the following:
                Create Procedure Employee_Select
                As
                   Select Eno, Ename, Job, Salaray, From Employee       
-Now right click on the document window and select execute which will create the procedure on Database Server.
Calling a SP from .Net application: if we want to call a SP from .net application we use DataAdapter class if it is a Select SP to load data into a DataSet or else we can use Command class if the SP is of any operation but here if it is Select SP we can load data either into a DataReader or DataSet also. To call the SP we adopt the below process:
Step 1: Create an object of class Command or DataAdapter by passing SP name as argument to their constructor.
DataAdapter da = new DataAdapter(“Employee_Select”, con);
                                                                                or
Command cmd = new Command (“Employee_Select”, con);
Step 2: Change the CommandType property of SelectCommand of DataAdapter object or CommandType property of Command object as StoredProcedure because by default CommandType property is configured to execute Sql Statements only after changing the property we can call Stored Procedures.
                da.SelectCommand.CommandType = CommandType.StoredProcedure;
                                                                                or
                cmd.CommandType = CommandType.StoredProcedure;
Step 3: If the SP has any parameters we need to pass values to those parameters by adding the parameters with their corresponding values under SelectCommand of DataAdapter or Command.
Step 4: To call the Select SP using DataAdapter we can directly call Fill method on DataAdapter object and load data into DataSet. If we want to call Select SP using Command call the ExecuteReader() method on Command object so that data gets loaded into a DataReader or else if we want to load the data into a DataSet create object of DataAdapter by passing this command object as a parameter and then call Fill method on DataAdapter. If the SP contains any non-query operations like Insert or Update or Delete then call ExecuteNonQuery method on command to execute the SP.
Calling above Stored Procedure using DataAdapter: In a new form place a DataGridView and write below code:
using System.Configuration; using System.Data.SqlClient;
Declarations: SqlConnection con; SqlDataAdapter da; DataSet ds;
Under Form Load: string constr = ConfigurationManager.ConnectionStrings["SConStr"].ConnectionString;
con = new SqlConnection(constr); da = new SqlDataAdapter(“Employee_Select”, con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
ds = new DataSet(); da.Fill(ds, “Employee”); dataGridView1.DataSource = ds.Tables[0];
Calling the above Stored Procedure using Command: take a new form and design it as following.










using System.Configuration; using System.Data.SqlClient;
Declarations: SqlConnection con; SqlCommand cmd; SqlDataReader dr;
Under Form Load: string constr = ConfigurationManager.ConnectionStrings["SConStr"].ConnectionString;
con = new SqlConnection(constr); cmd = new SqlCommand("Employee_Select", con);
cmd.CommandType = CommandType.StoredProcedure; con.Open(); dr = cmd.ExecuteReader(); ShowData();
label1.Text = dr.GetName(0); label2.Text = dr.GetName(1);
label3.Text = dr.GetName(2); label4.Text = dr.GetName(3);
private void ShowData()    {
 if (dr.Read()) {
  textBox1.Text = dr[0].ToString(); textBox2.Text = dr[1].ToString();
  textBox3.Text = dr[2].ToString(); textBox4.Text = dr[3].ToString();
 }
 else       
  MessageBox.Show("Last record of the table");
}
Under Next Button: ShowData();
Parameters to Stored Procedures:
SP can be defined with parameters either to send values for execution or receiving values after execution. While calling a SP with parameters from .net application for each parameter of the SP we need to add a matching parameter either under Command or DataAdapter i.e. for input parameter matching input parameter has to be added and for output parameter a matching output parameter has to be added. Every parameter that is added to Command or DataAdapter has 5 attributes to it like Name, Value, DbType, Size and Direction which can be Input(d) or Output or InputOutput (in case of oracle only).
·         Name refers to name of the parameter that is defined in SP.
·         Value refers to value being assigned in case of input or value we are expecting in case of output.
·         DbType refers to data type of the parameter in terms of the DB where the SP exists.
·         Size refers to size of data.
·         Direction specifies whether parameter is Input or Output or InputOutput.
If a SP has Input or Output parameters we need to specify the following attributes while adding parameters to Command or DataAdapter:

                        Input                      Output                   InputOutput
Name                      Yes                            Yes                               Yes
Value                      Yes                             No                               Yes
DbType                    No                            Yes                               Yes
Size                          No                            Yes                               Yes                  [Only in case of variable length types]
Direction                 No                            Yes                               Yes
Adding Input Parameter under .Net Application:
da.SelectCommand.Parameters.AddWithValue(string <pname>, object <pvalue>);
                                                                or
cmd.Parameters.AddWithValue(string <pname>, object <pvalue>);
Adding Output Parameter under .Net Application:
da.SelectCommand.Parameters.Add(string <pname>, <dbtype>).Direction = ParameterDirection.Output;
                                                                                                                or
cmd.Parameters.Add(string <pname>, <dbtype>).Direction = ParameterDirection.Output;
Adding Output parameter with size if it is a variable length type:
da.SelectCommand.Parameters.Add(string <pname>, <dbtype>, int <size>).Direction = ParameterDirection.Output;
                                                                                                                or
cmd.Parameters.Add(string <pname>, <dbtype>, int <size>).Direction = ParameterDirection.Output;
After executing the SP we can capture Output parameter values as following:
Object obj = da.SelectCommand.Parameters[<pname>].Value;
                                or
Object obj = cmd.Parameters[<pname>].Value;
Performing Select and DML Operations using Stored Procedures:
To perform select, insert, update and delete operations using SP’s first define the following procedures in Database.
Alter PROCEDURE Employee_Select (@Eno Int=Null, @Status bit=Null)
As
Begin
  If @Eno Is Null And @Status Is Null
    Select Eno, Ename, Job, Salary, Status From Employee
  Else If @Eno Is Null
    Select Eno, Ename, Job, Salary, Status From Employee Where Status=@Status
  Else
    Select Eno, Ename, Job, Salary, Photo From Employee Where Eno=@Eno And Status=@Status
End
Create Procedure Employee_Insert(@Ename Varchar(50), @Job Varchar(50), @Salary Money, @Photo Image, @Eno Int Output)
As
Begin
  Select @Eno = IsNull(Max(Eno), 1000) + 1 From Employee
  Insert Into Employee (Eno, Ename, Job, Salary, Photo) Values (@Eno, @Ename, @Job, @Salary, @Photo)
End
Create Procedure Employee_Update(@Eno Int, @Ename Varchar(50), @Job Varchar(50), @Salary Money, @Photo Image)
As
  Update Employee Set Ename=@Ename, Job=@Job, Salary=@Salary, Photo=@Photo Where Eno=@Eno       
CREATE PROCEDURE Employee_Delete (@Eno Int)
As
  Update Employee Set Status=0 Where Eno=@Eno
Take a new form, design it as following by adding an OpenFileDialog control and then write below code:




using System.Configuration; using System.Data.SqlClient;
Declarations: SqlConnection con; SqlCommand cmd; SqlDataReader dr;
Under Form Load: string constr = ConfigurationManager.ConnectionStrings["SConStr"].ConnectionString;
con = new SqlConnection(constr); cmd = new SqlCommand("Employee_Select", con);
cmd.CommandType = CommandType.StoredProcedure; con.Open(); dr = cmd.ExecuteReader(); ShowData();
label1.Text = dr.GetName(0); label2.Text = dr.GetName(1);
label3.Text = dr.GetName(2); label4.Text = dr.GetName(3);
private void ShowData()    {
 if (dr.Read()) {
  textBox1.Text = dr[0].ToString(); textBox2.Text = dr[1].ToString();
  textBox3.Text = dr[2].ToString(); textBox4.Text = dr[3].ToString();
 }
 else       
  MessageBox.Show("Last record of the table");
}
Under Next Button: ShowData();
Parameters to Stored Procedures:
SP can be defined with parameters either to send values for execution or receiving values after execution. While calling a SP with parameters from .net application for each parameter of the SP we need to add a matching parameter either under Command or DataAdapter i.e. for input parameter matching input parameter has to be added and for output parameter a matching output parameter has to be added. Every parameter that is added to Command or DataAdapter has 5 attributes to it like Name, Value, DbType, Size and Direction which can be Input(d) or Output or InputOutput (in case of oracle only).
·         Name refers to name of the parameter that is defined in SP.
·         Value refers to value being assigned in case of input or value we are expecting in case of output.
·         DbType refers to data type of the parameter in terms of the DB where the SP exists.
·         Size refers to size of data.
·         Direction specifies whether parameter is Input or Output or InputOutput.
If a SP has Input or Output parameters we need to specify the following attributes while adding parameters to Command or DataAdapter:

                        Input                      Output                   InputOutput
Name                      Yes                            Yes                               Yes
Value                      Yes                             No                               Yes
DbType                    No                            Yes                               Yes
Size                          No                            Yes                               Yes                  [Only in case of variable length types]
Direction                 No                            Yes                               Yes
Adding Input Parameter under .Net Application:
da.SelectCommand.Parameters.AddWithValue(string <pname>, object <pvalue>);
                                                                or
cmd.Parameters.AddWithValue(string <pname>, object <pvalue>);
Adding Output Parameter under .Net Application:
da.SelectCommand.Parameters.Add(string <pname>, <dbtype>).Direction = ParameterDirection.Output;
                                                                                                                or
cmd.Parameters.Add(string <pname>, <dbtype>).Direction = ParameterDirection.Output;
Adding Output parameter with size if it is a variable length type:
da.SelectCommand.Parameters.Add(string <pname>, <dbtype>, int <size>).Direction = ParameterDirection.Output;
                                                                                                                or
cmd.Parameters.Add(string <pname>, <dbtype>, int <size>).Direction = ParameterDirection.Output;
After executing the SP we can capture Output parameter values as following:
Object obj = da.SelectCommand.Parameters[<pname>].Value;
                                or
Object obj = cmd.Parameters[<pname>].Value;
Performing Select and DML Operations using Stored Procedures:
To perform select, insert, update and delete operations using SP’s first define the following procedures in Database.
Alter PROCEDURE Employee_Select (@Eno Int=Null, @Status bit=Null)
As
Begin
  If @Eno Is Null And @Status Is Null
    Select Eno, Ename, Job, Salary, Status From Employee
  Else If @Eno Is Null
    Select Eno, Ename, Job, Salary, Status From Employee Where Status=@Status
  Else
    Select Eno, Ename, Job, Salary, Photo From Employee Where Eno=@Eno And Status=@Status
End
Create Procedure Employee_Insert(@Ename Varchar(50), @Job Varchar(50), @Salary Money, @Photo Image, @Eno Int Output)
As
Begin
  Select @Eno = IsNull(Max(Eno), 1000) + 1 From Employee
  Insert Into Employee (Eno, Ename, Job, Salary, Photo) Values (@Eno, @Ename, @Job, @Salary, @Photo)
End
Create Procedure Employee_Update(@Eno Int, @Ename Varchar(50), @Job Varchar(50), @Salary Money, @Photo Image)
As
  Update Employee Set Ename=@Ename, Job=@Job, Salary=@Salary, Photo=@Photo Where Eno=@Eno       
CREATE PROCEDURE Employee_Delete (@Eno Int)
As
  Update Employee Set Status=0 Where Eno=@Eno
Take a new form, design it as following by adding an OpenFileDialog control and then write below code:

using System.Configuration; using System.Data.SqlClient;
Declarations: SqlConnection con; SqlCommand cmd; SqlDataReader dr;
Under Form Load: string constr = ConfigurationManager.ConnectionStrings["SConStr"].ConnectionString;
con = new SqlConnection(constr); cmd = new SqlCommand("Employee_Select", con);
cmd.CommandType = CommandType.StoredProcedure; con.Open(); dr = cmd.ExecuteReader(); ShowData();
label1.Text = dr.GetName(0); label2.Text = dr.GetName(1);
label3.Text = dr.GetName(2); label4.Text = dr.GetName(3);
private void ShowData()    {
 if (dr.Read()) {
  textBox1.Text = dr[0].ToString(); textBox2.Text = dr[1].ToString();
  textBox3.Text = dr[2].ToString(); textBox4.Text = dr[3].ToString();
 }
 else       
  MessageBox.Show("Last record of the table");
}
Under Next Button: ShowData();
Parameters to Stored Procedures:
SP can be defined with parameters either to send values for execution or receiving values after execution. While calling a SP with parameters from .net application for each parameter of the SP we need to add a matching parameter either under Command or DataAdapter i.e. for input parameter matching input parameter has to be added and for output parameter a matching output parameter has to be added. Every parameter that is added to Command or DataAdapter has 5 attributes to it like Name, Value, DbType, Size and Direction which can be Input(d) or Output or InputOutput (in case of oracle only).
·         Name refers to name of the parameter that is defined in SP.
·         Value refers to value being assigned in case of input or value we are expecting in case of output.
·         DbType refers to data type of the parameter in terms of the DB where the SP exists.
·         Size refers to size of data.
·         Direction specifies whether parameter is Input or Output or InputOutput.
If a SP has Input or Output parameters we need to specify the following attributes while adding parameters to Command or DataAdapter:

                        Input                      Output                   InputOutput
Name                      Yes                            Yes                               Yes
Value                      Yes                             No                               Yes
DbType                    No                            Yes                               Yes
Size                          No                            Yes                               Yes                  [Only in case of variable length types]
Direction                 No                            Yes                               Yes
Adding Input Parameter under .Net Application:
da.SelectCommand.Parameters.AddWithValue(string <pname>, object <pvalue>);
                                                                or
cmd.Parameters.AddWithValue(string <pname>, object <pvalue>);
Adding Output Parameter under .Net Application:
da.SelectCommand.Parameters.Add(string <pname>, <dbtype>).Direction = ParameterDirection.Output;
                                                                                                                or
cmd.Parameters.Add(string <pname>, <dbtype>).Direction = ParameterDirection.Output;
Adding Output parameter with size if it is a variable length type:
da.SelectCommand.Parameters.Add(string <pname>, <dbtype>, int <size>).Direction = ParameterDirection.Output;
                                                                                                                or
cmd.Parameters.Add(string <pname>, <dbtype>, int <size>).Direction = ParameterDirection.Output;
After executing the SP we can capture Output parameter values as following:
Object obj = da.SelectCommand.Parameters[<pname>].Value;
                                or
Object obj = cmd.Parameters[<pname>].Value;
Performing Select and DML Operations using Stored Procedures:
To perform select, insert, update and delete operations using SP’s first define the following procedures in Database.
Alter PROCEDURE Employee_Select (@Eno Int=Null, @Status bit=Null)
As
Begin
  If @Eno Is Null And @Status Is Null
    Select Eno, Ename, Job, Salary, Status From Employee
  Else If @Eno Is Null
    Select Eno, Ename, Job, Salary, Status From Employee Where Status=@Status
  Else
    Select Eno, Ename, Job, Salary, Photo From Employee Where Eno=@Eno And Status=@Status
End
Create Procedure Employee_Insert(@Ename Varchar(50), @Job Varchar(50), @Salary Money, @Photo Image, @Eno Int Output)
As
Begin
  Select @Eno = IsNull(Max(Eno), 1000) + 1 From Employee
  Insert Into Employee (Eno, Ename, Job, Salary, Photo) Values (@Eno, @Ename, @Job, @Salary, @Photo)
End
Create Procedure Employee_Update(@Eno Int, @Ename Varchar(50), @Job Varchar(50), @Salary Money, @Photo Image)
As
  Update Employee Set Ename=@Ename, Job=@Job, Salary=@Salary, Photo=@Photo Where Eno=@Eno       
CREATE PROCEDURE Employee_Delete (@Eno Int)
As
  Update Employee Set Status=0 Where Eno=@Eno
Take a new form, design it as following by adding an OpenFileDialog control and then write below code:








using System.Configuration; using System.IO; using System.Data.SqlClient; using Microsoft.VisualBasic;
Declarations: SqlConnection con; SqlCommand cmd; SqlDataAdapter da; DataSet ds;
string imgPath=””; byte[] data = null;
Under Form Load: string constr = ConfigurationManager.ConnectionStrings["SConStr"].ConnectionString;
con = new SqlConnection("ConStr"); cmd = new SqlCommand();
cmd.Connection = con; cmd.CommandType = CommandType.StoredProcedure;
Under Select Button: int Eno = int.Parse(Interaction.InputBox("Enter an Employee No."));
cmd.Parameters.Clear(); cmd.CommandText = "Employee_Select"; ds = new DataSet();
cmd.Parameters.AddWithValue("@Eno", Eno); cmd.Parameters.AddWithValue("@Status", true);
da = new SqlDataAdapter(cmd); da.Fill(ds, "Employee");
if (ds.Tables[0].Rows.Count > 0) {
  textBox1.Text = ds.Tables[0].Rows[0][0].ToString(); textBox2.Text = ds.Tables[0].Rows[0][1].ToString();
  textBox3.Text = ds.Tables[0].Rows[0][2].ToString(); textBox4.Text = ds.Tables[0].Rows[0][3].ToString();
  if (ds.Tables[0].Rows[0][4] != System.DBNull.Value) {
    data = (byte[])ds.Tables[0].Rows[0][4];   
    MemoryStream ms = new MemoryStream(data);
    pictureBox1.Image = Image.FromStream(ms);
  }
 else { pictureBox1.Image = null; }
}
 else
    MessageBox.Show("Employee doesn't exist, please check the given employee number.", "Warning",
                                                MessageBoxButtons.OK, MessageBoxIcon.Warning);
Under Clear Button:
textBox1.Text = textBox2.Text = textBox3.Text = textBox4.Text = "";
pictureBox1.Image = null; data = null; imgPath = ""; textBox2.Focus();
Under Insert Button:
try {
  cmd.Parameters.Clear(); cmd.CommandText = "Employee_Insert";
  cmd.Parameters.AddWithValue("@Ename", textBox2.Text);
  cmd.Parameters.AddWithValue("@Job", textBox3.Text);
  cmd.Parameters.AddWithValue("@Salary", textBox4.Text);
  if(imgPath.Trim().Length > 0) {
   
atabase-----
------------------------------------------------------------------------------------------------------------------data = File.ReadAllBytes(imgPath); cmd.Parameters.AddWithValue("@Photo", data);
  }
  else {
    cmd.Parameters.AddWithValue("@Photo", DBNull.Value);
   cmd.Parameters["@Photo"].SqlDbType = SqlDbType.Image;
  }
  cmd.Parameters.Add("@Eno", SqlDbType.Int).Direction = ParameterDirection.Output;
  con.Open(); cmd.ExecuteNonQuery();
  textBox1.Text = cmd.Parameters["@Eno"].Value.ToString();
}
catch (Exception ex)
 {  MessageBox.Show(ex.Message, "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error);  }
finally {  con.Close();  imgPath = “”; data = null; }
Under Update Button:
try {
  cmd.Parameters.Clear(); cmd.CommandText = "Employee_Update";
  cmd.Parameters.AddWithValue("@Eno", textBox1.Text);
  cmd.Parameters.AddWithValue("@Ename", textBox2.Text);
  cmd.Parameters.AddWithValue("@Job", textBox3.Text);
  cmd.Parameters.AddWithValue("@Salary", textBox4.Text);
  if (imgPath.Trim().Length == 0 && data == null) {
    cmd.Parameters.AddWithValue("@Photo", DBNull.Value);
    cmd.Parameters["@Photo"].SqlDbType = SqlDbType.Image;
  }
  else if (imgPath.Trim().Length > 0) {
    data = File.ReadAllBytes(imgPath);
    cmd.Parameters.AddWithValue("@Photo", data);
  }
  else if (data != null) {
    cmd.Parameters.AddWithValue("@Photo", data);
  }
  con.Open(); cmd.ExecuteNonQuery();
  MessageBox.Show("Record updated under the database table.", "Information Message", MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
catch (Exception ex)
{ MessageBox.Show(ex.Message, "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error); }
finally { con.Close(); imgPath = ""; data = null; }
Under Delete Button:
try {
  cmd.Parameters.Clear(); cmd.CommandText = "Employee_Delete";
  cmd.Parameters.AddWithValue("@Eno", textBox1.Text);
  con.Open(); cmd.ExecuteNonQuery(); btnClear.PerformClick();
  MessageBox.Show("Record deleted under the database table.", "Sql Message", MessageBoxButtons.OK,
 MessageBoxIcon.Information);
}
 catch (Exception ex)
 {  MessageBox.Show(ex.Message, "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error); }
finally {  con.Close();  }
Note: when we call PerformClick() method on a button internally the Click of that button occurs.
Under Load Image Button:
openFileDialog1.Filter = "Jpeg Images (*.jpg)|*.jpg|Bitmap Images (*.bmp)|*.bmp|All Files (*.*)|*.*";
DialogResult dr = openFileDialog1.ShowDialog();
if (dr == DialogResult.OK) {
  imgPath = openFileDialog1.FileName; pictureBox1.ImageLocation = imgPath;
}              
Create a new form as below for accessing all, active and in-active records from the table using select SP.







using System.Configuration; using System.Data.SqlClient;
Declarations: SqlConnection con; SqlDataAdapter da; DataSet ds;
Under Select Button: string constr = ConfigurationManager.ConnectionStrings["SConStr"].ConnectionString;
con = new SqlConnection(constr); da = new SqlDataAdapter("Employee_Select", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure; comboBox1.SelectedIndex = 0;  
Under ComboBox SelectedIndexChanged: da.SelectCommand.Parameters.Clear();           
if (comboBox1.SelectedIndex == 1) { da.SelectCommand.Parameters.AddWithValue("@Status", true); }
else if(comboBox1.SelectedIndex == 2) { da.SelectCommand.Parameters.AddWithValue("@Status", false); }
ds = new DataSet(); da.Fill(ds, "Employee"); dataGridView1.DataSource = ds.Tables[0];
Creating a SP with both Input and Output parameters:
Create a SP under Sql Server DB which takes the Employee No. and returns the Salary, Provident Fund, Professional Tax and Net Salary of the Employee by performing the calculations. In this case writing the logic under the SP provides an advantage of making the changes easier in the future if required.
CREATE PROCEDURE Employee_GetSalDetails (@Eno Int, @Salary Money Output, @PF Money Output, @PT Money Output, @NetSal Money Output)
As
Begin
  Select @Salary = Salary From Employee Where Eno = @Eno And Status = 1;
  Set @PF = @Salary * 0.12; Set @PT = @Salary * 0.05; Set @NetSal = @Salary - (@PF + @PT);
End
Calling the above Stored Procedure: Create a new form as following & set read-only of 2nd to 5th textbox’s as true.





using System.Data.SqlClient;
Declarations: SqlConnection con; SqlCommand cmd;
Under Form Load: string constr = ConfigurationManager.ConnectionStrings["SConStr"].ConnectionString;
con = new SqlConnection(constr); cmd = new SqlCommand("Employee_GetSalDetails",con);
cmd.CommandType = CommandType.StoredProcedure;
Under Execute Button:
 try {
  cmd.Parameters.Clear(); cmd.Parameters.AddWithValue("@Eno", textBox1.Text);
  cmd.Parameters.Add("@Salary", SqlDbType.Money).Direction = ParameterDirection.Output;
  cmd.Parameters.Add("@PF", SqlDbType.Money).Direction = ParameterDirection.Output;
  cmd.Parameters.Add("@PT", SqlDbType.Money).Direction = ParameterDirection.Output;
  cmd.Parameters.Add("@NetSal", SqlDbType.Money).Direction = ParameterDirection.Output;
  con.Open(); cmd.ExecuteNonQuery();
  textBox2.Text = cmd.Parameters["@Salary"].Value.ToString();
  textBox3.Text=cmd.Parameters["@PF"].Value.ToString();   
  textBox4.Text=cmd.Parameters["@PT"].Value.ToString();
  textBox5.Text = cmd.Parameters["@NetSal"].Value.ToString();
}
 catch (Exception ex)
{  MessageBox.Show(ex.Message, "Error Message", MessageBoxButtons.OK, MessageBoxIcon.Error);  }
finally { con.Close(); }
Under Close Button: this.Close();
Calling Select Stored Procedures from Oracle:
We can’t use select statements directly in Oracle SP’s as we used in Sql Server, so to define a select SP in Oracle for retrieving any data from the table(s) first we need to load the data from table into a cursor under SP and then that cursor should be returned as an output parameter back to the application.







To send cursor as an output parameter from a SP we need to use Ref Cursors, because Ref Cursor is a data type (user defined), which can be used as a procedure parameter, so first we need to define a Ref Cursor type and that should be used as an Output parameter to the SP. We define Ref Cursor types in Oracle Database as following:
                                Type <type name> is Ref Cursor;                     E.g.: Type DynaCur is Ref Cursor;
To define the SP with Ref Cursor Output Parameter first we need to define the  Ref Cursor under an object known as Package which is a group of Procedures, Functions, Variables and Sql Statements created as a single unit, used for storing of related objects. A package has two parts:
1. Package Specification or Spec or Package Header                   
2. Package Body
Package Specification acts as an interface to the package which contains only declaration of types, variables, constants, exceptions, cursors and sub-programs. Package Body is used to provide implementation for the sub-programs, queries for the cursors declared in the package specification.
Now let us define a package header with a Ref Cursor type definition and also 2 SP’s for selecting data from DEPT and EMP tables using the Ref Cursor type as an Output Parameter and then implement the SP’s under the Package Body.
Step 1: Defining Package Specification:
Create or Replace Package MyPackage
As
  Type DynaCur is Ref Cursor;
  Procedure Select_Emp(ecur out DynaCur);
  Procedure Select_Dept(dcur out DynaCur);
End MyPackage;
/
Step 2: Defining the Package Body:
Create or Replace Package Body MyPackage
As
  Procedure Select_Emp(ecur out DynaCur)
  Is
  Begin
    Open ecur For Select * From Emp;
  End Select_Emp;
  Procedure Select_Dept(dcur out DynaCur)
  Is
  Begin
    Open dcur for Select * From Dept;
  End Select_Dept;
End MyPackage;
/

Step 3: Displaying the data by loading it into the application:
Now take a new windows form place a SplitContainer on it, set its Orientation property as Horizontal, place a DataGridView control on each panel by setting their Dock property as fill and write the following code:
using System.Data.OracleClient;
Declarations: OracleConnection con; OracleDataAdapter da1, da2; DataSet ds;
Under Form Load:  string constr = ConfigurationManager.ConnectionStrings["OConStr"].ConnectionString;
con = new OracleConnection(constr); da1 = new OracleDataAdapter("MyPackage.Select_Emp", con);
da1.SelectCommand.CommandType = CommandType.StoredProcedure;
da1.SelectCommand.Parameters.Add("ecur", OracleType.Cursor).Direction=ParameterDirection.Output;
da2 = new OracleDataAdapter("MyPackage.Select_Dept", con);
da2.SelectCommand.CommandType = CommandType.StoredProcedure;
da2.SelectCommand.Parameters.Add("dcur", OracleType.Cursor).Direction=ParameterDirection.Output; 
ds = new DataSet(); da1.Fill(ds, "Emp"); da2.Fill(ds, "Dept");
dataGridView1.DataSource = ds.Tables["Dept"]; dataGridView2.DataSource = ds.Tables["Emp"];





----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

WINDOWS PROGRAMMING

Delegates
Delegate is a type which holds the method(s) reference in an object. It is also referred to as a type safe function pointer. Delegates are roughly similar to function pointers in C++; however, delegates are type-safe and secure. A delegate instance encapsulates a static or an instance method and calls the method for execution. Effective use of delegate improves the performance of application. Methods can be called in 2 different ways in C#, those are:
1.       Using object of a class if it is instance and name of the class if it is static.
2.       Using a delegate (either static or instance).

To use a delegate for calling a method we need to adopt the following process:
1.       Defining a delegate.
2.       Instantiating the delegate.
3.       Using the delegate and calling the method.

Defining a Delegate:
                [<modifiers>] delegate void|type Name( [<param definitions>] )
Note: while declaring a delegate you should follow the same syntax as in the method i.e. IO parameters of delegate should be same as the IO parameters of method we want to call using the delegate.
                public void AddNums(int x, int y) {
                   Console.WriteLine(x + y);
                }
                public delegate void AddDel(int x, int y);

                public static string SayHello(string name) {
                   return “Hello “ + name;
                }
                public delegate string SayDel(string name);

Instantiating the delegate: In this process we bind the method with delegate, as following:
                AddDel ad = new AddDel(AddNums);              or            AddDel ad = AddNums;
                SayDel sd = new SayDel(SayHello);                   or            SayDel sd = SayHello;

Using the delegate and calling the method: now when we call the delegate by passing the required parameters values the method which is bound with the delegate gets executed.
                ad(100, 50);                                                                          sd(“Raju”);

Note: Delegates can be defined either with in a class or under a namespace also just like we define other types.
Add a new code file under the project naming it as Delegates.cs and write the following code:
using System;
namespace OOPSProject {
  public delegate void AddDel(int a, int b, int c);
  public delegate string SayDel(string name);
  public delegate void MathDel(int x, int y);
}
Add a new class DelDemo.cs under the project and write the following code:
class DelDemo {
  public void AddNums(int x, int y, int z) {
    Console.WriteLine(x + y + z);
  }
  public static string SayHello(string name) {
    return "Hello " + name;
  }
  static void Main() {
    DelDemo obj = new DelDemo(); AddDel ad = obj.AddNums; SayDel sd = DelDemo.SayHello;
    ad(100, 50, 25); ad(123, 456, 789); ad(396, 224, 156);
    Console.WriteLine(sd("Raju")); Console.WriteLine(sd("Naresh")); Console.WriteLine(sd("Praveen"));
    Console.ReadLine();
  }
}
Multicast Delegate: It is a delegate which holds the reference of more than one method. Multicast delegates must contain only methods that return void. If we want to call multiple methods using a single delegate all the methods should have the same IO Parameters. To test this, add a new class MultiCastDemo.cs under the project and write the following code:
class MultiCastDemo {
  public void Add(int x, int y) {
    Console.WriteLine("Add: " + (x + y));
  }
  public void Sub(int x, int y) {
    Console.WriteLine("Sub: " + (x - y));
  }
  public void Mul(int x, int y) {
    Console.WriteLine("Mul: " + (x * y));
  }
  public void Div(int x, int y) {
    Console.WriteLine("Div: " + (x / y));
  }
  static void Main() {
   MultiCastDemo mc = new MultiCastDemo(); MathDel md = mc.Add; md += mc.Sub; md += mc.Mul; md += mc.Div;
    md(100, 50); Console.WriteLine(); md(575, 25); Console.WriteLine();
    md -= obj.Mul; md(678, 28); Console.ReadLine();
  }
}
Anonymous Methods:
In versions of C# before 2.0, the only way to declare a delegate was to use named methods. C# 2.0 introduced anonymous methods which provide a technique to pass a code block as a delegate parameter. Anonymous methods are basically methods without a name, just the body. An anonymous method is inline unnamed method in the code. It is created using the delegate keyword and doesn’t required name and return type. Hence we can say an anonymous method has only body without name, optional parameters and return type. An anonymous method behaves like a regular method and allows us to write inline code in place of explicitly named methods. To test this, add a new class AnonymousMethod.cs and write the following code:
class AnonymousMethod {
  static void Main() {
    SayDel sd = delegate(string name) {
      return "Hello Mr. " + name + " have a nice day.";
    };
    Console.WriteLine(sd("Raju")); Console.WriteLine(sd("Naresh")); Console.WriteLine(sd("Praveen"));
    Console.ReadLine();
  }
}
Lambda Expression:
While Anonymous Methods were a new feature in 2.0, Lambda Expressions are simply an improvement to syntax when using Anonymous Methods, introduced in C# 3.0. Lambda Operator => was introduced so that there is no longer a need to use the delegate keyword, or provide the type of the parameter. The type can usually be inferred by compiler from usage. To test this, add a new class LambdaExpression.cs and write the following code:
class LambdaExpression {
  static void Main() {
    SayDel sd = name => {
      return "Hello Mr. " + name + " have a nice day.";
    };
    Console.WriteLine(sd("Raju")); Console.WriteLine(sd("Naresh")); Console.WriteLine(sd("Praveen"));
    Console.ReadLine();
  }
}
Syntax of defining Lambda Expression: [(] Parameters [)] => { Executed code };
Why would we need to write a method without a name is convenience i.e. it's a shorthand that allows you to write a method in the same place you are going to use it. Especially useful in places where a method is being used only once and the method definition are short. It saves you the effort of declaring and writing a separate method to the containing class. Benefits are like Reduced typing, i.e. no need to specify the name of the function, its return type, and its access modifier as well as when reading the code you don't need to look elsewhere for the method's definition. Lambda expressions should be short. A complex definition makes calling code difficult to read.
Partial Classes:
It is possible to split the definition of a class or a struct, an interface over two or more source files. Each source file contains a section of the type definition, and all parts are combined when the application is compiled. There are several situations when splitting a class definition is desirable like:
·         When working on large projects, spreading a class over separate files enables multiple programmers to work on it at the same time.
·         When working with automatically generated source, code can be added to the class without having to recreate the source file. Visual Studio uses this approach when it creates Windows Forms, Web service Wrapper Code, and so on. 







The partial keyword indicates that other parts of the class, struct, or interface can be defined in the namespace. All the parts must use the partial keyword. All the parts must be available at compile time to form the final type. All the parts must have the same accessibility, such as public, internal, and so on. If any part is declared abstract, then the whole type is considered abstract. If any part is declared sealed, then the whole type is considered sealed. If any part declares a base type, then the whole type inherits that class. Parts can specify different base interfaces, and the final type implements all the interfaces listed by all the partial declarations. Any class, struct, or interface members declared in a partial definition are available to all the other parts. The final type is the combination of all the parts at compile time.
Note: The partial modifier is not available on delegate or enumeration declarations.
Add 2 new code files under the project Part1.cs and Part2.cs and write the following code:
using System;
namespace OOPSProject {
  partial class Parts {
    public void Method1() {
      Console.WriteLine("Method 1");
    }
    public void Method2() {
      Console.WriteLine("Method 2");
    }
  }
}
using System;
namespace OOPSProject {
  partial class Parts {
    public void Method3() {
      Console.WriteLine("Method 3");
    }
    public void Method4() {
      Console.WriteLine("Method 4");
    }
  }
}
Add a new class TestParts.cs under the project and write the following code:
class TestParts {
  static void Main() {
    Parts p = new Parts();
    p.Method1(); p.Method2(); p.Method3(); p.Method4();
    Console.ReadLine();
  }
}
Partial Methods: A partial class or struct may contain a partial method. One part of the class contains the signature of the method. An optional implementation may be defined in the same part or another part. If the implementation is not supplied, then the method and all calls to the method are removed at compile time.
Partial methods enable the implementer of one part of a class to define a method and the implementer of the other part of the class can decide whether to implement the method or not. If the method is not implemented, then the compiler removes the method signature and all calls to the method. The calls to the method, including any results that would occur from evaluation of arguments in the calls, have no effect at run time. Therefore, any code in the partial class can freely use a partial method, even if the implementation is not supplied. No compile-time or run-time errors will result if the method is called but not implemented.
Partial methods are especially useful as a way to customize generated code. They allow for a method name and signature to be reserved, so that generated code can call the method but the developer can decide whether to implement the method. Much like partial classes, partial methods enable code created by a code generator and code created by a human developer to work together without run-time costs.
A partial method declaration consists of two parts: the definition, and the implementation. These may be in separate parts of a partial class, or in the same part. If there is no implementation declaration, then the compiler optimizes away both the defining declaration and all calls to the method.
partial void TestMethod();                 // Definition in file1.cs
partial void TestMethod() {                // Implementation in file2.cs
  // method body
}
There are several rules to follow with partial class and there are several rules to follow with partial method as defined by Microsoft. Those rules are listed below:
·         Partial methods are indicated by the partial modifier and can be declared within partial classes only.
·         Partial methods must be private and must return void.
·         Partial methods do not always have an implementation and can also be declared as static.
·         Partial methods can have arguments including ref but not out. 
·         You cannot make a delegate to a partial method.
Add 2 new code files Test1.cs and Test2.cs and write the following code:
using System;
namespace OOPSProject {
  partial class PMethod {
    partial void TestMethod();
    public void Show() {
      Console.WriteLine("Show Method.");
    }
  }
}
using System;
namespace OOPSProject {
  partial class PMethod {
    partial void TestMethod() {
      Console.WriteLine("Partial Method Implemented.");
    }
    public void s() {
      Console.WriteLine("Display Method.");
    }
    static void Main() {
      PMethod obj = new PMethod();
      obj.Show(); obj.Display(); obj.TestMethod(); Console.ReadLine();
    }
  }
}
Windows Programming
In development of any application we need a user interface (UI) to communicate with end users. User interfaces are of 2 types:
1.       CUI (Character User Interface)
2.       GUI (Graphical User Interface)

Initially we have only CUI, E.g.: Dos, Unix OS etc., where these applications suffers from few criticisms like:
1.       They are not user friendly, because we need to learn the commands first to use them.
2.       They do not allow navigating from one place to other.

To solve the above problems, in early 90's GUI applications are introduced by Microsoft with its Windows OS, which has a beautiful feature known as 'Look and Feel'. To develop GUI's Microsoft has provided a language also in 90's only i.e. VB (Visual Basic), later when .Net was introduced the support for GUI has been given in all languages of .Net.
Developing Graphical User Interfaces:
To develop GUI’s we need some special components known as controls and those controls are readily available in .Net language's as classes under the namespace System.Windows.Forms. All the control classes that are present under this namespace were grouped into different categories like:
·         Common Controls
·         Container Controls
·         Menus and Tool Bar Controls
·         Data Controls
·         Components
·         Printing Controls
·         Dialog Controls
·         Reporting Controls

Properties, Methods and Events:
Whatever the control it was every control has 3 things in common like properties, methods and events.
1.       Properties: these are attributes of a control which have their impact on look of the control.
E.g.: Width, Height, BackColor, ForeColor, etc.
2.       Methods: these are actions performed by a control.
E.g.: Clear(), Focus(), Close(), etc.
3.       Events: these are time periods which specify when an action has to be performed.
E.g.: Click, Load, KeyPress, MouseOver, etc.

Note: the parent class for all the control classes is the class "Control", which is defined with the properties, methods and events that are common for each control like Button, TextBox, Form, Panel, etc.
How to develop a Desktop Application (GUI) ?
To develop a Desktop Application (GUI) the base control that has to be created first is Form. To create the Form first define a class inheriting from the pre-defined class "Form" so that the new class also becomes a Form.
E.g.:         public class Form1 : Form
                To run the Form we have created call the static method Run of Application class by passing the object of Form we have created as a parameter.
E.g:          Form1 f = new Form1(); Application.Run(f);   or  Application.Run(new Form1());
Note: we can develop a windows application either by using a notepad following the above process as well as under visual studio also using "Windows Forms Application" project template.
Developing Windows Application using Notepad: Open notepad, write the following code in it, save, compile and then execute.
using System; using System.Windows.Forms;
public class Form1 : Form {
 static void Main() {
  Form1 f = new Form1(); 
  Application.Run(f);
 }
}
Developing Windows Applications using Visual Studio:
To develop a windows application under VS open the new project window, select "Windows Forms Application" project template and specify a name to the project, e.g.: WindowsProject. By default the project comes with 2 classes in it:
·         Form1
·         Program

Form1 is the class which is defined inheriting from predefined class Form, e.g.: public partial class Form1 : Form
Here the class Form1 is partial which means it is defined on multiple files:
·         Form1.cs
·         Form1.Designer.cs
Note: we will not find the Form1.Designer.cs file open by default to open it go to solution explorer expand the node Form1.cs and under it we find Form1.Designer.cs file, double click on it to open.

Program is a static class and in this class we find a Main method under which object of class Form1 is created for execution, as following:
                Application.Run(new Form1());
Note: Program class is the main entry point of the project from where the execution starts.

Windows applications developed under VS have 2 places to work with:
·         Design View
·         Code View
Design View is the place where we design the application; this is accessible both to programmers and end user's whereas Code View is the place where we write code for the execution of application, this is accessible only to programmers.
Note: because of the design view what VS provides we call it as WYSIWYG IDE (What You See Is What You Get).
Adding new Forms in the project:
A project can contain any no. of forms in it, to add a new form under our project i.e. 'WindowsProject', open Solution Explorer -> right click on project and select Add -> "Windows Form", which adds a new form Form2.cs. To run the new form, go to Program class and change the code under Application.Run method as Form2.
E.g.: Application.Run(new Form2());
Properties: as we are aware that every control has properties, methods and events, to access the properties of a control VS provides 'Property Window' that lists all the properties of a control, to open Property Window select the control and press F4. We can change any property value in the list of properties, under property window like Width, Height, BackColor, Font, ForeColor etc., for which we can see the impact immediately after changing the property value. To test this go to properties of Form2 we have added right now and change any property value you want.
                Whenever we set a value to any property of a control under property window, VS on behalf of us writes all the necessary code by assigning values to the properties we have modified. We can view that code under InitializeComponent () method of the class which is called in the constructor of the class. To view code under InitializeComponent method, go to Code View and right click on the method called in constructor and select 'Go to definition', this takes us to Form2.Designer.cs file and here also we find the same class Form2 because it is partial.
Setting properties to control manually by writing the code in Notepad:
using System; using System.Drawing; using System.Windows.Forms;
public class Form2 : Form {
  public Form2() {
    InitializeComponent();
  }
  private void InitializeComponent() {
    this.Text = "My Form"; this.BackColor = Color.Pink; this.Size = new Size(400, 400);
  }
  static void Main() {
    Application.Run(new Form2());
 }
}
Events: it is a time periods which tells when an action has to be performed i.e. when exactly we want to execute a method. Every control will have no. of events under it where each event occurs on a particular time period. We can access the events of a control also under property window only. To view them in the property window choose events Tab on top of the property window. If we want to write any code that should execute when an event occurs double click on the desired event corresponding to a control, which takes you to code view and provides a method for writing the code.
Now in our project add a new form Form3.cs, go to its Events, double click on Load Event and write the following code under Form3_Load method that is generated in Code View:
                                MessageBox.Show("Welcome to windows applications.");
                Again go to design view, double click on the Click Event and write following code under Form3_Click method:
                                MessageBox.Show("You have clicked on form.");
What happens when we double click on an event of a control in the property window?

When we double click on an event in property window internally a method gets generated for writing the code and that method has a special name "Event Procedure", which is a block of code that is bound with an event of control and gets executed whenever the event occurs. The code written under event procedure will be executed by the event whenever the event occurs by taking the help of a delegate internally, as following:





In the above case whenever the Event occur it will call the delegate which then executes the event procedure that is bound with the event, because a delegate is responsible for execution of the event procedure first the event, delegate and event procedure should be bound with each other as following:
Syntax:                  <control>.<event> += new <delegate> (<event procedure>)
E.g.:                        this.Load += new EventHandler(Form3_Load);
                                button1.Click += new EventHandler(button1_Click);
                                textBox1.KeyPress += new KeyPressEventHandler(textBox1_KeyPress);
Events and Delegates are pre-defined under BCL (Events are defined in control classes and delegates are defined under namespaces), what is defined here is only an event procedures. After defining the event procedure in form class VS links the Event, Delegate and Event Procedure with each other as we have seen above, this can be found under the method InitializeComponent.
Note: 1 delegate can be used by multiple events to execute event procedures, but all events will not use the same delegates, where different events may use different delegates to execute event procedures.
How to define an Event Procedure manually?
To define Event Procedures manually we need to follow a standard format as following:
Syntax:                   [<modifiers>] void <Name>(object sender, EventArgs e) {
                                                <Stmts>;
}
·         Event Procedures are non-value returning methods.
·         An event procedure can have any name but VS adopts a convention while naming them i.e.: <control name>_<event>. E.g.: Form1_Load, button1_Click, textBox1_KeyPress
·         Every event procedure will take 2 mandatory parameters:       
                                 i.            Object sender
                                ii.            EventArgs e
Note: When we define event procedures manually we can give any name to them as per our choice.
Defining Event Procedures in Notepad:
using System; using System.Windows.Forms;
public class Form3 : Form {
  public Form3() {
    InitializeComponent();
  }
  private void InitializeComponent() {
    this.Text = "My New Form";
    this.Load += new EventHandler(TestProc1); this.Click += new EventHandler(TestProc2);
  }
  private void TestProc1(object sender,EventArgs e) {
    MessageBox.Show("Load Event Occured.");
  }
  private void TestProc2(object sender,EventArgs e) {
    MessageBox.Show("Click Event Occured.");
  }
  static void Main() {
    Application.Run(new Form3());
  }
}
Placing controls on a form:
By default we are provided with no. of controls where each control is a class. These controls are available in ToolBox window on LHS of the studio, which displays all controls, organized under different Tabs (groups). To place a control on the form either double click on desired control or select the control and place it in the desired location on form.
Note: use Layout toolbar to align controls properly.
How does a form gets created ?
When a form is added to the project internally following things takes place:
         i.            Defines a class inheriting from the pre-defined class Form so that the new class is also a Form.
E.g.: public partial class Form1 : Form
        ii.            Sets some initialization properties like name, text etc., under InitializeComponent method.
E.g.: this.Name = "Form1"; this.Text = "Form1";
How does a control gets placed on the form ?
When a control is placed on the form following things takes place internally:
1)       Creates object of appropriate control class.
E.g.: Button button1 = new Button();
2)       Sets some initialization properties that are required like name, text, size, location etc.,
E.g.: button1.Name = "button1";                       button1.Text = "button1";
                         button1.Location = new Point(x, y);        button1.Size = new Size(width, height);
3)       Now the control gets added to form by calling Controls.Add method on current Form.
E.g.: this.Controls.Add(button1);
Note: All the above code will be generated by VS under InitializeComponent method with in the file Designer.cs.
The code that is present under a windows application is divided into 2 categories:
·         Designer Code
·         Business Logic
Code which is responsible for construction of the form is known as designer code and code which is responsible for execution of the form is known as business logic. Desinger code is generated by VS under the InitializeComponent method of Designer.cs file and business logic is written by programmers in the form of event procedures.
Before .net 2.0 designer code and business logic were defined in a class present under a single file as following:
Form1.cs
public class Form1 : Form {
   -Designer Code
   -Business Logic
}
From .net 2.0 with introduction of partial classes’ designer code and business logic were separated into 2 different files but of the same class only as following:
Form1.cs
public partial class Form1 : Form {
   -Business Logic
}
Form1.Designer.cs
partial class Form1 {
   -Designer Code
}
Creating a form and placing a button on it using notepad:
using System;        using System.Drawing;        using System.Windows.Forms;
public class Form4 : Form {
  Button button1;
  public Form4() {
    InitializeComponent();
  }
  private void InitializeComponent() {
    button1 = new Button(); button1.Text = "Click Me"; button1.BackColor = Color.Pink;
    button1.Size = new Size(100, 50); button1.Location = new Point(100, 100);
    button1.Click += new EventHandler(TestProc); this.Controls.Add(button1); 
  }
  private void TestProc(object sender, EventArgs e) {
    MessageBox.Show("Button is clicked.");
  }
  static void Main() {
    Application.Run(new Form4());
  }
}
Default Events: as we are aware every control has no. of events to it, but 1 event will be default for a Control. To write code under that default event of Control directly double click on the control which takes to an event procedure associated with that default event.
                Control                                                                                                  Default Event
                Form                                                                                                       Load
Button                                                                                                    Click
TextBox                                                                                                  TextChanged
CheckBox and RadioButton                                                                CheckedChanged
Timer                                                                                                      Tick
ListView, ListBox, ComboBox and CheckedListBox                        SelectedIndexChanged
Working with Events and Event Procedures:
The concept of events and event procedures has been derived from classical VB Lang., but there an event procedure can be bound with only single event of a single control, where as in .NET it can be bound with multiple events of a control as well as with multiple controls also.

Binding event procedures with multiple events of a control:
Add a new form to the project Form4 and double click on it which defines an event procedure Form4_Load, now bind the same event procedure with click event of form also, to do this go to events of form, select click event and click on the drop down beside, which displays the list of event procedures available, select 'Form4_Load' event procedure that is defined previously which binds the event procedure with click event also now under the event procedure write the following code and execute:
MessageBox.Show("Event procedure bound with multiple events of a control.");
Binding an event procedure with multiple controls:
Add a new form in the project i.e. Form5 and design it as below. Now double click on button1 which generates a click event procedure for button1, bind that event procedure with button2, textBox1, textBox2 and Form5 also and write the following code under the event procedure: MessageBox.Show("Control is clicked");



Binding an event procedure with multiple controls and identifying ‘Type’ of control which is raising the event:
Add a new form in the project i.e. Form6 and design it same as Form5. Now double click on button1 which generates a click event procedure for button1, bind that event procedure with button2, textBox1, textBox2 and Form6 also and write the following code under the event procedure:
if (sender.GetType().Name == "Button")
                     MessageBox.Show("Button is clicked.");
else if (sender.GetType().Name == "TextBox")
                     MessageBox.Show("TextBox is clicked.");
else
                     MessageBox.Show("Form6 is clicked.");

When an event procedure is bound with multiple controls, any of the control can raise the event in runtime and execute the event procedure, but the object of control which is raising the event will be coming into the event procedure and captured under the parameter "sender" of event procedure as following:





As sender is of type object it's capable of storing object or instance of any class in it, so after the object or instance of the control class is captured under sender by calling GetType() method on it we can identify the type of control to which that object or instance belongs as we have performed above.
Binding an event procedure with multiple controls and identifying the exact control which is raising the event:
Add a new form in the project i.e. Form7 and design it same as Form5. Now double click on button1 which generates a click event procedure for button1, bind that event procedure with button2, textBox1, textBox2 and Form7 also and write the following code under the event procedure:
                if (sender.GetType().Name == "Button") {
  Button b = sender as Button;
                  if (b.Name == "button1")
                     MessageBox.Show("Button1 is clicked");
                  else
                     MessageBox.Show("Button2 is clicked");
}
else if (sender.GetType().Name == "TextBox") {
                  TextBox tb = (TextBox)sender;
                  if (tb.Name == "textBox1")
                     MessageBox.Show("TextBox1 is clicked");
                  else
                     MessageBox.Show("TextBox2 is clicked");
}
else
                  MessageBox.Show("Form7 is clicked");

When an event procedure is bound with multiple controls and if we want to identify the exact control which is raising the event, we need to identify the "Name" of control. But even if "sender" represents the control which is raising the event, using sender we cannot find the control name because as we are already aware that object of a class can be stored in its parent's variable and make it as a reference but with that reference we cannot access the child classes members (Rule No. 3 of Inheritance). So if we want to find the name of control that is raising the event we need to convert sender back into appropriate control type (Button or TextBox) from which it is created by performing an explicit conversion and then find out the name of control object, we can convert sender into control type in any of the following ways:
Button b = sender as Button;           or            Button b = (Button)sender;
TextBox tb = sender as TextBox;        or          TextBox tb = (TextBox)sender;
Working with Controls
RadioButton and CheckBox Controls:
We use these controls when we want the users to select from a list of values provided. RadioButton control is used when we want to allow only a single value to select from the set of values whereas CheckBox control is used when we want to allow multiple selections.
Note: as RadioButton control allows only single selection when we want to use them under multiple options or questions we need to group related RadioButton's, so that 1 can be selected from each group, to group them we need to place RadioButtons on separate container controls like Panel, GroupBox, TabControl etc.
               
Both these 2 controls provides a common boolean property Checked which returns true if the control is selected or else returns false, using which we can identify which option has been chosen by the users. Now add a new form in the project and write the below code by designing the form as following:







Code under “Show Selected Radio Button” button’s click event:
if (radioButton1.Checked)
   MessageBox.Show("Radio Button1 is selected");
else if (radioButton2.Checked)
   MessageBox.Show("Radio Button2 is selected");
else if (radioButton3.Checked)
   MessageBox.Show("Radio Button3 is selected");
Code under “Show Selected Check Box’s” button’s click event:
if (checkBox1.Checked)
   MessageBox.Show("Check Box1 is selected");
if (checkBox2.Checked)
   MessageBox.Show("Check Box2 is selected");
if (checkBox3.Checked)
   MessageBox.Show("Check Box3 is selected");             
Checked Changed Event: this is the default event of both the above 2 controls which occurs when the controls are selected as well as de-selected also. To work with the event design a form as following:












·      *   Change the name of ‘Name’ TextBox as txtName, ‘Total Fees’ TextBox as txtFees, ‘Reset Form’ Button as btnReset     and ‘Close Form’ button as btnClose.
·       *  Change the ReadOnly property of ‘Total Fees’ TextBox as true so that it becomes non editable, enter ‘0’ as a value in     Text property and also set the TextAlign property as right.
·      *   Set the Tag property for each CheckBox and RadioButton with their corresponding fees values and it should be ‘0’ for    Normal RadioButton. Tag property is used for associating user defined data to any control just like Text property, but      Text value is visible to end user and Tag value is not visible to end user.
·      *   Click on any one CheckBox so that CheckedChanged Event procedure gets generated; bind that event procedure with      all the remaining CheckBox’s.
·        * Click on any one RadioButton so that CheckedChanged Event procedure gets generated; bind that event procedure           with all the remaining RadioButton’s.
·       *  Now go to Code View and write the following code.
Class Declarations: int count = 0;
Code under CheckedChanged Event Procedure of all CheckBox’s:
radioButton1.Checked = true;
int amt = int.Parse(txtFees.Text);
CheckBox cb = sender as CheckBox;
if (cb.Checked) {
  count += 1; amt += Convert.ToInt32(cb.Tag);
}
else {
  count -= 1; amt -= Convert.ToInt32(cb.Tag);
}
txtFees.Text = amt.ToString();
Code under CheckedChanged Event Procedure of all RadioButton’s:
int amt = int.Parse(txtFees.Text);
RadioButton rb = sender as RadioButton;
if (rb.Checked)
   amt += (Convert.ToInt32(rb.Tag) * count);
else
   amt -= (Convert.ToInt32(rb.Tag) * count);
txtFees.Text = amt.ToString();
Code under Click Event Procedure of Reset Form Button:
foreach (Control ctrl in groupBox1.Controls) {
  CheckBox cb = ctrl as CheckBox; cb.Checked = false;
}
foreach (Control ctrl in this.Controls) {
  if (ctrl.GetType().Name == "TextBox") {
    TextBox tb = ctrl as TextBox; tb.Clear();
  }
}
txtFees.Text = "0"; txtName.Focus();
Code under Click Event Procedure of Reset Form Button: this.Close();
Button, Label and TextBox Controls:
1.       Button: used for taking acceptance from a user to perform an action.
2.       Label: used for displaying static text on the UI.
3.       TextBox: used for taking text input from the user, this control can be used in 3 different ways:
                                 I.            Single Line Text (d)
                                II.            Multi Line Text (Text Area)
                              III.            Password Field

The default behavior of the control is single line text; to make it multiline set the property Multiline of the control as true. By default the text area will not have any scroll bars to navigate up and down or left and right, to get them set the ScrollBars property either as Vertial or Horizontal or Both, default is none.
Note: by default the WordWrap property of the control is set as true disabling horizontal scroll bar so set it as false to get horizontal scroll bar.
To use the control as a password field either set the PasswordChar property of control with a character we want to use as Password Character like * or # or $ or @ etc., or else set the UseSystemPasswordChar property as true which indicates the text in the control should appear as the default password character.
To work with the above 3 controls add a new form in the project, design it as following, set the Name property of the TextBox’s as txtName, txtPwd, txtCPwd, txtPhone and txtAddress and set the Name property of the Button’s as btnSave, btnClear and btnClose.








Setting Tab Order of Form Controls:
While working with a windows application we navigate between controls using the Tab key of key board. By default Tab key navigates the focus between controls in the same order how they are placed on form. If we want to set the sequence of tab on our own, it can be done by setting the “Tab Order”. To do this go to View Menu and select Tab Order which shows the current tab order, now click on each control in a sequence how we want to move the tab, again go to view menu and select Tab Order.

In the above form check the following business rules (Validations):
1.       Check the user name, password and confirm password fields to be mandatory.
2.       Check password characters to be ranging between 8 to 16 characters.
3.       Check confirm password to be matching with password.
4.       Put the save button in disable state and enable it only if the above 3 rules are satisfied.
5.       Check phone TextBox to accept numeric values and back spaces only.
6.       Allow users to close the form if required at any time.

To perform the first 4 validations first set the enabled property of save button as false so that it will be in disabled state, then set the MaxLength property of both password textbox's to 16 so that they will accept only 16 chars, then define a Validating event procedure for user name textbox and bind that event procedure with both the password textbox's also. Now write the following code under the event procedure:
TextBox tb = sender as TextBox;
if (tb.Text.Trim().Length == 0) {
  MessageBox.Show("Cannot leave empty."); e.Cancel = true; return;
}
if (tb.Name != "txtName") {
  if (tb.Text.Trim().Length < 8){
    MessageBox.Show("Password should be between 8 to 16 chars"); e.Cancel = true; return;
  }
}
if (tb.Name == "txtCPwd") {
  if (txtPwd.Text.Trim() != txtCPwd.Text.Trim()) {
    MessageBox.Show("Confirm password should match with password"); return;
  }
   btnSave.Enabled = true;
}
·         Validating event occurs when the focus is leaving the control and validates the content entered in the control.
·         Some events are associated with properties with them e.g.: Validating, KeyPress etc., if we want to consume the properties of an event under its event procedure we can make use of the parameter "e" of the event procedure which refers to properties of current executing event.
·         In above case Cancel is a property of validating event when set as true restricts the focus not to leave the control.
·         To close the form even from mandatory fields go to properties of Close Button and set its 'Causes Validation' property as false so that code under that button gets executed before the execution of any other controls validating event. Now write the following code under Close Button Click Event:

txtName.CausesValidation = false; txtPwd.CausesValidation = false; txtCPwd.CausesValidation = false; this.Close();
When we set CausesValidation = false for TextBox it will restrict validating event of the control not to occur so that focus leaves the textbox and form gets closed.
                If we want the Phone No TextBox to accept only numeric values and back spaces define a KeyPress event procedure for Phone No TextBox and write following code in it:

if (char.IsDigit(e.KeyChar) == false && Convert.ToInt32(e.KeyChar) != 8) {
  MessageBox.Show("Enter numerics only"); e.Handled = true;
}    
·         KeyPress event occurs when we press and release a key while the focus is in the control.
·         KeyChar property of KeyPress gets the key value corresponding to the key pressed.
·         Handled property when set as true will restrict the key value to enter into the control.
·         Char.IsDigit(char) will return true if the given char is a numeric or else returns false.
·         Convert.ToInt32(char) will return ascii value of the given character.
Code under Save Button Click Event Procedure: MessageBox.Show("Data saved to database");
Code under Clear Button Click Event Procedure:
foreach(Control ctrl in this.Controls) {
  if(ctrl.GetType().Name == "TextBox") {
    TextBox tb = ctrl as TextBox; tb.Clear();
  }
}
btnSave.Enabled = false; txtName.Focus();
AcceptButton and CancelButton Properties of the Form Control:
Under Form we have 2 properties AcceptButton and CancelButton which allows us to map buttons on a form with keyboard keys. AcceptButton property if bound with a button that button gets clicked whenever we press Enter key of key board. CancelButton property if bound with a button that button gets clicked whenever we press Esc key of key board. To set them go to properties of form select either AcceptButton or CancelButton properties which will display the list of buttons on form select a button from them.
ComboBox, ListBox, CheckedListBox:
These controls are also used for providing users with a list of values to choose from, ComboBox allows only single selection but it is editable which gives a chance to either select from the list of values available or enter a new value, it’s a combination of 2 controls DropDownList + TextBox. CheckedListBox by default allows multi-selection. ListBox by default allows single selection only but can be changed to multi-selection by setting the SelectionMode property either to MultiSimple [Mouse Click] or MultiExtended [Ctrl + Mouse Click], default is one.

Adding values to the controls: we can add values to the 3 controls in different ways like:
1.       In the properties of the control we find a property Items, select it and click on the button beside it which opens a window, enter the values we want to add, but each in a new line.
2.       By using Items.Add method of the control we can add values, but only one at a time.
                                <control>.Items.Add(object value)
3.       By using Items.AddRange method of the control an array of values can be added at a time.
                                <control>.Items.AddRange(object[] values)
4.       By using DataSource property of the control a DataTable can be bound to it so that all the records of table gets bound to the control, but as it can display only a single column we need to specify the column to be displayed using the DisplayMember property.
 <control>.DataSource = <data table>            <control>.DisplayMember = <col name>
Identifying selected values from the controls: to identify the selected values from the controls we can make use of the following properties:
ComboBox:                                           Text -> string                         SelectedItem -> object             SelectedIndex -> int
ListBox: SelectedItem -> object        SelectedIndex -> int            SelectedItems -> object[]         SelectedIndices -> int[]
CheckedListBox:                                  CheckedItems -> object[]                                                         CheckedIndices -> int[]
Add a new form in the project and design it as below, then go to Items property of the ComboBox control, click on the button beside it and enter a list of countries in the window opened.







Code under Form Load Event Procedure:
listBox1.Items.Add("AP");                   listBox1.Items.Add("Tamilnadu");                     listBox1.Items.Add("Orissa");
listBox1.Items.Add("Karnataka");     listBox1.Items.Add("Kerala");                             listBox1.Items.Add("Maharastra");
string[] cities = { "Bengaluru", "Chennai", "Delhi", "Hyderabad", "Kolkota", "Mumbai" };
checkedListBox1.Items.AddRange(cities);

Adding new values into the Combo Box when we press the enter key and the given value not existing under the list of values.
Code under ComboBox KeyPress Event Procedure:
if(Convert.ToInt32(e.KeyChar) == 13) {
  if(comboBox1.FindStringExact(comboBox1.Text) == -1) {
    comboBox1.Items.Add(comboBox1.Text);
  }
}
Code under “Show Selected Country” Button Click Event Procedure:
MessageBox.Show(comboBox1.Text);
MessageBox.Show(comboBox1.SelectedItem.ToString()); MessageBox.Show(comboBox1.SelectedIndex.ToString());
Code under “Show Selected States” Button Click Event Procedure:
 foreach (object obj in listBox1.SelectedItems) {              MessageBox.Show(obj.ToString());         }
Code under “Show Selected Cities” Button Click Event Procedure:
string str = null;
foreach (object obj in checkedListBox1.CheckedItems) {                str += obj.ToString() + ", ";                  }
str = str.Substring(0, str.Length - 2); int pos = str.LastIndexOf(",");
if (pos != -1) {
  str = str.Remove(pos, 1); str = str.Insert(pos, " and");
}
MessageBox.Show(str);
SelectedIndexChanged: it is the default event of all the above 3 controls which gets raised once a values is selected in the list, to test this add a new form in the project, design it as below and add the values “Quarter1, Quarter2, Quarter3, Quarter4” under the first ComboBox by using its items property and write the code.






Declarations:
string[] q1 = { "January", "February", "March" };            string[] q2 = { "April", "May", "June" };
string[] q3 = { "July", "August", "September" };              string[] q4 = { "October", "November", "December" };
Code under first ComboBox SelectedIndexChanged Event Procedure:
comboBox2.Items.Clear();
switch (comboBox1.SelectedIndex) {
   case 0:                                comboBox2.Items.AddRange(q1);                    break;
   case 1:                                comboBox2.Items.AddRange(q2);                    break;
   case 2:                                comboBox2.Items.AddRange(q3);                    break;
   case 3:                                comboBox2.Items.AddRange(q4);                    break;
}
PictureBox:
We use it for displaying images with in the application. To bind an image to the control we can use any of the following properties:
ImageLocation = <path of the image>
Image = Image.FromFile(string <path of the image>)
Image = Image.FromStream(Stream stream)  
Use BorderStyle property to control what type of border we want for the PictureBox, with any of the following values:
                                None [d]                                                FixedSingle                            Fixed3D
                Use SizeMode property of the control to set image placement and control sizing under the PictureBox which can be set with any of the following values:
                                Normal [d]                             StretchImage                        AutoSize                                                CenterImage
Dialog Controls:
These are special controls which provide an interface for displaying a list of values too choose from or for entering of new values, we have 5 dialog controls like ColorDialog, FolderBrowserDialog, FontDialog, OpenFileDialog and SaveFileDialog. Dialog controls are not shown directly on the form even after adding them, we can see them at bottom of the studio in design time, to make them visible in runtime we need to explicitly call the method ShowDialog() on the controls object, which returns a value of type DialogResult (enum), using it we can find out which button has been clicked on the DialogBox like Ok button or Cancel button etc.
                Dialog Controls never performs any action they are only responsible for returning the values to application developers that has been chosen by end users or entered by the end users, where the developers are responsible for capturing the values and then perform the necessary actions. To capture the values that are chosen or entered by end users we are provided with following properties:
                ColorDialog: Color                                               FolderBrowserDialog: SelectedPath
                FontDialog: Font                                                   OpenFileDialog, SaveFileDialog: FileName

Design a new form as below, add the ColorDialog, FontDialog, OpenFileDialog and SaveFileDialog controls to the form and write the below code:





Code under Change Color Button:
DialogResult dr = colorDialog1.ShowDialog();
if(dr == DialogResult.OK) {                  button1.BackColor = colorDialog1.Color;               }
Code under Change Font Button:
DialogResult dr = fontDialog1.ShowDialog();
if(dr == DialogResult.OK) {                  button2.Font = fontDialog1.Font;                     }
Code under Load Image Button:
openFileDialog1.Filter = "Image Files (*.jpg)|*.jpg|Icon Images (*.ico)|*.ico|All Files (*.*)|*.*";
openFileDialog1.FileName = ""; DialogResult dr = openFileDialog1.ShowDialog();
if (dr != DialogResult.Cancel) {
  string imgPath = openFileDialog1.FileName; pictureBox1.ImageLocation = imgPath;
}
Code under Save Image Button:
saveFileDialog1.Filter = "Image Files (*.jpg)|*.jpg|Icon Images (*.ico)|*.ico|All Files (*.*)|*.*";
DialogResult dr = saveFileDialog1.ShowDialog();
if (dr != DialogResult.Cancel) {
  string imgPath = saveFileDialog1.FileName; pictureBox1.Image.Save(imgPath);
}
MessageBox:
                This control is used for display messages with in a windows application by calling its static method “Show”, which returns a value of type DialogResult (enum), using it we can find out which button has been clicked on the MessageBox like Ok or Yes or No or Cancel etc. Show is an overloaded method that is defined with different overloads as following:
·         Show(string msg)                                                                                                                                  -> Dialog Result
·         Show(string msg, string caption)                                                                                                       -> Dialog Result
·         Show(string msg, string caption, MessageBoxButtons buttons)                                   -> Dialog Result
·         Show(string msg, string caption, MessageBoxButtons buttons, MessageBoxIcon icon)          -> Dialog Result

MessageBoxButtons is an enum which provides a list of options to choose what buttons should be displayed on the MessageBox for the user to select.

MessageBoxIcon is an enum which provides a list of options to choose what icon should be displayed on the MessageBox describing about the message like Error or Warning of Question or Information etc., icons.
Dock Property:
It’s a property present under all controls except form that defines which border of the control is bound to the container. The property can be set with any of the following values:
·         None: in this case any of the controls border is not bound to its container.
·         Left, Right, Top and Bottom: in this case what option we select from the 4, that border of the control is bound with the same border of the container.
·         Fill: in this case all the four borders of the control will be bound with its container, so it occupies all empty space present on the container but leaving the space to existing controls.
Timer Control:
It’s a control which can raise an event at user defined intervals i.e. we can specify an interval time period and once the interval elapses automatically the event procedure associated with the control gets executed.
Members of Timer:
1.       Tick: it is an event which occurs whenever the specified interval time elapses.
2.       Interval: it is a property using which we specify the frequency of execution in milliseconds.
3.       Start(): it is a method to start the execution of timer.
4.       Stop(): it is a method to stop the execution of timer.
Developing an Image Viewer Application:
                Add a new form in the project. Place a panel control on the form and set the dock property as right. Place a picture box control on the form and set its dock property as fill and size mode property as “StretchImage”. Now design the panel present on the right hand side of the form as following:









Name the buttons as btnLoad, btnPrev, btnNext, btnStart and btnStop. Set the Enabled property of btnPrev, btnNext and btnStart button as false, set the Visible property of btnStop as false, then go to properties of form and under its CancelButton property select the button as btnStop which gets mapped to Esc key of keyboard. Add the FolderBrowserDialog and Timer controls to the form, set the Interval property of Timer as 3000 and write the following code in Code View:
using System.IO;
Declarations: string dirPath; int panelWidth;
Code under Load Images Button Click Event Procedure:
DialogResult dr = folderBrowserDialog1.ShowDialog();
if (dr == DialogResult.OK) {
   dirPath = folderBrowserDialog1.SelectedPath; string[] files = Directory.GetFiles(dirPath, "*.jpg");
   if(files.Length > 0) {           listBox1.Items.Clear();
      foreach (string file in files) {
         int pos = file.LastIndexOf("\\"); string fname = file.Substring(pos + 1); listBox1.Items.Add(fname);
      }
      listBox1.SelectedIndex = 0; btnPrev.Enabled = false; btnNext.Enabled = true; btnStart.Enabled = true;
   } 
}
Code under ListBox SelectIndexChanged Event Procedure:
string imgPath = listBox1.SelectedItem.ToString(); pictureBox1.ImageLocation = dirPath + "\\" + imgPath;
Code under Start Slide Show Button Click Event Procedure:
panelWidth = panel1.Width; panel1.Width = 0; btnStop.Visible = true; timer1.Start();
Code under Stop Slide Show Button Click Event Procedure:
timer1.Stop(); btnStop.Visible = false; panel1.Width = panelWidth;
Note: write code for << (Previous), >> (Next) buttons for navigating to next and previous images as well as write code under the Timer Tick event for playing the slide show of images.
Adding Menu's to a Form: 
To add menu's to Form first we need to place a MenuStrip control on the Form which is present under Menu's and Toolbar’s Tab of Toolbox, which sits on top of the Form as the dock property is set as Top.
                To add a Menu on MenuStrip click on LHS corner of it which shows a textbox asking to “Type Here”, enter Text in it which adds a Menu, and repeat the same process for adding of multiple Menu's.
To add a MenuItem under a menu, click on the Menu which shows a textbox below asking to “Type Here”, enter Text in it which adds a MenuItem, and repeat the same process for adding of multiple MenuItems.
Note: both Menu and MenuItem are objects of the class ToolStripMenuItem.
               
If we want Menu's to be responding for "Alt Keys" of keyboard prefix with "&" before the character that should respond for Alt. E.g.: &File     &Edit     F&ormat 
To define a shortcut for MenuItems so that they respond to keyboard actions, go to properties of MenuItem, select “Shortcut Keys” Property, click on drop down beside it, which displays a window, in that window choose a modifier Ctrl or Alt or Shift and then choose a Key from ComboBox below.
                To group related MenuItems under a Menu we can add Separators between MenuItems, to do it right click on a MenuItem and select Insert -> separator which adds a separator on top of the MenuItem.
Note: same as we inserted a separator we can also insert a MenuItem if required, in the middle.

If we want to display any Image beside MenuItem right click on it and select “Set Image” which opens a window, select Local Resource and click on Import button which opens a DialogBox, using it select an image from your Hard disk.
                Sometimes we find check mark beside MenuItem to identify a property is on or off, e.g.: Word Wrap under Notepad. To provide check marks beside a MenuItem right click on it and select "Checked", but to check or uncheck the item in run time we need to write code explicitly under click event of MenuItem as following:
                if (<control>.Checked == true)         {              <control>.Checked = false;                }
                else                                                         {              <control>.Checked = true;                                }
RichTextBox:
                This control works same as a TextBox but provides advanced text entry and editing features such as character and paragraph formatting.
Members of RichTextBox Control:
·         Properties: BackColor, ForeColor, WordWrap, Modified, Font, ScrollBars, SelectedText, SelectionColor etc.
·         Methods: Cut(), Copy(), Paste(), Undo(), Redo(), Clear(), ClearUndo(), SelectAll(), DeselectAll(), Focus(), ResetText(), Refresh(), LoadFile(string path, RichTextBoxStreamType fileType), SaveFile(string path, RichTextBoxStreamType, fileType)
RichTextBoxStreamType is an enum that specifies the types of input and output streams used to load and save data in the control. The enum provides a list of constants like PlainText, RichText, UnicodePlainText etc.
MaskedTextBox:
This control looks same as a TextBox but can be used for taking the input in specific formats from the users. To set a format for input, select the Mask property in property window and click on the button beside it which opens a window, in it we can either choose a mask from list of available masks or select custom and specify our own mask format using zeros in the mask textbox below as following:
·         Railway PNR:         000-0000000
·         CC No.:                   0000-0000-0000-0000
Multi Document Interface:
When designing an application it can contain any no. of forms in it, right now to run the desired form we are explicitly specifying the form class name under Program class. But, when we provide the application to client we only give him the assemblies of the project (i.e. IL Code) so client doesn't have a chance to edit the class Program and specify the form class name he wants to run.To overcome the above problem we are provided with an approach known Multi-Document Interface, where in this approach an application will be having only one form as a startup Form which is referred as MDI Parent or MDI Container, so that clients don't require changing the form name under program class at any time. Rest of the forms in application will be under the control of MDI Parent Form and referred as MDI Child's. To make a form as MDI Parent set the property IsMdiContainer as true. To launch a form as child of parent create object of child form class, set its MdiParent property with parent forms reference and then call Show() method.
Note: an application can have only one MDI Parent and all other forms must be children of parent which should come and sit under parent. E.g.: Visual Studio by default launches as an MDI Container and the all other forms like “New Project” and “Add New Item” windows will come and sit under it as its children.

Layout:
When we have more than one child form opened at a time under parent, child forms will be arranged inside the parent by using a layout for arrangement, which can be any of the following 4 options like:
         I.            Cascade (d): child forms are arranged 1 on the top of the other.
        II.            TileVertical: child forms are arranged 1 beside the other.
      III.            TileHorizontal: child forms are arranged 1 below the other.
      IV.            ArrangeIcons:  all child forms icons are arranged with in the bottom of parent.

To test this now add a new Form in the Project naming it as MdiParent.cs, set its IsMdiContainer property as true to make it as a MDI Parent and also set the WindowState property as Maximized so that form gets launched to the full size of the screen. Add a MenuStrip control to the Form and place 2 menus on it: Forms and Layout. Under Forms Menu add a MenuItem for each child form to launch e.g.: Form1, Form2, Form3 etc. Under Layout Menu add the following MenuItems: Arrange Icons, Cascade, Horizontal and Vertical and write the following code:
Code under Each Form's MenuItems:              Form1 f = new Form1(); f.MdiParent = this; f.Show();
Code under Arrange Icons MenuItem:            this.LayoutMdi(MdiLayout.ArrangeIcons);
Code under Cascade MenuItem:                       this.LayoutMdi(MdiLayout.Cascade); 
Code under Vertical MenuItem:                       this.LayoutMdi(MdiLayout.TileVertical); 
Code under Horizontal MenuItem:                  this.LayoutMdi(MdiLayout.TileHorizontal);
User Controls
These are re-usable software components that are developed by application developers to consume under their applications. We can develop User Controls in 2 ways:
·         Creating a new control from existing controls.
·         Inherited or extended controls.
In the first case we design a control making use of existing controls and then write the required behavior for the control. To design a control first we need to define a class (because every control is a class) inheriting from the predefined class UserControl which provides a container for designing.
In the second case we don't design anything newly; we only copy the design of an existing control for adding new functionalities or behavior that is required. In this case we define a class that is inheriting from the control class for which new behavior has to be added.
                To create a control in first process we need to add UserControl Item Template in the project which provides a class that is inheriting from UserControl class, whereas in the second case we need to add Class Item Template and then inherit from the control class we want to extend.
Note: to develop UserControls we are provided with Windows Forms Control Library project template. But the controls whatever we develop are finally consumed from Windows Forms Applications only.
People working on controls are classified as:
         I.            Component Developers    
        II.            Application Developers or Component Consumers
The person who develops a control is known as component developer and those who consume the control are known as application developers or component consumers.
Creating a StopClock control:
Open a new project of types Windows Forms Control Library, name it as “ControlsProject”. By default the project comes with a class UserControl1 under the file UserControl1.cs, open the solution explorer and rename the file as StopClock.cs so that the class name as changes to StopClock. Now design the control as following:





Go to properties of MaskedTextBox, set the Mask property by clicking on the button beside the property, select “Time (US)”, set the text property as “0000” and also set the ReadOnly property as True, then add a Timer control and set the interval property as “1000”. Now go to code view and write the following code in the class:
Declarations:
int sec, min; string secstr, minstr;
Under Timer Tick Event:
if (sec < 59)
  sec += 1;
else {
  sec = 0; min += 1;
}
if (sec < 10)            {              secstr = "0" + sec.ToString();               }
else                         {              secstr = sec.ToString();                         }
if (min < 10)          {              minstr = "0" + min.ToString();            }
else                         {              minstr = min.ToString();                      }
mtbTime.Text = minstr + secstr; 
Under Start Button: timer1.Start();
Under Stop Button: timer1.Stop();
Under Reset Button: timer1.Stop(); mtbTime.Text = "0000"; min = sec = 0;
Now open solution explorer, right click on the project, select build which compiles the project and generates an assembly ControlsProject.dll at following location:
<drive>:\<folder>\ControlsProject\ControlsProject\bin\Debug
Consuming the control:
The control what we have developed can be consumed only by placing it on a Windows Form, so go to our “WindowsProject” open the ToolBox, right click on it, select “Add Tab” which adds a new tab in the ToolBox enter a name to it as “My Controls”. Now right click on the “My Controls” tab and select the option “Choose Items” which opens a dialog box, click on the browse button in it and select the assembly “ControlsProject.dll” from its physical location which adds the control under the new tab. Now add a new form in the project, place the StopClock control on it and run to test the control.
Developing a Inherited or Extended Control:
In case of an inherited control we copy the design of an existing control and then add newer behavior to the control. Now let us create a MyTextBox control inheriting from the existing TextBox control and add new properties to it. To do this open our ControlsProject under which we have developed the StopClock, add a new code file in the project naming it as “MyTextBox.cs” and write the following code:
using System; using System.Windows.Forms;
namespace ControlsProject {
   public class MyTextBox : TextBox  {
      public enum Options { Any, Char, CharOrDigit, Digit };
      Options opt = 0; bool flag = false;
      public bool AcceptDecimal {
         get { return flag; } set { flag = value; }
      }
      public Options SetOption {
         get { return opt; } set { opt = value; }
      }
      public MyTextBox() {
         this.KeyPress += new KeyPressEventHandler(MyTextBox_KeyPress);
                                                or
         this.KeyPress += MyTextBox_KeyPress;   //Only in Visual Studio 2012 (i.e. C# 5.0 or .Net Framework 4.5)
      }
      private void MyTextBox_KeyPress(object sender, KeyPressEventArgs e) {
         if (Convert.ToInt32(e.KeyChar) == 8)       return;
         switch (opt) {
            case Options.Digit:
               if (flag == true)
                  if (Convert.ToInt32(e.KeyChar) == 46)
                     return;
               if (char.IsDigit(e.KeyChar) == false) {
                  MessageBox.Show("Enter numerics only"); e.Handled = true;
               }
            break;
            case Options.Char:    
               if (char.IsLetter(e.KeyChar) == false && Convert.ToInt32(e.KeyChar) != 32) {
                  MessageBox.Show("Enter alphabets only"); e.Handled = true;
               }
            break;
            case Options.CharOrDigit:
               if (char.IsLetterOrDigit(e.KeyChar) == false) {
                  MessageBox.Show("Enter alpha-numerics only"); e.Handled = true;
               }
            break;
         }     
      }        
   }           
}
Recompile the project again so that the new control MyTextBox gets added to ControlsProject.dll. To consume this control go back to our WindowsProject, right click on MyControls tab we added earlier, select Choose Items, click Browse, select the ControlsProject.dll from its physical location again, which adds the MyTextBox control to our tab under StopClock control. Now we can place the control on any form and consume it by setting the required option value under SetOption property of the control.



                                             
_____________________________________________________END________________________________________
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;





Working with Multiple Projects and Solution
[PROJECT MANAGEMENTS]




While developing an application sometimes code will be written under more than 1 project also, where collection of those projects is known as a Solution. Whenever we open a new project by default VS will create one Solution and under it the project gets added, where a solution is a collection of projects and project is a collection of items.
Solution: Collection of Projects
                                       Project: Collection of Items
A Solution also requires a name, which can be specified by us while opening a new project or else will take name of the first project that is created under solution, if not specified. In our case solution name is OOPSProject because our project name is OOPSProject. A solution can have projects of different .net languages as well as can be of different project templates also like Windows Application, Console Application, Class Library etc. but a project cannot contain items of different .net languages, and they must be specific to one language only.
          To add a new project under our OOPSProject solution, right click on solution node in Solution Explorer and select add “New Project” which opens the new project window, under it select language as Visual C#, template as Console Application, name the project as “SecondProject” and click ok which adds the new project under the OOPSProject solution. By default the new project also comes with a class Program but under SecondProject namespace, now write following code in its main method & execute:
Console.WriteLine(“Second Project”);
Console.ReadLine();
To run the above class, first we need to set a property “StartUp Project”, because there are multiple project's under the solution and VS by default runs first project of the Solution only i.e. OOPSProject under the solution. To set the “StartUp Project” property and run classes under SecondProject open Solution Explorer, right click on SecondProject, select “Set as StartUp Project” and then run the project.
Note: if the new project is added with new classes we need to again set “StartUp Object” property under Second Projects property window, because each project has its own property window.
Saving Solution & Projects:
The application what we have created right now is saved physically on hard disk in the same hierarchy as  seen under Solution Explorer i.e. first a folder is created representing the solution and under that a separate folder is created representing each project and under that items corresponding to that project gets saved as following:
                                      <drive>:\<folder>\OOPSProject\OOPSProject
<drive>:\<folder>\OOPSProject\SecondProject
Note: a solution file gets saved with “.sln” extension and C# Project file gets saved with “.csproj” extension which can contain items specific to C# language only.
Compilation of Projects:
Whenever a project is compiled it generates an output file known as Assembly that contains IL Code of all the Items present in the project. The name of Assembly file will be same as the project name and will have an extension of either “.exe” or “.dll”. Assembly files are what we carry on to the client systems when the application has to be installed or deployed there, so they are also referred as units of deployment. All BCL were installed on our machines in the form of assemblies only. The assembly file of a project will be present under bin\Debug folder of that project's folder.
                                      <drive>:\<folder>\OOPSProject\OOPSProject\bin\Debug
<drive>:\<folder>\OOPSProject\SecondProject\bin\Debug
ildasm: Intermediate Language Dis-Assembler.
We can use it to dis-assemble an Assembly file and view the content of it. To check it out open the Visual Studio Command Prompt, go to the location where the assembly files of the project are present use it as following:
ildasm <name of the assembly file>
E.g.: Open Visual Studio Command Prompt, go to the following location and try the following:
<drive>:\<folder>\OOPSProject\OOPSProject\bin\Debug> ildasm OOPSProject.exe
<drive>:\<folder>\OOPSProject\SecondProject\bin\Debug> ildasm SecondProject.exe
Q. Can we consume classes of a project from other classes of same project?
Ans: Yes, we can consume them directly because all those classes were under same project and will be considered as a family.

Q. Can we consume the classes of a project from other projects?
Ans: Yes, we can consume but not directly, as they are under different projects. To consume them first we need to add reference of the assembly in which the class is present to the project who wants to consume it.

Q. How to add the reference of an assembly to a project?
Ans: To add reference of an assembly to a project open solution explorer, right click on the project to whom reference has to be added, select “Add Reference” option, which opens a window “Reference Manager”, in that select “Browse” option on LHS, then click on “Browse” button below and select the assembly we want to consume from its physical location and click ok. Now we can consume types of that assembly by referring with their namespace or importing the namespace. To test this go to OOPSProject Solution, right click on the SecondProject we have newly added, select add reference and add the reference of OOPSProject assembly from its physical location: <drive>:\<folder>\OOPSProject\OOPSProject\bin\Debug
Now add a new class under the SecondProject naming it as Class1.cs and write the following code in it:
using OOPSProject;
class Class1 {
  static void Main() {
    Rectangle r = new Rectangle(12.34, 56.78);
    Console.WriteLine(r.GetArea()); Console.WriteLine(r.GetPerimeter());
    Circle c = new Circle(34.56);
    Console.WriteLine(c.GetArea()); Console.WriteLine(c.GetPerimeter()); Console.ReadLine();
  }
}
Assemblies and Namespaces:
An assembly is an output file which gets generated after compilation of a project and it is physical. The name of an assembly file will be same as project name and can't be changed at all.
Project:      Source Code                                    Assembly: Compiled Code (IL Code)
A namespace is a logic container of types which are used for grouping types. By default every project has a namespace and its name is same as the project name, but we can change namespace names as per our requirements and more over a project can contain multiple namespaces in it also. For Example: TestProject -> when compiled -> generates an assembly with the name as TestProject, under it namespaces can be as following:
namespace NSP1 {
  Class1
  Class2
}
namespace NSP2 {
  Class3
  Class4
}
Whenever we want to consume a type which is defined under a project from other projects first we need to add reference of the assembly corresponding to that project and then only we can consume types of that assembly in the new project. While consuming types in the assembly for which reference is added we need to prefix type names with their namespace or import the namespace and consume the types.
Access Specifiers: these are also modifiers used to define scope of a type as well as their members i.e. who can access them and who cannot. C# supports 5 access specifier’s, those are:
1. private   2. internal  3. protected        4. protected internal   5. public
Note: members that are defined in a type with any scope or specifier are always accessible with in the type, restrictions comes into picture only when we try to access them outside of the type.

Private: members declared as private under a class or structure can't be accessed outside of the type in which they are defined and more over their default scope is private only. Types can't be declared as private, so private can be used only on members. Interfaces can't contain any private members and their default scope is public.
Protected: members declared as protected under a class can be accessed only with in the class or in a child class, non-child classes can't consume them. Types can't be declared as protected also, so this can also be used only on members.
Internal: members and types that are declared as internal can be consumed only with in the project, both from a child or non-child. The default scope for any type in C# is internal only.
Protected Internal: members declared as protected internal will have dual scope i.e. within the project they behave as internal providing access to anywhere in the project and out-side the project they will change to protected and still provides access to their child classes. Types cannot be declared as protected internal also, so this can also be used only on members.
Public: a type or member of a type if declared as public is global in scope which can be accessed from anywhere.
To test all these open VS -> go to File Menu -> select New Project -> select language as Visual C# -> choose Console Application Project Template, name the project as “AccessDemo1” and re-name the solution as “MySolution”. By default the project comes with a class Program, write the following code in it making it as public.
public class Program { //Case 1 (Accessing members of a class from same class)
  private void Test1() {
    Console.WriteLine("Private Method");
  }
  internal void Test2() {
    Console.WriteLine("Internal Method");
  }
  protected void Test3() {
    Console.WriteLine("Protected Method");
  }
  protected internal void Test4() {
    Console.WriteLine("Protected Internal Method");
  }
  public void Test5() {
    Console.WriteLine("Public Method");
  }
  static void Main(string[] args) {
    Program p = new Program(); p.Test1();p.Test2();p.Test3();p.Test4();p.Test5(); Console.ReadLine();
  }
}
Now add a new class Two.cs under the project and write the following:
class Two : Program { //Case 2 (Accessing members of a class from a child class of the same project)
  static void Main() {
    Two obj = new Two(); obj.Test2();obj.Test3();obj.Test4();obj.Test5(); Console.ReadLine();
  }
}
Now add another new class Three.cs in the project and write the following:
class Three {                 //Case 3 (Accessing members of a class from a non-child class of the same project)
  static void Main() {
    Program p = new Program(); p.Test2(); p.Test4(); p.Test5(); Console.ReadLine();
  }
}
Now Add a new project under the solution of type Console Application, name it as AccessDemo2, rename default file Program.cs as Four.cs so that class name also changes as Four, now add the reference of AccessDemo1 assembly from its physical location to AccessDemo2 project and write the following code.
class Four : AccessDemo1.Program {  //Case 4 (Accessing members of a class from a child class of another project)
  static void Main() {
    Four obj = new Four(); obj.Test3(); obj.Test4(); obj.Test5(); Console.ReadLine();
  }
}
Now add a new class under AccessDemo2 project, naming it as Five.cs and write the following:
using AccessDemo1
class Five {          //Case 5(Accessing members of a class from a non-child class of another project)
  static void Main() {
    Program p = new Program(); p.Test5(); Console.ReadLine();
  }
}





Language Interoperability:
As discussed earlier the code written under 1 .net language can be consumed from any other .net languages, to test this add a new project under “MySolution” choosing the language as Visual Basic, template as Class Library and name the project as VBProject1. A Class Library is a collection of types that can be consumed but not executed; extension of the assembly will be .dll in case of Class Library projects.

·       VB is not a case-sensitive language.
·       VB does not have any curly braces; the end of a block is represented with a matching End stmt.
·       VB does not have any semi colon terminators each statement must be in a new line.
·       In VB language methods are divided into 2 categories like: 
1.    Functions (Value returning methods)
2.    Sub-Routines (Non-value returning methods)

By default the project comes with a class Class1 within the file Class1.vb, write following code in it:
Public Class Class1
  Public Function SayHello(   name As String) As String
    Return "Hello " & name
  End Function
  Public Sub AddNums(x As Integer, y As Integer)
    Console.WriteLine(x + y)
  End Sub
  Public Sub Math(a As Integer, b As Integer, ByRef c As Integer, ByRef d As Integer)
    c = a + b
    d = a * b
  End Sub
End Class
Now to compile the project open solution explorer, right click on VBProject1 and select “Build” option which compiles and generates an assembly VBProject1.dll. Now add a new class under AccessDemo2 project as TestVB.cs and add the reference of assembly VBProject1.dll from its physical location, then write the following code under TestVB class:
using VBProject1;
class TestVB {
  static void Main() {
    Class1 obj = new Class1();
    obj.AddNums(100, 50);
    int x = 0, y = 0; obj.Math(100, 25, ref x, ref y); Console.WriteLine(x + "  " + y);
    string str =obj.SayHello(“Raju”);  Console.WriteLine(str);  Console.ReadLine();
  }
}
Now to test consuming CSharp code in VB.Net add another project under the MySolution of language VB.Net, type as ConsoleApplication and name it as VBProject2. By default the project comes with a file Module1.vb, open the solution explorer, delete that file under project and add a new class naming it as TestCS.vb. Now add the reference of AccessDemo1 assembly to the current project choosing it from its physical location and write the following code under TestCS Class:
Imports AccessDemo1
Public Class TestCS : Inherits Program
  Shared Sub Main()
    Dim obj As New TestCS()
    obj.Test3()
    obj.Test4()
    obj.Test5()
    Console.ReadLine()
  End Sub
End Class
Q. How to restrict a class not to be accessible for any other class to consume?
Ans: This can be done by declaring all the class c onstructors as private.
Q. How to restrict a class not to be inherited for any other class?
Ans: This can be done by declaring class as sealed.
Q. How to restrict a class not to be accessible for any other class to consume by creating its object?
Ans: This can be done by declaring all the class constructors as protected.
Extension Methods
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.







Core idea of defining Extension Methods:
·       Extension methods should be defined in a static class.
·       The first parameter of an extension method is to specify for which type the method has to be bound with, pre-fixed with “this” keyword and this parameter is not considered while calling the method.
·       If an extension method is defined with “n” no. of parameters while calling we have n – 1 parameters only.
·       We can never bind an extension method with multiple types.
·       Extension methods can't access the private members in the extended type.
·       If you want to add extension methods to a type, you don't need the source code of that type.
·       If you create extension methods that have the same signature methods inside the type you are extending, then the extension methods will never be called.
Adding extension methods to pre-defined classes of Base Class Library
Add a new class in our OOPSProject naming the class as MyExtension.cs and write the following code.
static class MyExtension {
  public static int factorial(this int i) {
    if (i <= 1) return 1;
    if (i == 2) return 2;
    else
      return i * factorial(i - 1);
  }
  public static string ToProper(this string value) {
    if (value.Length > 0) {
      char[] array = value.ToCharArray(); array[0] = char.ToUpper(array[0]); return new string(array);
    }
    return value;
  }
  public static void TestMethod(this Program p) {
    Console.WriteLine("Extension Method.");
  }
}
Now to call the above methods add a new class TestExtension.cs and write the following code:
class TestExtension {
  static void Main(string[] args) {
    Program p = new Program(); p.TestMethod();
    int x = 6; Console.WriteLine(x.factorial());
    string str = "hello"; Console.WriteLine(str.ToProper());Console.ReadLine();
  }
}
Adding extension methods to our own classes
Add a new class OldClass.cs and write the following code:
class OldClass {
  public int x;
  public OldClass(int x) {
    this.x = x;
  }
  public void Test1() {
    Console.WriteLine("Method One: " + this.x);
  }
  public void Test2() {
    Console.WriteLine("Method Two: " + this.x);
  }
}
Add another class NewClass.cs for defining extension methods for OldClass.cs and write the following code:
static class NewClass {
  public static void Test3(this OldClass oc) {
    Console.WriteLine("Method Three");
  }
  public static void Test4(this OldClass oc, int a) {
    Console.WriteLine("Method Four: " + a);
  }
  public static void Test5(this OldClass oc) {
    Console.WriteLine("Method Five: " + oc.x);
  }
}
Now to test the extension methods we defined add a new class TestOldClass.cs and write the following code:
class TestOldClass {
  static void Main() {
    OldClass obj = new OldClass(100);
    obj.Test1(); obj.Test2(); obj.Test3(); obj.Test4(10); obj.Test5();
    Console.ReadLine();
  }
}
Destructors
Destructors are used to destruct objects (instances) of classes. A destructor is a special method just like a constructor, whereas constructors are called when object of a class is created and destructors are called when object of a class is destroyed. Both of them will have the same name i.e. the name of the class in which they are defined, but to differentiate between each other we prefix destructor with a tilde (~) operator. For Example:
class Test {
  Test() {
    //Constructor
  }
  ~Test() {
    //Destructor
  }
Remarks:
·       Destructors cannot be defined in structs. They are only used with classes.
·       A class can only have one destructor and cannot be inherited or overloaded.
·       Destructors cannot be called. They are invoked automatically.
·       A destructor does not take modifiers or have parameters.

The programmer has no control over when the destructor is called because this is determined by the garbage collector; garbage collector calls the destructor in any of the following cases:
1.    Called in the end of a programs execution and destroys all objects that are associated with the program.
2.    In the middle of a programs execution also the garbage collector checks for objects that are no longer being used by the application. If it considers an object is eligible for destruction, it calls the destructor and reclaims the memory used to store the object.
3.    It is possible to force garbage collection by calling GC.Collect() method to check for un-used objects and reclaim the memory used to store the objects.

Note: you can force the garbage collector to do clean up by calling the GC.Collect method, but in most cases this should be avoided because it may create performance issues, i.e. when the garbage collector comes into picture for reclaiming memory of un-used objects it will suspend the execution of programs.
To test a destructor add a new class DestDemo.cs and write the following:
class DestDemo {
  public DestDemo() {
    Console.WriteLine("Object is created.");
  }
  ~DestDemo() {
    Console.WriteLine("Object is destroyed.");
  }
  static void Main()
  {
    DestDemo d1 = new DestDemo(); DestDemo d2 = new DestDemo(); DestDemo d3 = new DestDemo();
    //d1 = null; d3 = null; GC.Collect();
  Console.ReadLine();
  }
}
Execute the above program by using Ctrl + F5 and watch the output of the program, first it will call the constructor for 3 times because 3 objects are created and then waits at the ReadLine() statement to execute, now press the enter key to finish the execution of ReadLine(), immediately the destructor gets called for 3 times because it is the end of programs execution, so all the 3 objects associated with the program are destroyed. This proves that destructor is called in the end of a programs execution.
         
Now un-comment the commented code in the Main method of the above program and re-execute the program again by using Ctrl + F5 to watch the difference in the output, in this case 2 objects are destroyed before the execution of ReadLine() because we have marked them as un-used and called the Garbage Collector explicitly and the third object is destroyed in the end of programs execution.

Destructors and Inheritance:
As we are aware that whenever a child class object is created it will call its parents class constructor internally, same as this when a child class object is destroyed it will also call the parent classes destructor, but the difference is constructor are called in "top to bottom" hierarchy and destructor are called in "bottom to top" hierarchy. To test this add a new class DestDemo2.cs and write the following code:

class DestDemo2 : DestDemo {
  public DestDemo2() {
    Console.WriteLine("Object2 is created.");
  }
  ~DestDemo2() {
    Console.WriteLine("Object2 is destroyed.");
  }
  static void Main() {
    DestDemo2 obj = new DestDemo2();
    Console.ReadLine();
  }
}

Conclusion about Destructors:
In general, C# does not require as much memory management; it is needed when you develop with a language that does not target a runtime with garbage collection. This is because the .NET Framework garbage collector implicitly manages the allocation and release of memory for your objects. However, when your application encapsulates unmanaged resources such as files, databases and network connections, you should use destructors to free those resources.
Properties
A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field (Variable). Properties can be used as if they are public data members, but they are actually special methods called accessors. This enables data to be accessed easily and still helps promote the safety and flexibility of methods. Suppose a class is associated with any value and if we want to access that value outside of the class access to that value can be given in 2 different ways:

       I.            By storing the value under a public variable, access can be given to that value outside of the class, for Example:
public class Circle {
                     public double Radius = 12.34;
}
Now by creating the object of above class we can get or set a value to the variable as following:
class TestCircle {
                     static void Main() {
                     Circle c = new Circle();
                     double Radius = c.Radius;            //Getting the old value of Radius
                     c.Radius = 56.78;                           //Setting a new value for Radius
                     }
}
Note: but in this approach it will provide Read/Write access to the value i.e. anyone can get the old value of the variable as well as anyone can set with a new value for the variable.

     II.            By storing the value under a private variable also we can provide access to the value outside of the class by defining a property on that variable. The advantage in this approach is it can provide access to the value in 3 different ways:
                               I.            Only get access (Read Only Property)
                             II.            Only set access (Write Only Property)
                          III.            Both get and set access (Read/Write Property)

Syntax to define a property:
[<modifiers>] <type> Name {
            [ get { -Stmts } ]                   //Get Accessor
            [ set { -Stmts } ]          //Set Accessor
      }
·       A property is one or two code blocks, representing a get accessor and/or a set accessor.
·       The code block for the get accessor is executed when the property is read and the body of the get accessor resembles that of a method. It must return a value of the property type. The execution of the get accessor is equivalent to reading the value of the field. E.g.: string str = "Hello"; int length = str.Length;
·       The code block for the set accessor is executed when the property is assigned with a new value and the set accessor resembles a method whose return type is void. It uses an implicit parameter called value, whose type is the type of the property. E.g.: Console.Title = "My Console Window";
·       A property without a set accessor is considered as read-only. A property without a get accessor is considered as write-only. A property that has both accessors is considered as read-write.

Remarks:
·       Properties can be marked as public, private, protected, internal, or protected internal. These access modifiers define how users of the class can access the property. The get and set accessors for the same property may have different access modifiers. For example, the get may be public to allow read-only access from outside the class, and the set may be private or protected.

·       A property may be declared as a static property by using the static keyword. This makes the property available to callers at any time, even if no instance of the class exists.
·       A property may be marked as a virtual property by using the virtual keyword. This enables derived classes to override the property behavior by using the override keyword. A property overriding a virtual property can also be sealed, specifying that for derived classes it is no longer virtual.
·       A property can be declared abstract. This means that there is no implementation in the class, and derived classes must write their own implementation.

To test properties first add a new code file Cities.cs and write the following code:
using System;
namespace OOPSProject {
  public enum Cities { Bengaluru, Chennai, Delhi, Hyderabad, Kolkata, Mumbai }
}

Now add a new class Customer.cs and write the following code:
public class Customer {
  int _Custid; string _Cname, _State; double _Balance; bool _Status; Cities _City;
  public Customer(int Custid) {
    this._Custid = Custid; this._Cname = "Smith"; this._Balance = 5000; this._Status = false;
    this._City = 0; this._State = "Karnataka"; this.Country = "India";
  }
  public int Custid {                          //Read Only Property
    get { return _Custid; }
  }
  public string Cname {                             //Read/Write Property
    get { return _Cname; } set { _Cname = value; }
  }
  public bool Status {                      //Read/Write Property
    get { return _Status; } set { _Status = value; }
  }
  public double Balance {                         //Read/Write property with conditions
    get {
      if(_Status == true)
        return _Balance;
      return 0;
    }
    Set {
      if(value >= 500)
        _Balance = value;
    }
  }
  public Cities City {                         //Enumerated Property
    get { return _City; } set { _City = value; }
  }
  public string State {                      //Property with independent scope to each property accessor
    get { return _State; } protected set { _State = value; }
  }
  public string Country {                           //Automatic Property
    get; private set;
  }
}
Note: The contextual keyword value is used in the set accessor in ordinary property declarations. It is similar to an input parameter on a method. The word value references the value that client code is attempting to assign to the property.

Enumerated Property:
It is a property that provides with a set of constants to choose from, for example BackgroundColor property of the Console class that provides with a list of constant colors to choose from under an enum ConsoleColor.
          E.g.: Console.BackgrounColor = ConsoleColor.Blue;
An enum is a distinct type that consists of a set of named constants called the enumerator list. Usually it is best to define an enum directly within a namespace so that all classes in the namespace can access it with equal convenience. However, an enum can also be nested within a class or struct.

Syntax to define an enum:
[<modifiers>] enum <Name> { <list of values> };
E.g.: public enum Days { Monday, Tuesday, Wednesday, Thursday, Friday };
          By default, the first value is represented with an index 0, and the value of each successive enumerator is increased by 1. For example, in the following enumeration, Monday is 0, Tuesday is 1, Wednesday is 2, and so forth. To define an Enumerated Property adopt the following process:

Step 1: define an enum with the list of constants we want to provide for the property to choose.
E.g.: public enum Days { Monday, Tuesday, Wednesday, Thursday, Friday };
Step 2: declare a variable of type enum on which we want to define a property.
E.g.: Days _Day = 0; or Days _Day = Days.Monday;
Step 3: now define a property on the enum variable for providing access to the variables value.
          public Days Day {
            get { return _Day; }
            set { _Day = value; }
          }

Auto-Implemented properties:
In C# 3.0 and later, auto-implemented properties make property-declaration more concise when no additional logic is required in the property accessors. E.g.: Country property in our Customer class.

Note: it is important to remember that auto-implemented properties must contain both get and set blocks either with the same access modifier or different also.

To consume the properties we have defined above add a new class TestCustomer.cs and write the following:
class TestCustomer {
  static void Main() {
    Customer obj = new Customer(101);
    Console.WriteLine("Custid: " + obj.Custid);
    //obj.Custid = 102; //Can't be assigned to as property is read only
   
    Console.WriteLine("Old Name: " + obj.Cname);
    obj.Cname = "John Smith"; Console.WriteLine("New Name: " + obj.Cname);
    Console.WriteLine("Current Status: " + obj.Status);
    Console.WriteLine("Current Balance: " + obj.Balance); //Prints Balance as 0 because status is in-active
    obj.Status = true; //Activating the status again
    Console.WriteLine("Modified Status: " + obj.Status);
    Console.WriteLine("Current Balance: " + obj.Balance); //Prints actual Balance as status is active again
    obj.Balance -= 4600; //Transaction fails
    Console.WriteLine("Balance when transaction failed: " + obj.Balance); //Prints old balance value only
    obj.Balance -= 4500; //Transaction succeeds
    Console.WriteLine("Balance when transaction succeeded " + obj.Balance); //Prints new balance value

    Console.WriteLine("Current City: " + obj.City);
    obj.City = Cities.Hyderabad;
    Console.WriteLine("Modified City: " + obj.City);
    Console.WriteLine("Current State: " + obj.State);
    //obj.State = "AP"; //Can't be assigned with a value as current class is not a child class of Customer
           
    Console.WriteLine("Country: " + obj.Country); Console.ReadLine();
  }
}
Object Initializers
Object initializers let you assign values to any accessible variables or properties of an object at creation time without having to explicitly invoke a constructor. You can use object initializers to initialize type objects in a declarative manner without explicitly invoking a constructor for the type. Object Initializers will use the default constructor for initializing variables or properties. To test these add a new class Student.cs and write the following:
public class Student {
  int _Sno, _Class; string _Sname; float _Marks, _Fees;
  public int Sno {
    get { return _Sno; } set { _Sno = value; }
  }
  public int Class {
    get { return _Class; } set { _Class = value; }
  }
  public string Sname {
    get { return _Sname; } set { _Sname = value; }
  }
  public float Marks {
    get { return _Marks; } set { _Marks = value; }
  }
  public float Fees {
    get { return _Fees; } set { _Fees = value; }
  }
  public override string ToString() {
    return "Sno: " + _Sno + "\nSname: " + _Sname + "\nMarks: " + _Marks + "\nClass: " + _Class + "\nFees: " + _Fees;
  }
}
Now to consume object initializers add a new class TestStudent.cs and write the following:
class TestStudent {
  static void Main() {
    Student s1 = new Student {
      Sno = 1, Sname = "Ajay", Class = 10, Marks = 500.5f, Fees = 5000.00f
    };

    Student s2 = new Student {
      Sno = 2, Sname = "Vijay", Class = 9               
    };

    Student s3 = new Student {
      Sno = 3, Class = 8, Marks = 550.00f               
    };

    Console.WriteLine(s1); Console.WriteLine(s2); Console.WriteLine(s3); Console.ReadLine();
  }
}
Indexers
Indexers allow instances of a class or struct to be indexed just like arrays. Indexers resemble properties except that their accessors take parameters. Indexers are syntactic conveniences that enable you to create a class, struct, or interface that client applications can access just as an array. Defining an indexer allows you to create classes that act like "virtual arrays." Instances of that class can be accessed using the [] array access operator. Defining an indexer in C# is similar to defining operator [] in C++, but is considerably more flexible. For classes that encapsulate array- or collection-like functionality, using an indexer allows the users of that class to use the array syntax to access the class. An indexer doesn't have a specific name like a property it is defined by using “this” keyword.

Syntax to define Indexer:
[<modifiers>] <type> this[<param list>] {
  [ get { -Stmts } ]          //Get Accessor
  [ set { -Stmts } ] //Set Accessor
}

Indexers Overview:
·       This keyword is used to define the indexers.
·       The out and ref keyword are not allowed on parameters
·       A get accessor returns a value. A set accessor assigns a value.
·       The value keyword is only used to define the value being assigned by the set indexer.
·       Indexers do not have to be indexed by an integer value; it is up to you how to define the specific look-up mechanism.
·       Indexers can be overloaded.
·       Indexers can't be defined as static.
·       Indexers can have more than one formal parameter, for example, when accessing a two-dimensional array.
To define indexers add a new class Employee.cs and write the following:
public class Employee {
  int _Empno; string _Ename, _Job; double _Salary;
  public Employee(int Empno) {
    this._Empno = Empno; this._Ename = "Scott"; this._Job = "Manager"; this._Salary = 8000.00;
  }
  public object this[int index] {
    get {
      if (index == 0) { return _Empno; }
      else if (index == 1) { return _Ename; }
      else if (index == 2) { return _Job; }
      else if (index == 3) { return _Salary; }
      return null;
    }
    set {
      if (index == 1) { _Ename = value.ToString(); }
      else if (index == 2) { _Job = value.ToString(); }
      else if (index == 3) { _Salary = Convert.ToDouble(value); }
    }
  }
  public object this[string name] {
    get {
      if (name.ToLower() == "empno") { return _Empno; }
      else if (name.ToLower() == "ename") { return _Ename; }
      else if (name.ToLower() == "job") { return _Job; }
      else if (name.ToLower() == "salary") { return _Salary; }
      return null;
    }
    set {
      if (name.ToUpper() == "ENAME") { _Ename = value.ToString(); }
      else if (name.ToUpper() == "JOB") { _Job = value.ToString(); }
      else if (name.ToUpper() == "SALARY") { _Salary = Convert.ToDouble(value); }
    }
  }
}
To consume indexers add a new class TestEmployee.cs and write the following:
class TestEmployee {
  static void Main() {
    Employee Emp = new Employee(1001);
    Console.WriteLine(Emp[0]); Console.WriteLine(Emp[1]); Console.WriteLine(Emp[2]); Console.WriteLine(Emp[3]);    
   
    Emp[1] = "Smith"; Emp["Job"] = "President"; Emp[3] = 12000;
    Console.WriteLine(); Console.WriteLine(Emp["Empno"]); Console.WriteLine(Emp["Ename"]);
    Console.WriteLine(Emp["Job"]); Console.WriteLine(Emp["Salary"]); Console.ReadLine();
  } 
}
Exceptions and Exception Handling
In the development of an application we will be coming across 2 different types of errors, like:
·       Compile time errors.
·       Runtime errors.

Errors which occur in a program due to syntactical mistakes at the time of program compilation are known as compile time errors and these are not considered to be dangerous.
Errors which occur in a program while the execution of program is taking place are known as runtime errors, which can be due to various reasons like wrong implementation of logic, invalid input supplied to the program, missing of required resources etc., these errors are considered to be dangerous because when they occur under the program the program terminates abnormally at the line where the error got occurred without executing the next lines of code. To test this, add a new class naming it as ExceptionDemo.cs and write the following code:
class ExceptionDemo {
  static void Main() {
    int x, y, z;
    Console.Write("Enter value for x: " ); x = int.Parse(Console.ReadLine());
    Console.Write("Enter value for y: " ); y = int.Parse(Console.ReadLine());
    z = x / y; Console.WriteLine(z); Console.WriteLine("End of the program.");     
  }
}
          When we execute the above program there are chances of getting few runtime errors under the program, to check those, enter the value for y as zero or enter character input for x or y values, so in both the cases when the error got occurred program gets terminated at the same line where the error got occurred.
Exception: In C#, errors in the program at run time are caused through the program by using a mechanism called exceptions. Exceptions can be thrown by the .NET Framework common language runtime (CLR) when basic operations fail or by code in a program. Exceptions are represented as classes derived from class Exception of System namespace. Throwing an exception involves creating an instance of an exception-derived class, and then throwing the object by using the throw keyword. There are so many Exception classes under the base class library where each class is defined representing a different type of error that occurs under the program, for example: FormatException, NullReferenceException, IndexOutOfRangeException, ArithmeticException etc.

Note: Exceptions are basically 2 types, like SystemExceptions and ApplicationExceptions. System Exception are pre-defined exception that are fatal errors which occurs on some pre-defined error conditions like DivideByZero, FormatException, NullReferenceException etc. ApplicationExceptions are non-fatal application errors i.e. these are error that are caused by the programs explicitly. Whatever the exception it is every class is a sub class of class Exception only. The hierarchy of exception classes will be as following:
Ø Exception
Ø SystemException
Ø FormatException
Ø NullReferenceException
Ø IndexOutOfRangeException
Ø ArithmeticException
Ø DivideByZeroException
Ø OverflowException
Ø ApplicationException
Exception Handling: It is a process of stopping the abnormal termination of a program whenever a runtime error occurs under a program; if exceptions are handled under a program we will be getting the following benefits:
1.    Abnormal termination is stopped; so statements that are not related with the error can be still executed.
2.    We can also take any corrective actions which can resolve the problem that may occur due to the errors.
3.    Display user friendly messages to end users so that they can fix the error provided if it is in his control.

To handle an error we need to enclose the code of the program under some special blocks known as try and catch blocks that should be used as following:

          try {
            -Statements which will cause the runtime errors.
            -Statements which should not execute when the error got occurred.
          }
          catch(<exception class name> <var>) {
            -Statements which should execute only when the error got occurred.
          }
          ---<multiple catch blocks if required>---

To test handling exceptions add a new class TryCatchDemo.cs and write the following code:

class TryCatchDemo {
  static void Main() {
    int x, y, z;
    try {
      Console.Write("Enter value for x: " ); x = int.Parse(Console.ReadLine();
      Console.Write("Enter value for y: " ); y = int.Parse(Console.ReadLine());
      z = x / y; Console.WriteLine(z);
    }
    catch(DivideByZeroException ex1) { Console.WriteLine("Divisor value should be zero."); }
    catch(FormatException ex2) { Console.WriteLine("Input values must be numeric."); }
    catch(Exception ex) { Console.WriteLine(ex.Message); }
    Console.WriteLine("End of the program.");
  }   
}

If we enclose the code under try and catch blocks the execution of program will take place as following:
·       If all the statements under try block are successfully executed (i.e. no error in the program), from the last statement of try the control directly jumps to the first statement which is present after all the catch blocks.
·       If any statement under try causes an error from that line, without executing any other line of code in try, control directly jumps to catch block searching for a matching catch block to handle the error:
·       If a matching catch block is available exceptions are caught by that catch block, executes the code inside of that catch block and from there again jumps to the first statement which is present after all the catch blocks.
·       If a catch block is not available to catch that exception which got occurred abnormal termination takes place again on that line.
Note: Message is a property under the Exception class which gets the error message associated with the exception that got occurred under the program, this property was defined as virtual under the class Exception and overridden under all the child classes of class Exception as per their requirement, that is the reason why when we call (ex.Message), even if “ex” is the reference of parent class, it will get the error message that is associated with the child exception class but not of itself because we have already learnt in overriding that “parent’s reference which is created by using child classes object can call child classes overridden members”.

Finally Block: this is another block of code that can be paired with try along with catch or without catch block also and the specialty of this block is code written under this block gets executed at any cost i.e. when an exception got occurred under the program or an exception did not occur under the program. All statements under try gets executed only when there is no exception under the program and statements under catch block will be executed only when there is exception under the program where as code under finally block gets executed in both the cases. To test finally block add a new class FinallyDemo.cs and write the following code:

class FinallyDemo {
  static void Main() {
    int x, y, z;
    try {   
      Console.Write("Enter value for x: " ); x = int.Parse(Console.ReadLine());
      Console.Write("Enter value for y: " ); y = int.Parse(Console.ReadLine());
      If (y == 1) { return; } z = x / y; Console.WriteLine(z);
    }
    catch(Exception ex) { Console.WriteLine(ex.Message); }
    finally { Console.WriteLine("Finally block executed."); }
    Console.WriteLine("End of the program.");
  }
}
          Execute the above program for 2 times, first time by giving input which doesn’t cause any error and second time by giving the input which causes an error and check the output where in both the cases finally block gets executed.
In both the cases not only finally block along with it “End of the program” statement also gets executed, now test the program for the third time by giving the divisor value i.e. value to y as 1, so that the condition in the try block gets satisfied and return statement gets executed. As we are aware that return is a jump statement which jumps out of the method in execution, but in this case it will jump out only after executing the finally block of the method because once the control enters into try we cannot stop the execution of finally block.

Note: try, catch and finally blocks can be used in 3 different combinations like:
       I.            try and catch: in this case exceptions that occur in the program are caught by the catch block so abnormal termination will not take place.
     II.            try, catch and finally: in this case behavior will be same as above but along with it finally block keeps executing in any situation.
  III.            try and finally: in this case exceptions that occur in the program are not caught because there is no catch block so abnormal termination will take place but still the code under finally block gets executed.

Application Exceptions: these are non-fatal application errors i.e. these are error that are caused by the programs explicitly. Application exceptions are generally raised by programmers under their program basing on their own error conditions, for example in a division program we don’t want the divisor value to be an odd number. If a programmer wants to raise an exception explicitly under his program he needs to do 2 things under the program.
1.    Create an object of any exception class.
2.    Throw that object by using “throw statement.” E.g.: throw <object of exception class>

While creating an Exception class object to throw explicitly we are provided with different options in choosing which exception class object has to be created to throw, like:
1.    We can create object of a pre-defined class i.e. ApplicationException by passing the error message that has to be display when the error got occurred as a parameter to the class constructor and then throw that object.
E.g. ApplicationException ex = new ApplicationException (“<error message>”);
        throw ex;
                                      or
        throw new ApplicationException (“<error message>”);
2.    We can also define our own exception class, create object of that class and throw it when required. If we want to define a new exception class we need to follow the below process:
                               I.            Define a new class inheriting from any pre-defined Exception class (but ApplicationException is preferred as we are dealing with application exceptions) so that the new class also is an exception.
                             II.            Override the Message property inherited from parent by providing the required error message.

To test this first add a new class under the project naming it DivideByOddNoException.cs and write the following:
public class DivideByOddNoException : ApplicationException {
  public override string Message {
    get { return “Attempted to divide by odd number.”; }
  }
}
Now add a new class ThrowDemo.cs and write the following code:
class ThrowDemo {
  static void Main() {
    int x, y, z;
    Console.Write("Enter value for x: " ); x = int.Parse(Console.ReadLine());
    Console.Write("Enter value for y: " ); y = int.Parse(Console.ReadLine());
    if(y % 2 > 0) {
      throw new ApplicationException(“Divisor should not be an odd number.”);
      //throw new DivideByOddNoException();
    }
    z = x / y; Console.WriteLine(z);
    Console.WriteLine("End of the program.");
  }
}
          Test the above program for the first time by giving the divisor value as an odd number and now ApplicationException will raise and displays the error message “Divisor should not be an odd number”. Now comment the first throw statement and uncomment the second throw statement so that when the divisor value is an odd number DivideByOddNoException will raise and display the error message as “Attempted to divide by odd number”.


......................................................................................................................................................................................................................................................................................................................................................................


                                                                       ASSEMBLIES




Assemblies are the building blocks of .NET Framework applications. An assembly is a collection of types and resources that are built to work together and form a logical unit of functionality. An assembly provides the common language runtime with the information it needs to be aware of type implementations. To the runtime, a type does not exist outside the context of an assembly.
Every project after compilation will generate an output file known as assembly. The name of an assembly file will be same as the project name. The assembly corresponding to a project will be present under bin\Debug folder of that project folder. Assemblies are known as units of deployment because once the project development is completed what we carry and install on the client systems is the assembly files only. The extension of an assembly file will be either .exe (executable) or .dll (dynamic link library).
                Windows Forms Applications, Console Applications, WPF Applications and Windows Services projects will generate an .exe assembly. Class Library and Windows Forms Control Library projects will generate a .dll assembly.
Exe assemblies are known as in-process components which were capable of running on their own as well as provide the support for others to execute. When we work with project templates like Windows Forms Applications, Console Applications, WPF Applications and Windows Services they generate an exe assembly when compiled.
                Dll assemblies are known as out-process components which were not capable of running on their own they can only support others to execute. When we work with project templates like Class Library and Windows Forms Control Library they generate a dll assembly when compiled.

Note: every application is a blend of both .dll and .exe assemblies combined together to give better efficiency.





Creating an assembly to test it is by default private:
Open a new project of type Class Library and name it as “PAssembly”, which will by default come with a class Class1 under the file Class1.cs. Now write the following code under the class:
public string SayHello() {
   return "Hello from private assembly.";
}
Now compile the project by opening the Solution Explorer, right click on the project and select “Build” which will compile and generate an assembly with the name as PAssembly.dll.
Note: we can find path of assembly in the output window present at bottom of the studio after build.
Testing the assembly we have created:
Open a new project of type Windows, name it as “TestPAssembly”, place a button on Form and set its text as “Call SayHello() Method of Class1 in PAssembly.dll”. Now add the reference of PAssembly.dll from its physical location and write the following code under click of button:
                                                                PAssembly.Class1 obj = new PAssembly.Class1();
MessageBox.Show(obj.SayHello());
Run the project to test it, then go and verify under bin/debug folder of current project where we can find a copy of PAssembly.dll as it is private assembly.

Note: the advantage of a private assembly is faster execution as it was in the local folder, whereas the draw back was multiple copies gets created when multiple projects adds the reference to consume it.
Shared Assemblies:
                If we intend to use an assembly among several applications private assemblies are not feasible, in such cases we can install it into a centralized location known as the global assembly cache. Each computer where the common language runtime is installed has this machine-wide code cache. The global assembly cache stores assemblies specifically designated to be shared by several applications on the computer. All BCL assemblies are shared .dll assemblies only, so we can find them under GAC. If an assembly is shared multiple copies of the assembly will not be created even if being consumed by multiple projects, only a single copy under GAC serves all the projects.





Note: administrators often protect the Windows directory using an access control list (ACL) to control write and execute access. Because the global assembly cache is installed in the Windows directory, it inherits that directory's ACL. It is recommended that only users with Administrator privileges be allowed to add or delete files from the global assembly cache.
Managing assemblies in Global Assembly Cache:
                To manage assemblies in GAC like install, un-install and view we are provided with a tool known as Gacutil.exe (Global Assembly Cache Tool). This tool is automatically installed with Visual. To run the tool, use the Visual Studio Command Prompt. These utilities enable you to run the tool easily, without navigating to the installation folder. To use Global Assembly Cache on your computer: On the taskbar, click Start, click All Programs, click Visual Studio, click Visual Studio Tools, and then click Visual Studio Command Prompt and type the following:
gacutil [/i | /u | /l] <assembly name>
/i:            Install
/u:           Un-install
/l:            List
Note: assemblies deployed in the global assembly cache must have a strong name. When an assembly is added to the global assembly cache, integrity checks are performed on all files that make up the assembly.
Strong Name:
A strong name consists of the assembly's identity - its simple text name, version number, and public key.

  1. Name: it was the name of an assembly used for identification. Every assembly by default has name.
  2. Version: software’s maintain versions for discriminating changes that has been made from time to time. As an assembly is also a software component it will maintain versions, whenever the assembly is created it has a default version for it i.e. 1.0.0.0, which can be changed when required.
  3. Public Key: as GAC contains multiple assemblies in it, to identify each assembly it will maintain a key value for the assembly known as public key, which should be generated by us and associate with the assembly to make it Strong Named.

You can ensure that a name is globally unique by signing an assembly with a strong name. In particular, strong names satisfy the following requirements:
Strong names guarantee name uniqueness by relying on unique key pairs. No one can generate the same assembly name that you can. Strong names protect the version lineage of an assembly.
A strong name can ensure that no one can produce a subsequent version of your assembly. Users can be sure that a version of the assembly they are loading comes from the same publisher that created the version the application was built with.
Strong names provide a strong integrity check. Passing the .NET Framework security checks guarantees that the contents of the assembly have not been changed since it was built.

Generating a Public Key:
To sign an assembly with a strong name, you must have a public key pair. This public cryptographic key pair is used during compilation to create a strong-named assembly. You can create a key pair using the Strong Name tool (Sn.exe) from visual studio command prompt as following:
sn -k <file name>
                E.g.: sn -k Key.snk
Note: the above statement generates a key value and writes it into the file “Key.snk”. Key pair files usually have .snk extension.
Creating a Shared Assembly:

Step 1: generate a public key. Open VS command prompt, go into your folder and generate a public key as following:                <drive>:\<folder> sn -k key.snk

Step 2: develop a new project and associate the key file to it before compilation so that the assembly which is generated will be Strong Named.
To do this open a new project of type Class Library, name it as “SAssembly” and write the following code under the class Class1:

public string SayHello() {
   return "Hello from shared assembly 1.0.0.0";
}
To associate key file we have generated with the project, open project properties window, select Signing tab on LHS, which displays a CheckBox as “Sign the Assembly” select it, now in the ComboBox below select browse, select the key.snk file from its physical location which adds the file under solution explorer, then compile the project using “Build” option that will generate SAssembly.dll which is Strong Named.
Step 3: installing assembly into GAC by using the “Global Assembly Cache Tool”.
To install the assembly into open Visual Studio Command Prompt, go to the location where SAssembly.dll was present and write the following:
                <drive>:\<folder\SAssembly\SAssembly\bin\Debug> gacutil -i SAssembly.dll

Step 4: testing the Shared Assembly.
Open a new project of type Windows, name it as “TestSAssembly”, place a button on the form and set its text as “Call SayHello method of Class1 in SAssembly.dll 1.0.0.0”. Now add reference of SAssembly.dll from its physical location and write the following code under click of button:
                                                SAssembly.Class1 obj = new SAssembly.Class1();
MessageBox.Show(obj.SayHello());
Run the project, test it and verify under bin/debug folder of current project where we will not find any copy of SAssembly.dll as it is shared assembly.
Versioning Assemblies:
Every assembly is associated with a set of attributes that describes about general info of an assembly like Title, Company, Description, Version etc. These attributes will be under AssemblyInfo.cs file of each project. To view them expand properties node under the project in Solution Explorer where we find AssemblyInfo.cs file. We can change values of any attribute as per our requirements. In bottom of the file we find an attribute “AssemblyVersion” which is a combination of 4 values:
  • Major Version
  • Minor Version
  • Build Number
  • Revision
The default version of every assembly is 1.0.0.0; we can change the version no. of an assembly whenever we make modifications to the code under assembly.

Testing the process of changing version no of an assembly:
Open the SAssembly project we have developed earlier and add a new method under the class Class1 as following:
public string SayHello(string name) {
   return "Hello from shared assembly 1.0.1.0";
}
Now open “AssemblyInfo.cs” file and change the AssemblyVersion and AssemblyFileVersion attributes to 1.0.1.0, re-build the project and add the new version of SAssembly.dll also into GAC using the Gacutil Tool.
Note: GAC allows placing of multiple versions of an assembly in it and provides different applications using different versions of the assembly to execute correctly using their required version. Now open the GAC folder where we find 2 versions of SAssembly i.e. 1.0.0.0 and 1.0.1.0

Assemblies and Side-by-Side Execution:
                Side-by-side execution is the ability to store and execute multiple versions of an application or component on the same computer. Support for side-by-side storage and execution of different versions of the same assembly is an integral part of strong naming and is built into the infrastructure of the runtime. Because the strong-named assembly's version number is part of its identity, the runtime can store multiple versions of the same assembly in the global assembly cache and load those assemblies at run time. To test this open a new project of type Windows, name it as “TestSAssemblyNew”, place a button on the form and set its text as “Call SayHello method of Class1 in SAssembly.dll 1.0.1.0”. Now add reference of SAssembly 1.0.1.0 version from its physical location and write the following code under click of button:
                                                SAssembly.Class1 obj = new SAssembly.Class1();
MessageBox.Show(obj.SayHello(“Raju”));
                To check side by side execution of projects run the exe files of TestSAssembly and TestSAssemblyNew projects at the same time, where each project will use its required version of SAssembly and execute, as following:








Multi-Module Assemblies:
If you are programming with .Net framework, you will deal with Assemblies all the time. After all, assemblies are the building blocks of .Net framework. Assemblies can have single file, or can have multiple files. We typically refer an assembly with multiple files as Multi-Module Assembly, and each file as a module. The main advantage of multi-module assemblies is we can combine modules written in different languages into one single assembly.  
A multi-module assembly is divided into 2 parts like Main-Module and Sub-Modules where we can have only one main module and all the other are sub-modules. First we need to compile the sub-module files each individually by using their corresponding compilers, so that they will generate an output file with the extension as .netmodule and then we need to compile the main-module file by adding all the sub-modules we compiled to it, so that it generates and assembly file with an extension of either .exe or .dll.





Note: here any file or class can be chosen as main module and rest of the others will become sub-modules.

Developing a Multi-Module Assembly:
                Currently there is no tool can create the assembly from source code written in different languages. Those sources have to be compiled into modules by the corresponding compilers, and then a separate tool will merge them into a single assembly. To test this process first define two classes in 2 separate .net languages using notepad as following:
Imports System                                                                                                     using System;
Namespace MyNSP                                                                                              namespace MyNsp {
  Public Class VBTest                                                                                              public class CSTest {
    Public Function SayHello() As String                                                                 public string SayHello() {
      Return "Hello from Visual Basic Language"                                                     return “Hello from Visual CSharp Lang”;
    End Function                                                                                                         }
  End Class                                                                                                                }
End Namespace                                                                                                    }
Compiling Sub-Modules:
vbc /target:module <vb file name>
csc /target:module <cs file name>

Compiling Main-Module:
vbc [/target:library] /addmodule:<list of sub modules> <vb file name>
csc [/target:library] /addmodule:<list of sub modules> <cs file name>

Note: if /target:library is used it will generate a .dll assembly or else will generate a .exe assembly, but to generate a .exe assembly we need to define Main method under the main-module class.

Making VBTest as a Sub-Module:
drive:\folder> vbc /target:module VBTest.vb

Making CSTest as a Main-Module:
drive:\folder> csc /target:library /addmodule:VBTest.netmodule CSTest.cs
Consuming the multi-module assembly:
Open a new project of type windows and name it as TestMulti, place 2 buttons on the form and set the text as “Call SayHello() of CSTest” and “Call SayHello() of VBTest”. Now add reference of the CSTest.dll we have generated above from its physical location and write the following code under click of the buttons:

Under “Call SayHello() of CSTest” Button:
MyNSP.CSTest obj = new MyNSP.CSTest();      MessageBox.Show(obj.SayHello());

Under “Call SayHello() of VBTest” Button:
MyNSP.VBTest obj = new MyNSP.VBTest();     MessageBox.Show(obj.SayHello()); 
Globalization and Localization using Satellite Assemblies:
                In the past, the term localization often referred to a process that began after an application developer compiled the source files in the original language. Another team then began the process of reworking the source files for use in another language. The original language, for example, might be English, and the second language might be German. That approach, however, is prohibitively expensive and results in inconsistencies among versions. It has even caused some customers to purchase the original-language version instead of waiting months for the localized version. A more cost effective and functional model divides the process of developing world-ready applications into three distinct parts, globalization, localizability, and localization. The primary advantages of designing and implementing your application to be sensitive and appropriate to regional conventions, data in a variety of world languages, and alternate format are:
  • You can launch your application onto the market more rapidly. No additional development is necessary to localize an application once the initial version is complete.
  • You use resources more efficiently. Implementing world-readiness as part of the original development process requires fewer development and testing resources than if you add the support after the initial development work starts.
  • Your application is easier to maintain.

Globalization: it is the process of designing and developing a software product that functions in multiple cultures/locales. This process involves:
  • Identifying the culture/locale that must be supported
  • Designing features which support those cultures/locales
  • Writing code that functions equally well in any of the supported cultures/locales

In other words, globalization adds support for input, display, and output of a defined set of language scripts that relate to specific geographic areas. The most efficient way to globalize these functions is to use the concept of cultures/locales. A culture/locale is a set of rules and a set of data that are specific to a given language and geographic area. These rules and data include information on:
  • Date and time formatting
  • Numeric, currency, weight, and measure conventions
  • Sorting rules

Localizability: it is an intermediate process for verifying that a globalized application is ready for localization. In an ideal situation, this is only a quality assurance phase. If you designed and developed your application with an eye towards localization, this phase will primarily consist of localizability testing.
                Localizability is also the process of preparing an application for localization. An application prepared for localization has two conceptual blocks, a data block and a code block. The data block exclusively contains all the user-interface string resources. The code block exclusively contains only the application code applicable for all cultures/locales. In theory, you can develop a localized version of your application by changing only the data block. The code block for all cultures/locales should be the same. The combination of the data block with the code block produces a localized version of your application. The keys to successful world-ready software design and subsequent localization success is separation of the code block from the data block. Once localizability is complete, your application is ready for localization.

Localization: it is the process of adapting a globalized application, which you have already processed for localizability, to a particular culture/locale. The localization process refers to translating the application user interface (UI) or adapting graphics for a specific culture/locale. The localization process can also include translating any help content associated with the application.

Culture: the utmost basic entity in this scenario is Culture usually called as CultureInfo provides information about a specific culture. The information includes the names for the culture, the writing system, the calendar used, and formatting for dates and sort strings. The CultureInfo class renders culture-specific information, such as the associated language, sublanguage, country/region, calendar, and cultural conventions.
The CultureInfo class present under the System.Globalization specifies a unique name for each culture which is a combination of a two-letter lowercase culture code associated with a language and a two-letter uppercase subculture code associated with a country or region. Examples include ja-JP for Japanese (Japan), en-US for English (United States), fr-FR for French (France), hi-IN for Hindi (India) and te-In for Telugu (India) etc.
When object of this class is created by passing the culture name as a parameter will change the culture of our application, i.e. if we make an application in English culture, and create an object of CultureInfo class for French language, and automatically everything will start working in French.
                To develop culture neutral application, for each culture’s UI the text we want to see over the forms, we will have to define the translations explicitly and this information is known as resources, and they exist in the form of .resx files. These are XML files and to manage them there are classes listed under System.Resources namespace.
               
To develop an application for Globalization and Localization, open a new project of type windows, name the project as “MultiLang” and design the form as following:








Now add 3 resources files under the project from the “Add New Item” window naming them as “MyRes.en-US.resx”, “MyRes.hi-IN.resx” and “MyRes.te-IN.resx” and enter the text for Labels, Button and Checkbox separately for each language under the resources files as following:

Name                      Value (MyRes.en-US.resx)                  Value (MyRes.hi-IN.resx)                    Value (MyRes.te-IN.resx)
L1                            Sign in                                                    साइन इन करें                  సైన్ ఇన్ చేయండి
L2                            Username                                              उपयोगकर्ता नाम                వినియోగదారు పేరు
L3                            Password                                               पासवर्ड                      పాస్వర్డ్
B1                           Sign in                                                    साइन इन करें                  సైన్ ఇన్ చేయండి
CB1                         Stay signed in                                        साइन इन रहें                  సైన్ ఇన్ చేసి ఉండండి
Note: while naming the resource files we need to adopt a pattern that is <base name>.<culture name>, where base name is a common name for all the resource files (MyRes in our case). These resource files once after compilation of the project will be converted into assemblies and we call those assemblies as satellite assemblies.

using System.Reflection; using System.Resources; using System.Globalization;
Declarations: CultureInfo ci; ResourceManager rm;
Under Form Load: rm = new ResourceManager("MultiLang.MyRes", Assembly.GetExecutingAssembly());
private void GetValues() {
  label1.Text = rm.GetString("L1", ci); label2.Text = rm.GetString("L2", ci); label3.Text = rm.GetString("L3", ci);
  button1.Text = rm.GetString("B1", ci); checkBox1.Text = rm.GetString("CB1", ci);
}
Under English Link Label: ci = new CultureInfo("en-US"); GetValues();
Under Hindi Link Label: ci = new CultureInfo("hi-IN"); GetValues();
Under Telugu Link Label: ci = new CultureInfo("te-IN"); GetValues();
                ResourceManager class under the System.Resources namespace is used for accessing the culture specific information at runtime by reading the values from resource files.
System.Resources.ResourceManager(string baseName, Assembly assembly)
baseName is the root name of the resource files without its extension but including the fully qualified namespace name.
                Assembly is the main assembly for the resource, to get that use the method GetExecutingAssembly() under Assembly class of System.Reflection namespace.
Note: after compilation and execution of the project, now go and verify under the bin\Debug folder of the current project where we find a separate folder created for each resource file, with the culture name and in that folder we find the satellite assemblies that got created.
In general, an assembly consists of four elements:
  • The assembly manifest, which contains assembly metadata.
  • Type metadata.
  • Microsoft intermediate language (MSIL) code or CIL Code that implements the types.
  • A set of resources.             



Assembly Manifest: contains information about the attributes that are associated with an assembly like Assembly Name, Version Number, Culture, Strong Name Information, List of files in the assembly etc.

Type Metadata: describes every type and member defined in your code in a language-neutral manner. Metadata stores the following information:
  • Description of the assembly.
§  Identity (name, version, culture, public key).
§  Other assemblies that this assembly depends on.
§  Security permissions needed to run.
  • Description of types.
§  Name, visibility, base class, and interfaces implemented.
§  Members (methods, fields, properties, events, nested types).
Metadata provides the following major benefits:
  1. Self-describing files, common language runtime modules and assemblies are self-describing.
  2. Language interoperability, metadata provides all the information required about compiled code for you to inherit a class from a file written in a different language.

MSIL Code or CIL Code: during compilation of any .net programming languages, the source code is translated into CIL code rather than platform or processor-specific code. CIL is a CPU and platform-independent instruction set that can be executed in any environment supporting the Common Language Infrastructure, such as the .NET runtime on Windows, or the cross-platform Mono runtime.
Compilation and Execution Process of a CSharp Project:





Setup and Deployment
The final stage in the development of an application is deploying the project on client machines, which should be managed carefully. To organize the things in a proper fashion and install required files on the required folders we were provided with Setup and Deployment project under .net. This has to be added under the same solution where we developed our application.

Note: Before preparing Setup for an application in the top of the Visual Studio we find a ComboBox showing the options Debug and Release, default will be Debug change it as Release and then right click on the solution node in solution explorer and Select Build, which will compile all the Projects and re-generates the assemblies again but not in the bin\Debug folder but in bin\Release folder and these assemblies will be used in the setup process.

To add Setup and Deployment Project, open “Add New Project” window and in LHS panel expand the option "Other Project Types" and also expand the “Setup and Deployment” option and select Visual Studio Installer, now in the RHS panel choose "Setup Project" and give a name to the project.






When Setup Project is selected and opened it shows the options as following:
v  File System on Target Machine
Ø  Application Folder
Ø  User's Desktop
Ø  User's Programs Menu


















No comments:

Post a Comment

FAQ--(3- Tier Project)

BACK   https://meeraacademy.com/3-tier-architecture-example-in-asp-net-c/ 1. Presentation Layer (UI – User Interface Layer) 2. Busine...