Search This Blog

Friday, May 25, 2012

Six important .NET concepts: Stack, heap, value types, reference types, boxing, and unboxing

What goes inside when you declare a variable?

When you declare a variable in a .NET application, it allocates some chunk of memory in the RAM. This memory has three things: the name of the variable, the data type of the variable, and the value of the variable.
That was a simple explanation of what happens in the memory, but depending on the data type, your variable is allocated that type of memory. There are two types of memory allocation: stack memory and heap memory. In the coming sections, we will try to understand these two types of memory in more detail.

Stack and heap

In order to understand stack and heap, let’s understand what actually happens in the below code internally.
public void Method1()
{
    // Line 1
    int i=4;

    // Line 2
    int y=2;

    //Line 3
    class1 cls1 = new class1();
}
It’s a three line code, let’s understand line by line how things execute internally.
  • Line 1: When this line is executed, the compiler allocates a small amount of memory in the stack. The stack is responsible for keeping track of the running memory needed in your application.
  • Line 2: Now the execution moves to the next step. As the name says stack, it stacks this memory allocation on top of the first memory allocation. You can think about stack as a series of compartments or boxes put on top of each other.
  • Memory allocation and de-allocation is done using LIFO (Last In First Out) logic. In other words memory is allocated and de-allocated at only one end of the memory, i.e., top of the stack.
  • Line 3: In line 3, we have created an object. When this line is executed it creates a pointer on the stack and the actual object is stored in a different type of memory location called ‘Heap’. ‘Heap’ does not track running memory, it’s just a pile of objects which can be reached at any moment of time. Heap is used for dynamic memory allocation.
One more important point to note here is reference pointers are allocated on stack. The statement, Class1 cls1; does not allocate memory for an instance of Class1, it only allocates a stack variable cls1 (and sets it to null). The time it hits the new keyword, it allocates on "heap".
Exiting the method (the fun): Now finally the execution control starts exiting the method. When it passes the end control, it clears all the memory variables which are assigned on stack. In other words all variables which are related to int data type are de-allocated in ‘LIFO’ fashion from the stack.
The big catch – It did not de-allocate the heap memory. This memory will be later de-allocated by the garbage collector.

Now many of our developer friends must be wondering why two types of memory, can’t we just allocate everything on just one memory type and we are done?
If you look closely, primitive data types are not complex, they hold single values like ‘int i = 0’. Object data types are complex, they reference other objects or other primitive data types. In other words, they hold reference to other multiple values and each one of them must be stored in memory. Object types need dynamic memory while primitive ones needs static type memory. If the requirement is of dynamic memory, it’s allocated on the heap or else it goes on a stack.

Value types and reference types

Now that we have understood the concept of Stack and Heap, it’s time to understand the concept of value types and reference types. Value types are types which hold both data and memory on the same location. A reference type has a pointer which points to the memory location.
Below is a simple integer data type with name i whose value is assigned to another integer data type with name j. Both these memory values are allocated on the stack.
When we assign the int value to the other int value, it creates a completely different copy. In other words, if you change either of them, the other does not change. These kinds of data types are called as ‘Value types’.

When we create an object and when we assign an object to another object, they both point to the same memory location as shown in the below code snippet. So when we assign obj to obj1, they both point to the same memory location.
In other words if we change one of them, the other object is also affected; this is termed as ‘Reference types’.

So which data types are ref types and which are value types?

In .NET depending on the data type, the variable is either assigned on the stack or on the heap. ‘String’ and ‘Objects’ are reference types, and any other .NET primitive data types are assigned on the stack. The figure below explains the same in a more detail manner.

Boxing and unboxing

Wow, you have given so much knowledge, so what’s the use of it in actual programming? One of the biggest implications is to understand the performance hit which is incurred due to data moving from stack to heap and vice versa.
Consider the below code snippet. When we move a value type to reference type, data is moved from the stack to the heap. When we move a reference type to a value type, the data is moved from the heap to the stack.
This movement of data from the heap to stack and vice-versa creates a performance hit.
When the data moves from value types to reference types, it is termed ‘Boxing’ and the reverse is termed ‘UnBoxing’.

If you compile the above code and see the same in ILDASM, you can see in the IL code how ‘boxing’ and ‘unboxing’ looks. The figure below demonstrates the same.

Performance implication of boxing and unboxing

In order to see how the performance is impacted, we ran the below two functions 10,000 times. One function has boxing and the other function is simple. We used a stop watch object to monitor the time taken.
The boxing function was executed in 3542 ms while without boxing, the code was executed in 2477 ms. In other words try to avoid boxing and unboxing. In a project where you need boxing and unboxing, use it when it’s absolutely necessary.
With this article, sample code is attached which demonstrates this performance implication.

Currently I have not included source code for unboxing but the same holds true for it. You can write code and experiment it using the stopwatch class.

Saturday, January 1, 2011

C# code to insert, delete and update in generic list

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

namespace GenericList
{
    public partial class frmContact : Form
    {
        List contacts;
        public frmContact()
        {
            InitializeComponent();
        }

        # region Insert Operation
        private void btnInsert_Click(object sender, EventArgs e)
        {
            Customer cnt = new Customer();
            cnt.Name = txtName.Text.Trim();
            cnt.Mobile = txtMobile.Text.Trim();
            contacts.Add(cnt);
            CurrencyManager cm = (CurrencyManager)this.BindingContext[contacts];
            cm.Refresh();
            dgcontacts.DataSource = contacts;
        }
        # endregion

        #region Update Operation

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            List select = contacts.FindAll(new Predicate(HasName));
            if (select.Count > 0) // record found
            {
                foreach (Customer cnt in select)
                {
                    cnt.Name = txtName.Text.Trim();
                    cnt.Mobile = txtMobile.Text.Trim();
                }
                CurrencyManager cm = (CurrencyManager)this.BindingContext[contacts];
                cm.Refresh();
                dgcontacts.DataSource = contacts;

            }
            else
            {
                MessageBox.Show("No records found");
            }
        }

        # endregion

        //This function will check for the person name
        bool HasName(Customer c)
        {
            return (c.Name == txtName.Text);
        }

        # region Delete Operation

        private void btnDelete_Click(object sender, EventArgs e)
        {
            List select = contacts.FindAll(new Predicate(HasName));
            if (select.Count > 0) // record found
            {
                foreach (Customer cnt in select)
                {
                    contacts.Remove(cnt);
                }
                CurrencyManager cm = (CurrencyManager)this.BindingContext[contacts];
                cm.Refresh();
                dgcontacts.DataSource = contacts;

            }
            else
            {
                MessageBox.Show("No records found");
            }

        }

        # endregion

        private void frmContact_Load(object sender, EventArgs e)
        {
            contacts = new List();
        }
    }

    //Customer Class
    public class Customer
    {
        private string _Name;
        private string _Mobile;

        public string Name
        {
            get { return _Name; }
            set { _Name = value; }
        }

        public string Mobile
        {
            get { return _Mobile; }
            set { _Mobile = value; }
        }
    }
}

Tuesday, December 21, 2010

Differences between different datatypes in SQL Server

Differences between varchar and nvarchar in SQL Server

VARCHAR is an abbreviation for variable-length character string. It's a string of text characters that can be as large as the page size for the database table holding the column in question. The size for a table page is 8,196 bytes, and no one row in a table can be more than 8,060 characters. This in turn limits the maximum size of a VARCHAR to 8,000 bytes.

The "N" in NVARCHAR means uNicode. Essentially, NVARCHAR is nothing more than a VARCHAR that supports two-byte characters. The most common use for this sort of thing is to store character data that is a mixture of English and non-English symbols — in my case, English and Japanese.


Differences between char and varchar in SQL Server
char is used for fixed length memory storage whereas varchar is used for variable lenght memory storage.
Fox Example if we have char(10) then we can store 10 bit value in it but if we store only 6 bit value in it then rest of the 4 bit space is goes wasted. this limitation is overcome by varchar.
In varchar if we use less space than define space the rest of space is not wasted.

Differences between nchar and nvarchar in SQL Server

NCHAR and NVARCHAR data types are both Unicode character data types with a maximum length of 4,000 characters. The main difference between these 2 data types is that an NCHAR data type is fixed-length while an NVARCHAR is variable-length. If the number of characters entered in an NCHAR data type column is less than the specified column length, spaces are appended to it to fill up the whole length.

Another difference is in the storage size wherein the storage size for NCHAR is two times n bytes while for NVARCHAR is two times the number of characters entered (in bytes).

Differences between varchar and nvarchar in SQL Server 

VARCHAR and NVARCHAR data types are both character data types that are variable-length. Below is the summary of the differences between these 2 data types:

VARCHAR Character Data Type:- Non-Unicode Data
NVARCHAR Character Data Type:- Unicode Data

VARCHAR Maximum Length:- 8,000
NVARCHAR Maximum Length:- 4,000

VARCHAR Character Size:- 1 byte
NVARCHAR Character Size:- 2 byte

VARCHAR Storage Size:- Actual Length (in bytes)
NVARCHAR Storage Size:- 2 times Actual Length (in bytes)

You would use NVARCHAR data type for columns that store characters from more than one character set or when you will be using characters that require 2-byte characters, which are basically the Unicode characters such as the Japanese Kanji or Korean Hangul characters.

Wednesday, December 15, 2010

Disadvantages of LINQ over Stored procedures

Disadvantages of LINQ over stored procedures:
  • LINQ needs to process the complete query, which might have a performance impact in case of complex queries against stored procedures which only need serialize sproc-name and argument data over the network.
  • LINQ is generic, whereas stored procedures etc can take full advantage of the complete database features.
  • If there has been a change, the assembly needs to be recompiled and redeployed whereas stored procedures are much simpler to update.
  • It’s much easier to restrict access to tables in database using stored procedures and ACL’s than through LINQ.

Saturday, November 27, 2010

Concept of Early Binding and Late Bindind in C#

Before discussing about the differences, let's know what is meant by Early and Late Binding.

Early Binding:
The name itself describes that compiler knows about what kind of object it is, what are all the methods and properties it contains. As soon as you declared the object, .NET Intellisense will populate its methods and properties on click of the dot button.

 
Common Examples:

 
ComboBox cboItems;
ListBox lstItems;

 
In the above examples, if we type the cboItem and place a dot followed by, it will automatically populate all the methods, events and properties of a combo box, because compiler already know it's an combobox.

 
Late Binding:
The name itself describes that compiler does not know what kind of object it is, what are all the methods and properties it contains. You have to declare it as an object, later you need get the type of the object, methods that are stored in it. Everything will be known at the run time.

 
Common Examples:

 
Object objItems;
objItems = CreateObject("DLL or Assembly name");

 
Here during the compile time, type of objItems is not determined. We are creating an object of a dll and assigning it to the objItems, so everything is determined at the run time.

 
Early Binding vs. Late Binding
  • Application will run faster in Early binding, since no boxing or unboxing are done here.
  • Easier to write the code in Early binding, since the intellisense will be automatically populated
  • Minimal Errors in Early binding, since the syntax is checked during the compile time itself.
  • Late binding would support in all kind of versions, since everything is decided at the run time.
  • Minimal Impact of code in future enhancements, if Late Binding is used. 
Performance will be code in early binding.

Both have merits and demerits, it's the developer decision to choose the appropriate binding based on the scenario.

 

Friday, October 29, 2010

Getting the Index of a dataGridView Row in the MouseMove Event Window Application

private void dataGridView1_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
  {
            if (e.RowIndex >= 0)
            {
                if (!((DataGridViewRow)(dataGridView1.Rows[e.RowIndex])).Selected)
                {
                    dataGridView1.ClearSelection();
                    ((DataGridViewRow)dataGridView1.Rows[e.RowIndex]).Selected = true;
                    if (dataGridView1.SelectedRows.Count > 0)
                    {
                       DataGridViewRow row = (DataGridViewRow)dataGridView1.Rows[e.RowIndex];
                        TextBox1.Text = e.RowIndex.ToString();

// return row index of dataGridView On CellMouseMove Event and Display RowIndex in TextBox1.                    }
                }
            }
        }

Tuesday, October 19, 2010

Sending Email using C# and ASP.Net

Most often, we will have requirements to send email from our asp.net applications. This article will help us understand some of the available techniques we can use to send email from asp.net applications. With the introduction of .Netframework 2.0, the classes for sending email are packed in System.Net.Mail namespace as opposed to System.Web.Mail namespace in 1.x framework. Moving forward we will see,

Ø       Sending a Simple Mail
Ø       Sending Mail with Attachment
Ø       Sending Mail with HTML body
Ø       Sending Email with Embedded Image in the Message Body
Ø       Sending Email with Gmail SMTP Server from ASP.Net

Sending a Simple Mail
MailMessage mail = new MailMessage();
mail.To.Add("to@gmail.com");
mail.From = new MailAddress("from@gmail.com");
mail.Subject = "Test Email";
string Body = "Welcome to Mysite.Com!!";
mail.Body = Body;
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com" ;
smtp.Send(mail);

Sending Mail with Attachment
We can also send email with attachments. The below code will help you to achieve it.

MailMessage mail = new MailMessage();
mail.To.Add("to@gmail.com");
mail.From = new MailAddress("From@gmail.com");
mail.Subject = "Test Email";
string Body = "Welcome to Mysite.Com!!";
mail.Body = Body;
mail.Attachments.Add(new Attachment(@"F:\Articles\Email in ASP.Net 2.0\SendEmail\mail.png"));
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com" ;
smtp.Send(mail);

Sending Mail with HTML Body
Sometimes, we will have requirements to send email as a HTML body. The below code will help you to achieve the same.
MailMessage mail = new MailMessage();
mail.To.Add("to@gmail.com");
mail.From = new MailAddress("From@gmail.com");
mail.Subject = "Test Email";
string Body = "Welcome to Mysite.com!!";
mail.Body = Body;
mail.IsBodyHtml = true;
SmtpClient smtp = new SmtpClient();
smtp.Host ="smtp.gmail.com" ;
smtp.Send(mail);


Sending Email with Gmail SMTP Server from ASP.Net
To send email using gmail SMTP server you will require a valid gmail userid and password. If you didn’t specify a valid gmail userid and password then you will get the following error.

The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required.

The below code can be used to send email using gmail SMTP server, smtp.gmail.com.

MailMessage mail = new MailMessage();
mail.To.Add("to@gmail.com");
mail.From = new MailAddress("from@gmail.com");
mail.Subject = "Test Email";
string Body = "Welcome to Mysite.com!!";
mail.Body = Body;
mail.IsBodyHtml = true;
SmtpClient smtp = new SmtpClient();
smtp.Host ="smtp.gmail.com" ;
smtp.Credentials = new System.Net.NetworkCredential("mail@gmail.com","password");
smtp.EnableSsl = true;   
smtp.Send(mail);

Tuesday, September 14, 2010

Store Procedure

In this article, we will examine what a stored procedure is and how to call one from SQL Server database.

Outline:
  • Why Use Stored Procedures?
  • Creating a Stored Procedure
  • Calling a Stored Procedure
  • Specifying Parameters
  • Data Retrieval
  • Inserting Data Using Parameters


Why Use Stored Procedures?

There are several advantages of using stored procedures instead of standard SQL. First, stored procedures allow a lot more flexibility offering capabilities such as conditional logic. Second, because stored procedures are stored within the DBMS, bandwidth and execution time are reduced. This is because a single stored procedure can execute a complex set of SQL statements. Third, SQL Server pre-compiles stored procedures such that they execute optimally. Fourth, client developers are abstracted from complex designs. They would simply need to know the stored procedure's name and the type of data it returns.

Creating a Stored Procedure

Enterprise Manager provides an easy way to create stored procedures. First, select the database to create the stored procedure on. Expand the database node, right-click on "Stored Procedures" and select "New Stored Procedure...". You should see the following:
CREATE PROCEDURE [OWNER].[PROCEDURE NAME] AS
Substitute OWNER with "dbo" (database owner) and PROCEDURE NAME with the name of the procedure. For example:
CREATE PROCEDURE [dbo].[GetProducts] AS
So far, we are telling SQL Server to create a new stored procedure with the name GetProducts. We specify the body of the procedure after the AS clause:
CREATE PROCEDURE [dbo].[GetProducts] AS
SELECT ProductID, ProductName FROM Products
Click on the Check Syntax button in order to confirm that the stored procedure is syntactically correct. Please note that the GetProducts example above will work on the Northwind sample database that comes with SQL Server. Modify it as necessary to suite the database you are using.

Now that we have created a stored procedure, we will examine how to call it from within a C# application.

Calling a Stored Procedure

A very nice aspect of ADO.NET is that it allows the developer to call a stored procedure in almost the exact same way as a standard SQL statement.

1. Create a new C# Windows Application project.

2. From the Toolbox, drag and drop a DataGrid onto the Form. Resize it as necessary.

3. Double-click on the Form to generate the Form_Load event handler. Before entering any code, add "using System.Data.SqlClient" at the top of the file.

Enter the following code:
private void Form1_Load(object sender, System.EventArgs e)
{
    SqlConnection conn = new SqlConnection("Data 
Source=localhost;Database=Northwind;Integrated Security=SSPI");
    SqlCommand command = new SqlCommand("GetProducts", conn);
    SqlDataAdapter adapter = new SqlDataAdapter(command);
    DataSet ds = new DataSet();
    adapter.Fill(ds, "Products");
    this.dataGrid1.DataSource = ds;
    this.dataGrid1.DataMember = "Products";
}
As you can see, calling a stored procedure in this example is exactly like how you would use SQL statements, only that instead of specifying the SQL statement, you specify the name of the stored procedure. Aside from that, you can treat it exactly the same as you would an ordinary SQL statement call with all the advantages of a stored procedure.

Specifying Parameters

Most of the time, especially when using non-queries, values must be supplied to the stored procedure at runtime. For instance, a @CategoryID parameter can be added to our GetProducts procedure in order to specify to retrieve only products of a certain category. In SQL Server, parameters are specified after the procedure name and before the AS clause.
CREATE PROCEDURE [dbo].[GetProducts] (@CategoryID int) AS
SELECT ProductID, ProductName FROM Products WHERE CategoryID = @CategoryID
Parameters are enclosed within parenthesis with the parameter name first followed by the data type. If more than one parameter is accepted, they are separated by commas:
CREATE PROCEDURE [dbo].[SomeProcedure] (
    @Param1 int,
    @Param2 varchar(50),
    @Param3 varchar(50)
) AS
...
For our GetProducts example, if @CategoryID was supplied with the value 1, the query would equate to:
SELECT ProductID, ProductName FROM Products WHERE CategoryID = 1
Which would select all the products that belong to CategoryID 1 or the Beverages category. To call the stored procedure, use Query Analyzer to execute:
exec GetProducts X
where X is the @CategoryID parameter passed to the stored procedure. To call the stored procedure from within a C# application using 1 as the @CategoryID parameter value, use the following code:
SqlConnection conn = new SqlConnection("Data 
Source=localhost;Database=Northwind;Integrated Security=SSPI");
SqlCommand command = new SqlCommand("GetProducts", conn);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("@CategoryID", SqlDbType.Int).Value = 1;
SqlDataAdapter adapter = new SqlDataAdapter(command);
DataSet ds = new DataSet();
adapter.Fill(ds, "Products");
this.dataGrid1.DataSource = ds;
this.dataGrid1.DataMember = "Products";
Note that you must now specify the CommandType property of the SqlCommand object. The reason we did not do this in the first example was that it is not required if the stored procedure does not accept parameters. Of course, specifying the CommandType property even if it is not needed may improve readability. The next line actually combines two lines in one:
command.Parameters.Add("@CategoryID", SqlDbType.Int);
command.Parameters["@CategoryID"].Value = 1;
The first line of this segment specifies that the command object (which calls the GetProducts stored procedure) accepts a parameter named @CategoryID which is of type SqlDbType.Int. The type must be the same as the data type specified by the stored procedure. The second line of this code segment gives the parameter the value 1. For simplicity, especially when using more than one parameter, I prefer to combine to two lines into a single line:
command.Parameters.Add("@CategoryID", SqlDbType.Int).Value = 1;
The rest of the code is the same as in the previous example without parameters. As illustrated in the previous examples, ADO.NET takes a lot of pain out of database programming. Calling a stored procedure uses virtually the same code as using standard SQL and specifying parameters is a painless process.

Data Retrieval

Data Retrieval with stored procedures is the same (surprise!) as if using standard SQL. You can wrap a DataAdapter around the Command object or you can use a DataReader to fetch the data one row at a time. The previous examples have already illustrated how to use a DataAdapter and fill a DataSet. The following example shows usage of the DataReader:
SqlConnection conn = new SqlConnection("Data 
Source=localhost;Database=Northwind;Integrated Security=SSPI");
SqlCommand command = new SqlCommand("GetProducts", conn);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("@CategoryID", SqlDbType.Int).Value = 1;
conn.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
    Console.WriteLine(reader["ProductName"]);
}
conn.Close();
Again, using either a DataAdapter or a DataReader against a query from a stored procedure is the same as specifying the SQL from within the code.

Inserting Data Using Parameters

Using other SQL statements such as INSERT, UPDATE or DELETE follow the same procedure. First, create a stored procedure that may or may not accept parameters, and then call the stored procedure from within the code supply the necessary values if parameters are needed. The following example illustrates how to insert a new user in a users table that has a username and password field.
CREATE PROCEDURE [dbo].[InsertUser] (
    @Username varchar(50),
    @Password varchar(50)
) AS
INSERT INTO Users VALUES(@Username, @Password)
string username = ... // get username from user
string password = ... // get password from user
SqlConnection conn = new SqlConnection("Data 
Source=localhost;Database=MyDB;Integrated Security=SSPI");
SqlCommand command = new SqlCommand("InsertUser", conn);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("@Username", SqlDbType.VarChar).Value = username;
command.Parameters.Add("@Password", SqlDbType.VarChar).Value = password;
conn.Open();
int rows = command.ExecuteNonQuery();
conn.Close();
First, we retrieve the username and password information from the user. This information may be entered onto a form, through a message dialog or through some other method. The point is, the user specifies the username and password and the applicaton inserts the data into the database. Also notice that we called the ExecuteNonQuery() method of the Connection object. We call this method to indicate that the stored procedure does not return results for a query but rather an integer indicating how many rows were affected by the executed statement. ExecuteNonQuery() is used for DML statements such as INSERT, UPDATE and DELETE. Note that we can test the value of rows to check if the stored procedure inserted the data successfully.
if (rows == 1)
{
    MessageBox.Show("Create new user SUCCESS!");
}
else
{
    MessageBox.Show("Create new user FAILED!");
}
We check the value of rows to see if it is equal to one. Since our stored procedure only did one insert operation and if it is successful, the ExecuteNonQuery() method should return 1 to indicate the one row that was inserted. For other SQL statements, especially UPDATE and DELETE statements that affect more than one row, the stored procedure will return the number of rows affected by the statement.
DELETE FROM Products WHERE ProductID > 50
This will delete all products whose product ID is greater than 50 and will return the number of rows deleted.

Conclusion

Stored procedures offer developers a lot of flexibility with many features not available using standard SQL. ADO.NET allows us to use stored procedures in our applications seamlessly. The combination of these two allows us to create very powerful appliations rapidly.

Thursday, September 9, 2010

Passing Data Between Forms

Introduction

Some of you would have faced a scenario where you wanted to pass data from one form to another in WinForms. Honestly, I too had a similar problem (that’s why I am writing this article!).
There are so many methods (How many? I don't know) to pass data between forms in Windows application. In this article, let me take four important (easiest) ways of accomplishing this:
  1. Using constructor
  2. Using objects
  3. Using properties
  4. Using delegates
Let us see all the above methods in detail in the following sections.
For data to be passed between forms using any of the above methods, we need two forms and some controls. Let us start by following the steps given below.

Step 1

Create a new project and select Windows application. This will create a default form as “Form1”. We can use this form for sending data.

Step 2

Add a textbox and a button to the form.

Step 3

Add another Windows Form for receiving the data and to display it. Right click the project and select Add->Add Windows Form. Enter a name or use the default name “Form2.cs” and click ok button.

Step 4

Add a label to the second form to display the text from form1.

The Constructor Approach

This could be the easiest method of all. A method is invoked whenever you instantiate an object. This method is called a constructor. Code a constructor for form2 class with one string parameter. In the constructor, assign the text to the label’s text property. Instantiate form2 class in form1’s button click event handler using the constructor with one string parameter and pass the textbox’s text to the constructor.
Follow the steps given below:

Step 1

Code a constructor for form2 class as below:

public Form2(string strTextBox)
{
  InitializeComponent(); 
  label1.Text=strTextBox;
}

Step 2

Instantiate form2 class in form1’s button click event handler as below:

private void button1_Click(object sender, System.EventArgs e)
{
    Form2 frm=new Form2(textBox1.Text);
    frm.Show();
}

The Object Approach

Objects are reference types, and are created on the heap, using the keyword new. Here we are going to pass data using objects. The approach is simple; in form2 we are going to instantiate form1 class.
Then instantiate form2 in the button click event handler of form1. After this we are going to pass form1 object to the form2 using form2’s form1 object. The last step is to invoke the form2 window by calling the form2’s show method.
Follow the below steps:

Step 1

Change the access modifier for textbox in form1 to public:

public class Form1 : System.Windows.Forms.Form
{  
 public System.Windows.Forms.TextBox textBox1;

Step 2

In the button click event-handler, add the following code:

private void btnSend_Click(object sender, System.EventArgs e)
{
    Form2 frm= new Form2();
    frm.frm1=this;
    frm.Show();
}

Step 3

In form2.cs, instantiate form1 class:

public class Form2 : System.Windows.Forms.Form
{
     private System.Windows.Forms.Label label1;
     public Form1 frm1;

Step 4

In Form2’s Load method, type cast the object (frm1) of form1 to Form1 and access form1’s textbox and assign its text to label’s text.

private void Form2_Load(object sender, System.EventArgs e)
{
    label1.Text=((Form1)frm1).textBox1.Text;
}

The Properties Approach

Properties allow clients to access class state as if they were accessing member fields directly, while actually implementing that access through a class method. In this method, we are going to add one property to each form. In form1 we are going to use one property for retrieving value from the textbox and in form2, one property to set the label’s text property. Then, in form1’s button click event handler, we are going to instantiate form2 and use the form2’s property to set the label’s text.
Follow the below steps:

Step 1

Add a property in form1 to retrieve value from textbox:

public string _textBox1
{
    get{return textBox1.Text;}
}

Step 2

Add a property in form2 to set the labels’ text:

public string _textBox
{
   set{label1.Text=value;}
}

Step 3

In form1’s button click event handler, add the following code:

private void button1_Click(object sender, System.EventArgs e)
{
     Form2 frm=new Form2();
     frm._textBox=_textBox1;
     frm.Show();
}

The Delegates Approach

Technically, a delegate is a reference type used to encapsulate a method with a specific signature and return type. You can encapsulate any matching method in that delegate. Here we are going to create a delegate with some signature and assign a function to the delegate to assign the text from textbox to label.
Follow the below steps:

Step 1

Add a delegate signature to form1 as below:

public delegate void delPassData(TextBox text);

Step 2

In form1’s button click event handler, instantiate form2 class and delegate. Assign a function in form2 to the delegate and call the delegate as below:

private void btnSend_Click(object sender, System.EventArgs e)
{
    Form2 frm= new Form2();
    delPassData del=new delPassData(frm.funData);
    del(this.textBox1);
    frm.Show();
}

Step 3

In form2, add a function to which the delegate should point to. This function will assign textbox’s text to the label:

public void funData(TextBox txtForm1)
{
    label1.Text = txtForm1.Text;
}

Friday, September 3, 2010

C# to give download link in gridview control

Source code fot gridview:-

   1:  <asp:GridView ID="grdsearch" runat="server" AutoGenerateColumns="False">
   2:                             
   3:<Columns>
   4: <asp:BoundField HeaderText="Full Name" DataField="FullName"/>
   5: <asp:BoundField HeaderText="Email ID" DataField="Email"/>
   6: <asp:BoundField HeaderText="Gender" DataField="Sex"/>
   7: <asp:BoundField HeaderText="Education" DataField="Education"/>
   8: <asp:BoundField HeaderText="Skills" DataField="Skillsetdetails"/>
   9: <asp:BoundField HeaderText="Total Experience" DataField="Totalexperience"/>
  10: <asp:BoundField HeaderText="Relvent Experience" DataField="Relventexperience"/>
  11: <asp:BoundField HeaderText="Address" DataField="Address"/>
  12: <asp:BoundField HeaderText="Previous Company Detail" DataField="Previousemployerdetail"/>
  13: <asp:BoundField HeaderText="Mobile Number" DataField="Mobileno"/>
  14: <asp:BoundField HeaderText="Availability" DataField="Availability"/>
  15: <asp:BoundField HeaderText="Currentctc" DataField="Currentctc"/>
  16: <asp:BoundField HeaderText="Expectedctc" DataField="Expectedctc"/>
  17: <asp:BoundField HeaderText="Preferred Location" DataField="StateName"/>
  18: <asp:BoundField HeaderText="Resume Name" DataField="ResumeName"/>
  19: <asp:TemplateField>
  20:  <ItemTemplate>
  21: <asp:LinkButton ID="LinkButton1" runat="server" Text="Resume Download" 
    CommandArgument='<%#Eval("Attachment")%>' OnCommand="btnDownload_Click">
  22:   
  23: asp:LinkButton>
  24:     ItemTemplate>
  25: asp:TemplateField>
  26:                  
  27:  Columns>
  28:  asp:GridView>

C# code to make file download on linkbutton click:-

 protected void btnDownload_Click(object sender, System.Web.UI.WebControls.CommandEventArgs e)
        {
            //Response.Write(e.CommandArgument.ToString());
            //Response.Write(e.CommandName.ToString()  );

            string queryString = e.CommandArgument.ToString();
            Response.Redirect(queryString);

        }

Monday, August 30, 2010

Deleting Multiple Rows in a GridView

If you have used Hotmail or any other similar email client, you might have observed that  we have the option of selecting multiple rows (using the checkbox provided) and perform a set of operations on them. In this article, we will replicate this scenario for a gridview. A gridview allows us to delete only a single row at a time. We will extend this functionality to select multiple rows and delete all of the selected rows in a single stroke. In this article, I assume that you are aware of creating asp.net web applications and have worked with gridview.
The sample makes use of the Northwind database. We will be pulling data from the Employee table. For this sample to work, drop all the Foreign Key relationships on the Employee Table. To do so, in Sql Server Management Studio, browse to the Northwind database and open the Employee table in design view. Right click in the Table designer on the right hand side and choose ‘Relationships’. Select all the relationships like FK_Orders_Employees,  FK_EmployeeTerritories_Employees etc and delete them. This step is necessary as we will get a constraint violation exception if we do not do so.
Once we are through with the task of removing the relationships in the Employee table, let us explore the steps to create a gridview with functionality to delete multiple rows at a time.
Perform the following steps :
Step 1: Create an .aspx page and add a GridView and a SqlDataSource control to it.
Step 2: Configure the connection of SqlDataSource to point to the Northwind database.  Create queries for the Select and Delete commands. The resultant code will look similar as given below :
<asp:SqlDataSource ID="SqlDataSource1" Runat="server"
    SelectCommand="SELECT EmployeeID, LastName, City FROM Employees"
    DeleteCommand="DELETE FROM Employees WHERE [EmployeeID] = @EmployeeID"
    ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" >
       <DeleteParameters>
           <asp:Parameter Name="EmployeeID" />
       DeleteParameters>
asp:SqlDataSource>                                   
Step 3: Once the SqlDataSource has been configured, bind the gridview with this data source.
Step 4: To create a checkbox in each row, follow these steps:
1.    Create a TemplateField inside the <Columns> to add custom content to each column.
2.    Inside the TemplateField, create an ItemTemplate with a CheckBox added to it.
<asp:TemplateField>
       <ItemTemplate>
             <asp:CheckBox ID="chkRows" runat="server"/>
      ItemTemplate>
 asp:TemplateField>
This will add a checkbox to each row in the grid.
Step 5: Add a button control, and rename it to btnMultipleRowDelete.
The resultant markup in the design view will look similar to the code below :
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="EmployeeID" DataSourceID="SqlDataSource1">
  
   <Columns>
      <asp:TemplateField>
          <ItemTemplate>
            <asp:CheckBox ID="cbRows" runat="server"/>
          ItemTemplate>
       asp:TemplateField>
 
<asp:BoundField DataField="EmployeeID" HeaderText="EmployeeID" InsertVisible="False" ReadOnly="True" SortExpression="EmployeeID" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
   Columns>
asp:GridView>
 
<asp:SqlDataSource ID="SqlDataSource1" Runat="server"
SelectCommand="SELECT EmployeeID, LastName, City FROM Employees"
DeleteCommand="DELETE FROM Employees WHERE [EmployeeID] = @EmployeeID"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" >
   <DeleteParameters>
       <asp:Parameter Name="EmployeeID" />
   DeleteParameters>
asp:SqlDataSource>
 
<asp:Button
   ID="btnMultipleRowDelete"
   OnClick="btnMultipleRowDelete_Click"
   runat="server"
   Text="Delete Rows" />
 
In Code behind file (.cs) for C# and (.vb) for VB.NET, code the button click event. Our code will first loop through all the rows in the GridView. If a row is checked, the code retrieves the EmployeeID and passes the selected value to the Delete Command.
C#
 
 
protected void btnMultipleRowDelete_Click(object sender, EventArgs e)
{
        // Looping through all the rows in the GridView
        foreach (GridViewRow row in GridView1.Rows)
        {
            CheckBox checkbox = (CheckBox)row.FindControl("cbRows");
 
            //Check if the checkbox is checked.
//value in the HtmlInputCheckBox's Value property is set as the //value of the delete command's parameter.
            if (checkbox.Checked)
            {
                // Retreive the Employee ID
int employeeID = Convert.ToInt32(GridView1.DataKeys[row.RowIndex].Value);
// Pass the value of the selected Employye ID to the Delete //command.
SqlDataSource1.DeleteParameters["EmployeeID"].DefaultValue = employeeID.ToString();
                SqlDataSource1.Delete();
            }
        }
 }