A Common requirement we have would be to have a Dropdownlist of items which would be common across all the pages (top navigation or in the left navigation).
Retrieving the selected item in a dropdownlist which resides in the same page, is pretty straight forward dropdownlist1.selecteditem.value.
However, when it is in a usercontrol, its pretty difficult to retrieve it since you will get the "Object Reference not set to an instance" error if you try the normal method. Even if you create an instance of the usercontrol and try to access its dropdownlist, you will get the above error.
The following code demonstrates how to overcome this problem.
UserControl objCtrl = ((UserControl)(FindControl("Id of the Usercontrol as declared in the container page")));
DropDownList ddl = ((DropDownList)(objCtrl.FindControl("Id of the Dropdownlist control in the usercontrol")));
Response.Write(ddl.SelectedItem.Value);
Thats it and you can access the value.
Cheers and Happy Programming!
Wednesday, December 17, 2008
Tuesday, December 16, 2008
How ASP.NET databinding deals with Eval() and Bind() statements
A recent question on one of our internal mailing lists asked where the definition for the Bind() method is located in ASP.NET. The asker had located the definition of the Eval() method on the TemplateControl class, but the Bind() method was nowhere to be found, even using Reflector.
If you're familiar with databinding in ASP.NET 2.0, you probably know that for read-only values such as Labels you can use the Eval() statement, and for read-write values such as TextBoxes (also known as "two-way databinding") you can use the Bind() statement. Where does that Bind() statement come from?
To the surprise of many readers, there isn’t a bind method in ASP.NET! When ASP.NET parses your file and sees you're using a databinding expression (in the angle-bracket-percent-pound format, "<%# %>") it has special-case code to parse for the Bind syntax and generates some special code for it. When you use <%# Bind("Name") %> it's not a real function call. If ASP.NET parses the code and detects a Bind() statement, it splits the statement into two parts. The first part is the one-way databinding portion, which ends up being just a regular Eval() call. The second part is the reverse portion, which is typically some code along the lines of "string name = TextBox1.Text" that grabs the value back out from where it was bound.
Non-Bind() databinding statements are literal code (we use CodeSnippetExpressions in CodeDom), so arbitrary code in the language of your choice is allowed. However, because ASP.NET has to parse Bind() statements, two-way databinding doesn’t support anything other than Bind(). For example, the following syntax is invalid because it tries to invoke arbitrary code and use Bind() at the same time:
<%# FormatNameHelper(Bind("Name")) %>
The only formats supported in two-way databinding are Bind("field") and Bind("field", "format string {0}"). There are some very minor variations of these syntax examples, such as allowing use of single quotes and not just double quotes. Since some languages supported by ASP.NET favor one format over the other, we have to support both formats, even though the language you're using may support only one.
The moral of the story is: There are some things that Reflector won't tell you.
If you're familiar with databinding in ASP.NET 2.0, you probably know that for read-only values such as Labels you can use the Eval() statement, and for read-write values such as TextBoxes (also known as "two-way databinding") you can use the Bind() statement. Where does that Bind() statement come from?
To the surprise of many readers, there isn’t a bind method in ASP.NET! When ASP.NET parses your file and sees you're using a databinding expression (in the angle-bracket-percent-pound format, "<%# %>") it has special-case code to parse for the Bind syntax and generates some special code for it. When you use <%# Bind("Name") %> it's not a real function call. If ASP.NET parses the code and detects a Bind() statement, it splits the statement into two parts. The first part is the one-way databinding portion, which ends up being just a regular Eval() call. The second part is the reverse portion, which is typically some code along the lines of "string name = TextBox1.Text" that grabs the value back out from where it was bound.
Non-Bind() databinding statements are literal code (we use CodeSnippetExpressions in CodeDom), so arbitrary code in the language of your choice is allowed. However, because ASP.NET has to parse Bind() statements, two-way databinding doesn’t support anything other than Bind(). For example, the following syntax is invalid because it tries to invoke arbitrary code and use Bind() at the same time:
<%# FormatNameHelper(Bind("Name")) %>
The only formats supported in two-way databinding are Bind("field") and Bind("field", "format string {0}"). There are some very minor variations of these syntax examples, such as allowing use of single quotes and not just double quotes. Since some languages supported by ASP.NET favor one format over the other, we have to support both formats, even though the language you're using may support only one.
The moral of the story is: There are some things that Reflector won't tell you.
Tuesday, December 2, 2008
Types Of Parameters In C#
Parameters are means: way of passing values to a method.The syntax of passing parameter in C# is:
[modifier] DataType ParameterName
There are four different ways of passing parameters to a method in C#. The four different types of parameters are:
1. Value
2. Out
3. Ref
4. Params
1. Value parameters This is the default parameter type in C#. If the parameter does not have any modifier it is "value" parameter by default.When we use "value" parameters the actual value is passed to the function,which means changes made to the parameter is local to the function and is not passed back to the calling part.
using System;
class ParameterInCSharp
{
static void ParameterType(int intValueParameter)
{
intValueParameter = 100;
}
static void Main()
{
int intAnotherValue = 5;
ParameterType(intAnotherValue);
Console.WriteLine(intAnotherValue);
}
}
Output of the above program would be 5.Eventhough the value of the parameter Param1 is changed within MyMethod it is not passed back to the calling part since value parameters are input only.
2. Out parameters "out" parameters are output only parameters meaning they can only passback a value from a function.We create a "out" parameter by preceding the parameter data type with the out modifier. When ever a "out" parameter is passed only an unassigned reference is passed to the function.
using System;
class ParameterInCSharp
{
static void ParameterType(out int outParameter)
{
outParameter = 100;
}
static void Main()
{
int intAnotherValue = 5;
ParameterType(intAnotherValue);
Console.WriteLine(intAnotherValue);
}
}
Output of the above program would be 100 since the value of the "out" parameter is passed back to the calling part.
Note:
The modifier "out" should precede the parameter being passed even in the calling part. "out" parameters cannot be used within the function before assigning a value to it. A value should be assigned to the "out" parameter before the method returns.
3. Ref parameters "ref" parameters are input/output parameters meaning they can be used for passing a value to a function as well as to get back a value from a function.We create a "ref" parameter by preceding the parameter data type with the ref modifier. When ever a "ref" parameter is passed a reference is passed to the function.
using System;
class ParameterInCSharp
{
static void ParameterType(ref int refParameter)
{
refParameter = refParameter + 10;
}
static void Main()
{
int intAnotherValue=5;
ParameterType(intAnotherValue);
Console.WriteLine(intAnotherValue);
}
}
Output of the above program would be 15 since the "ref" parameter acts as both input and output.
Note:
The modifier "ref" should precede the parameter being passed even in the calling part. "ref" parameters should be assigned a value before using it to call a method. 4.Params parameters "params" parameters is a very useful feature in C#. "params" parameter are used when a variable number of arguments need to be passed.The "params" should be a single dimensional or a jagged array.
using System;
class ParameterTest
{
static int ParameterType(params int[] paramsParameter)
{
int testParameter = 0;
foreach(int intParams in paramsParameter)
{
testParameter = testParameter + intParams;
}
return testParameter;
}
static void Main()
{
Console.WriteLine(ParameterType(1,2,3));
}
}
Output of the above program would be 6.
Note:
The value passed for a "params" parameter can be either comma separated value list or a single dimensional array. "params" parameters are input only.
[modifier] DataType ParameterName
There are four different ways of passing parameters to a method in C#. The four different types of parameters are:
1. Value
2. Out
3. Ref
4. Params
1. Value parameters This is the default parameter type in C#. If the parameter does not have any modifier it is "value" parameter by default.When we use "value" parameters the actual value is passed to the function,which means changes made to the parameter is local to the function and is not passed back to the calling part.
using System;
class ParameterInCSharp
{
static void ParameterType(int intValueParameter)
{
intValueParameter = 100;
}
static void Main()
{
int intAnotherValue = 5;
ParameterType(intAnotherValue);
Console.WriteLine(intAnotherValue);
}
}
Output of the above program would be 5.Eventhough the value of the parameter Param1 is changed within MyMethod it is not passed back to the calling part since value parameters are input only.
2. Out parameters "out" parameters are output only parameters meaning they can only passback a value from a function.We create a "out" parameter by preceding the parameter data type with the out modifier. When ever a "out" parameter is passed only an unassigned reference is passed to the function.
using System;
class ParameterInCSharp
{
static void ParameterType(out int outParameter)
{
outParameter = 100;
}
static void Main()
{
int intAnotherValue = 5;
ParameterType(intAnotherValue);
Console.WriteLine(intAnotherValue);
}
}
Output of the above program would be 100 since the value of the "out" parameter is passed back to the calling part.
Note:
The modifier "out" should precede the parameter being passed even in the calling part. "out" parameters cannot be used within the function before assigning a value to it. A value should be assigned to the "out" parameter before the method returns.
3. Ref parameters "ref" parameters are input/output parameters meaning they can be used for passing a value to a function as well as to get back a value from a function.We create a "ref" parameter by preceding the parameter data type with the ref modifier. When ever a "ref" parameter is passed a reference is passed to the function.
using System;
class ParameterInCSharp
{
static void ParameterType(ref int refParameter)
{
refParameter = refParameter + 10;
}
static void Main()
{
int intAnotherValue=5;
ParameterType(intAnotherValue);
Console.WriteLine(intAnotherValue);
}
}
Output of the above program would be 15 since the "ref" parameter acts as both input and output.
Note:
The modifier "ref" should precede the parameter being passed even in the calling part. "ref" parameters should be assigned a value before using it to call a method. 4.Params parameters "params" parameters is a very useful feature in C#. "params" parameter are used when a variable number of arguments need to be passed.The "params" should be a single dimensional or a jagged array.
using System;
class ParameterTest
{
static int ParameterType(params int[] paramsParameter)
{
int testParameter = 0;
foreach(int intParams in paramsParameter)
{
testParameter = testParameter + intParams;
}
return testParameter;
}
static void Main()
{
Console.WriteLine(ParameterType(1,2,3));
}
}
Output of the above program would be 6.
Note:
The value passed for a "params" parameter can be either comma separated value list or a single dimensional array. "params" parameters are input only.
Monday, December 1, 2008
MultiSelectDropDownList

In CSS
.Default
{
font-size:smaller;
font-family:Tahoma;
}
table
{
padding:0px;
border-collapse:collapse;
}
.DropDownLook
{
padding:0px;
border-style:solid;
border-width:1px;
}
.DivClose
{
display:none;
position:absolute;
width:250px;
height:220px;
border-style:solid;
border-color:Gray;
border-width:1px;
background-color:#99A479;
}
.LabelClose
{
vertical-align:text-top;
position:absolute;
bottom:0px;
font-family:Verdana;
}
.DivCheckBoxList
{
display:none;
background-color:White;
width:250px;
position:absolute;
height:200px;
overflow-y:auto;
overflow-x:hidden;
border-style:solid;
border-color:Gray;
border-width:1px;
}
.CheckBoxList
{
position:relative;
width:250px;
height:10px;
overflow:scroll;
font-size:small;
}
In .CS
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
lstMultipleValues.Attributes.Add("onclick", "FindSelectedItems(this," + txtSelectedMLValues.ClientID + ");");
SetMultiValue();
lblDescription.Text = "On click of dropdown, the multi select option will appear.
Once you remove focus from the dropdown"
+ " area it will get auto collapsed.
In case needed, you can go ahead and close it with the close ('X') provided at the bottom.
";
}
}
protected void SetMultiValue()
{
DataTable dt = new DataTable("Table1");
DataColumn dc1 = new DataColumn("Text");
DataColumn dc2 = new DataColumn("Value");
dt.Columns.Add(dc1);
dt.Columns.Add(dc2);
//To get enough data for scroll
dt.Rows.Add("Bangalore", 1);
dt.Rows.Add("Kolkata", 2);
dt.Rows.Add("Pune", 3);
dt.Rows.Add("Mumbai", 4);
dt.Rows.Add("Noida", 5);
dt.Rows.Add("Gurgaon", 6);
dt.Rows.Add("Hyderabad", 7);
dt.Rows.Add("Chennai", 8);
dt.Rows.Add("Jaipur", 8);
dt.Rows.Add("Patna", 8);
dt.Rows.Add("Ranchi", 8);
lstMultipleValues.DataSource = dt;
lstMultipleValues.DataTextField = "Text";
lstMultipleValues.DataValueField = "Value";
lstMultipleValues.DataBind();
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
// Text showed that were selected
lblTextSelected.Text = "Submitted Values: " + txtSelectedMLValues.Value;
// One can loop through the checkboxlist control to get the Values too for the text selected if required.
}
}
In JavaScript
var timoutID;
function ShowMList()
{
var divRef = document.getElementById("divCheckBoxList");
divRef.style.display = "block";
var divRefC = document.getElementById("divCheckBoxListClose");
divRefC.style.display = "block";
}
function HideMList()
{
document.getElementById("divCheckBoxList").style.display = "none";
document.getElementById("divCheckBoxListClose").style.display = "none";
}
function FindSelectedItems(sender,textBoxID)
{
var cblstTable = document.getElementById(sender.id);
var checkBoxPrefix = sender.id + "_";
var noOfOptions = cblstTable.rows.length;
var selectedText = "";
for(i=0; i < noOfOptions ; ++i)
{
if(document.getElementById(checkBoxPrefix+i).checked)
{
if(selectedText == "")
selectedText = document.getElementById(checkBoxPrefix+i).parentNode.innerText;
else
selectedText = selectedText + "," + document.getElementById(checkBoxPrefix+i).parentNode.innerText;
}
}
document.getElementById(textBoxID.id).value = selectedText;
}
In .ASPX
asp:UpdatePanel ID="upDefault" runat="server"
ContentTemplate
asp:Label ID="lblDescription" runat="server" Text="Label" /asp:Label
div id="divCustomCheckBoxList" runat="server" onmouseover="clearTimeout(timoutID);" onmouseout="timoutID = setTimeout('HideMList()', 750);"
table
tr
td align="right" class="DropDownLook"
input id="txtSelectedMLValues" type="text" readonly="readonly" onclick="ShowMList()" style="width:229px;" runat="server" /
/td
td align="left" class="DropDownLook"
img id="imgShowHide" runat="server" src="drop.gif" onclick="ShowMList()" align="left" /
/td
/tr
tr
td colspan="2" class="DropDownLook"
div
div runat="server" id="divCheckBoxListClose" class="DivClose"
label runat="server" onclick="HideMList();" class="LabelClose" id="lblClose" x /label
/div
div runat="server" id="divCheckBoxList" class="DivCheckBoxList"
asp:CheckBoxList ID="lstMultipleValues" runat="server" Width="250px" CssClass="CheckBoxList" /asp:CheckBoxList
/div
/div
/td
/tr
/table
/div
div
asp:Button ID="btnSubmit" runat="server" Text="Submit Selection" OnClick="btnSubmit_Click" /
asp:Label ID="lblTextSelected" runat="server" Text="" Font-Bold="true" >/asp:Label
/div
/ContentTemplate
/asp:UpdatePanel
Understanding Identity Columns
How can I reset an Identity column and not start where it left?" I've been getting quite a few questions about identity columns lately. This article should cover everything I know about them. I'll cover creating them, populating them, resetting them and a few other goodies. (This article has been updated through SQL Server 2005.)
Creating an Identity Column
In it's simplest form an identity column creates a numeric sequence for you. You can specify a column as an identity in the CREATE TABLE statement:
CREATE TABLE dbo.Yaks ( YakID smallint identity(7,2), YakName char(20) )
The identity clause specifies that the column YakID is going to be an identity column. The first record added will automatically be assigned a value of 7 (the seed) and each subsequent record will be assigned a value 2 higher (the increment) than the previous inserted row. Most identity columns I see are specified as IDENTITY(1,1) but I used IDENTITY(7,2) so the difference would be clear. If you don't specify the identity and seed they both default to 1. Identity columns can be int, bigint, smallint, tinyint, or decimal or numeric with a scale of 0 (i.e. no places to the right of the decimal).
Populating the Table
When you insert into a table with an identity column you don't put a value into the identity column.
INSERT INTO dbo.Yaks (YakName) values ('Gertrude')
INSERT INTO dbo.Yaks (YakName) values ('Helga')
SELECT YakID, YakName
FROM dbo.Yaks
- - - - - - - - - - - - - - - - - - - - - - - -
YakID YakName
------ --------------------
7 Gertrude
9 Helga
The value for YakID was automatically filled in. If you do try to fill in a value for an identity column it will give you an error:
INSERT INTO dbo.Yaks (YakID, YakName) values (5, 'Sam')
- - - - - - - - - - - - - - - - - - - - - - - -
Server: Msg 544, Level 16, State 1, Line 1
Cannot insert explicit value for identity column in table 'Yaks' when IDENTITY_INSERT is set to OFF.
Finding the Identity Value that was Inserted
If you want to see what identity value was just inserted you can use @@IDENTITY.
INSERT INTO dbo.Yaks (YakName) values ('Sam the Yak')
SELECT SCOPE_IDENTITY() as NewRec
- - - - - - - - - - - - - - - - - - - - - - - -
NewRec
----------------
11
Older applications might use @@IDENTITY to return the last identity value inserted. If you use @@IDENTITY and insert into a table that runs a trigger and generates another identity value, you will get back the last value generated in any table. That's why you use SCOPE_IDENTITY to return the inserted value. Every procedure, trigger, function and batch is it's own scope. SCOPE_IDENTITY shows the most recently inserted IDENTITY in the current scope (which ignores any triggers that might fire). SCOPE_IDENTITY is only available in SQL Server 2000 and higher. You can also see the most recent identity value for a table regardless of scope or session (process). You can use IDENT_CURRENT for that (again, SQL Server 2000 and higher only).
SELECT IDENT_CURRENT('Yaks') as SameRecordAgain
- - - - - - - - - - - - - - - - - - - - - - - -
SameRecordAgain
----------------
11
Notice that we had to pass in the table name to the IDENT_CURRENT function. This will give you the most recent identity value for that table regardless of who inserted it.
Inserting Explicit Values into an Identity Column
If you want to insert a value into an identity column you can use the SET IDENTITY_INSERT statement.
SET IDENTITY_INSERT Yaks ON
INSERT INTO dbo.Yaks (YakID, YakName) Values(1, 'Mac the Yak')
SET IDENTITY_INSERT Yaks OFF
SELECT * from yaks
- - - - - - - - - - - - - - - - - - - - - - - -
YakID YakName
------ --------------------
7 Gertrude
9 Helga
11 Sam the Yak
1 Mac the Yak
You can only turn on IDENTITY_INSERT for one table per session so it's always a good idea to turn it off when you're done with it.
Deleting rows from a table with an Identity Column
If you delete all the records from a table it won't reset the identity.
DELETE FROM dbo.Yaks
INSERT INTO dbo.Yaks (YakName) Values ('New Herd')
SELECT SCOPE_IDENTITY()
returns the inserted identity as 13. To reset the identity seed you need to use a DBCC command.
DELETE FROM dbo.Yaks
DBCC CHECKIDENT('Yaks', RESEED, 7)
INSERT INTO dbo.Yaks (YakName) Values ('New Herd')
SELECT SCOPE_IDENTITY()
This returns an identity of 9. After the seed value is reset to 7, it's incremented by 2 (as we specified when we created the table) for the next record. Which also FINALLY answered Karla's question. You can also run DBCC CHECKIDENT without specifying a reseed value. If the current seed is lower than the highest value in the table, the seed is updated to the highest value in the table.
SQL Server makes no attempt to guarantee sequential gap-free values in identity columns. If records are deleted SQL Server won't go back and populate using those values. It's also possible for an insert to fail and "use up" an identity value. Books Online has additional detailed information about identity columns.
Creating an Identity Column
In it's simplest form an identity column creates a numeric sequence for you. You can specify a column as an identity in the CREATE TABLE statement:
CREATE TABLE dbo.Yaks ( YakID smallint identity(7,2), YakName char(20) )
The identity clause specifies that the column YakID is going to be an identity column. The first record added will automatically be assigned a value of 7 (the seed) and each subsequent record will be assigned a value 2 higher (the increment) than the previous inserted row. Most identity columns I see are specified as IDENTITY(1,1) but I used IDENTITY(7,2) so the difference would be clear. If you don't specify the identity and seed they both default to 1. Identity columns can be int, bigint, smallint, tinyint, or decimal or numeric with a scale of 0 (i.e. no places to the right of the decimal).
Populating the Table
When you insert into a table with an identity column you don't put a value into the identity column.
INSERT INTO dbo.Yaks (YakName) values ('Gertrude')
INSERT INTO dbo.Yaks (YakName) values ('Helga')
SELECT YakID, YakName
FROM dbo.Yaks
- - - - - - - - - - - - - - - - - - - - - - - -
YakID YakName
------ --------------------
7 Gertrude
9 Helga
The value for YakID was automatically filled in. If you do try to fill in a value for an identity column it will give you an error:
INSERT INTO dbo.Yaks (YakID, YakName) values (5, 'Sam')
- - - - - - - - - - - - - - - - - - - - - - - -
Server: Msg 544, Level 16, State 1, Line 1
Cannot insert explicit value for identity column in table 'Yaks' when IDENTITY_INSERT is set to OFF.
Finding the Identity Value that was Inserted
If you want to see what identity value was just inserted you can use @@IDENTITY.
INSERT INTO dbo.Yaks (YakName) values ('Sam the Yak')
SELECT SCOPE_IDENTITY() as NewRec
- - - - - - - - - - - - - - - - - - - - - - - -
NewRec
----------------
11
Older applications might use @@IDENTITY to return the last identity value inserted. If you use @@IDENTITY and insert into a table that runs a trigger and generates another identity value, you will get back the last value generated in any table. That's why you use SCOPE_IDENTITY to return the inserted value. Every procedure, trigger, function and batch is it's own scope. SCOPE_IDENTITY shows the most recently inserted IDENTITY in the current scope (which ignores any triggers that might fire). SCOPE_IDENTITY is only available in SQL Server 2000 and higher. You can also see the most recent identity value for a table regardless of scope or session (process). You can use IDENT_CURRENT for that (again, SQL Server 2000 and higher only).
SELECT IDENT_CURRENT('Yaks') as SameRecordAgain
- - - - - - - - - - - - - - - - - - - - - - - -
SameRecordAgain
----------------
11
Notice that we had to pass in the table name to the IDENT_CURRENT function. This will give you the most recent identity value for that table regardless of who inserted it.
Inserting Explicit Values into an Identity Column
If you want to insert a value into an identity column you can use the SET IDENTITY_INSERT statement.
SET IDENTITY_INSERT Yaks ON
INSERT INTO dbo.Yaks (YakID, YakName) Values(1, 'Mac the Yak')
SET IDENTITY_INSERT Yaks OFF
SELECT * from yaks
- - - - - - - - - - - - - - - - - - - - - - - -
YakID YakName
------ --------------------
7 Gertrude
9 Helga
11 Sam the Yak
1 Mac the Yak
You can only turn on IDENTITY_INSERT for one table per session so it's always a good idea to turn it off when you're done with it.
Deleting rows from a table with an Identity Column
If you delete all the records from a table it won't reset the identity.
DELETE FROM dbo.Yaks
INSERT INTO dbo.Yaks (YakName) Values ('New Herd')
SELECT SCOPE_IDENTITY()
returns the inserted identity as 13. To reset the identity seed you need to use a DBCC command.
DELETE FROM dbo.Yaks
DBCC CHECKIDENT('Yaks', RESEED, 7)
INSERT INTO dbo.Yaks (YakName) Values ('New Herd')
SELECT SCOPE_IDENTITY()
This returns an identity of 9. After the seed value is reset to 7, it's incremented by 2 (as we specified when we created the table) for the next record. Which also FINALLY answered Karla's question. You can also run DBCC CHECKIDENT without specifying a reseed value. If the current seed is lower than the highest value in the table, the seed is updated to the highest value in the table.
SQL Server makes no attempt to guarantee sequential gap-free values in identity columns. If records are deleted SQL Server won't go back and populate using those values. It's also possible for an insert to fail and "use up" an identity value. Books Online has additional detailed information about identity columns.
C# 2.0 Anonymous Methods
C# 2.0 provides a new feature called Anonymous Methods, which allow you to create inline un-named ( i.e. anonymous ) methods in your code, which can help increase the readability and maintainability of your applications by keeping the caller of the method and the method itself as close to one another as possible. This is akin to the best practice of keeping the declaration of a variable, for example, as close to the code that uses it.
Here is a simple example of using an anonymous method to find all the even integers from 1...10:
private int[] _integers =
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int[] evenIntegers = Array.FindAll(_integers,
delegate(int integer)
{
return (integer%2 == 0);
}
);
The Anonymous Method is:
delegate(int integer)
{
return (integer%2 == 0);
}
which is called for each integer in the array and returns either true or false depending on if the integer is even.
If you don't use an anonymous method, you will need to create a separate method as such:
private int[] _integers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int[] evenIntegers = Array.FindAll(_integers, IsEven);
private bool IsEven(int integer)
{
return (integer%2 == 0);
}
When you have very simple methods like above that won't be reused, I find it much more elegant and meaningful to use anonymous methods. The code stays closer together which makes it easier to follow and maintain.
Here is an example that uses an anonymous method to get the list of cities in a state selected in a DropDownList ( called States ):
List citiesInFlorida =
cities.FindAll(delegate(City city)
{
return city.State.Name.Equals(States.SelectedValue);
}
);
You can also use anonymous methods as such:
button1.Click +=
delegate
{
MessageBox.Show("Hello");
};
which for such a simple operation doesn't “deserve“ a separate method to handle the event.
Other uses of anonymous methods would be for asynchronous callback methods, etc.
Anonymous methods don't have the cool factor of Generics, but they do offer a more expressive in-line approach to creating methods that can make your code easier to follow and maintain.
Here is a simple example of using an anonymous method to find all the even integers from 1...10:
private int[] _integers =
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int[] evenIntegers = Array.FindAll(_integers,
delegate(int integer)
{
return (integer%2 == 0);
}
);
The Anonymous Method is:
delegate(int integer)
{
return (integer%2 == 0);
}
which is called for each integer in the array and returns either true or false depending on if the integer is even.
If you don't use an anonymous method, you will need to create a separate method as such:
private int[] _integers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int[] evenIntegers = Array.FindAll(_integers, IsEven);
private bool IsEven(int integer)
{
return (integer%2 == 0);
}
When you have very simple methods like above that won't be reused, I find it much more elegant and meaningful to use anonymous methods. The code stays closer together which makes it easier to follow and maintain.
Here is an example that uses an anonymous method to get the list of cities in a state selected in a DropDownList ( called States ):
List
cities.FindAll(delegate(City city)
{
return city.State.Name.Equals(States.SelectedValue);
}
);
You can also use anonymous methods as such:
button1.Click +=
delegate
{
MessageBox.Show("Hello");
};
which for such a simple operation doesn't “deserve“ a separate method to handle the event.
Other uses of anonymous methods would be for asynchronous callback methods, etc.
Anonymous methods don't have the cool factor of Generics, but they do offer a more expressive in-line approach to creating methods that can make your code easier to follow and maintain.
Sunday, November 30, 2008
Maximum Capacity Specifications for SQL Server 2005
# Batch size : -> 65,536 * Network Packet Size
# Bytes per short string column : -> 8000
# Bytes per text, ntext, image, varchar(max), nvarchar(max), varbinary(max), or XML column : -> 231 -1 bytes/p>
# Bytes per GROUP BY, ORDER BY : -> 8060
# Bytes per index : -> 900
# Bytes per foreign key : -> 900
# Bytes per primary key : -> 900
# Bytes per row : -> 8060
# Bytes in source text of a stored procedure : -> Lesser of batch size or 250 MB
# Clustered indexes per table : -> 1
# Columns in GROUP BY, ORDER BY : -> Limited only by number of bytes
# Columns or expressions in a GROUP BY WITH CUBE or WITH ROLLUP statement : -> 10
# Columns per index : -> 16
# Columns per foreign key : -> 16
# Columns per primary key : -> 16
# Columns per base table : -> 1024
# Columns per SELECT statement : -> 4096
# Columns per INSERT statement : -> 1024
# Connections per client : -> Maximum value of configured connections
# Database size : -> 1,048,516 terabytes
# Databases per instance of SQL Server : -> 32767
# Filegroups per database : -> 32767
# Files per database : -> 32767
# File size (data) : -> 32 terabytes
# File size (log) : -> 32 terabytes
# Foreign key table references per table : -> 253
# Identifier length (in characters) : -> 128
# Instances per computer : -> 50
# Length of a string containing SQL statements (batch size) : -> 65,536 * Network packet size
# Locks per connection : -> Maximum locks per server
# Locks per instance of SQL Server : -> Up to 2,147,483,647
# Nested stored procedure levels : -> 32
# Nested subqueries : -> 32
# Nested trigger levels : -> 32
# Nonclustered indexes per table : -> 249
# Objects concurrently open in an instance of SQL Server : -> 2,147,483,647 per database (depending on available memory)
# Objects in a database : -> 2147483647
# Parameters per stored procedure : -> 2100
# Parameters per user-defined function : -> 2100
# REFERENCES per table : -> 253
# Rows per table : -> Limited by available storage
# Tables per database : -> Limited by number of objects in a database
# Tables per SELECT statement : -> 256
# Triggers per table : -> Limited by number of objects in a database
# UNIQUE indexes or constraints per table : -> 249 nonclustered and 1 clustered
# Bytes per short string column : -> 8000
# Bytes per text, ntext, image, varchar(max), nvarchar(max), varbinary(max), or XML column : -> 231 -1 bytes/p>
# Bytes per GROUP BY, ORDER BY : -> 8060
# Bytes per index : -> 900
# Bytes per foreign key : -> 900
# Bytes per primary key : -> 900
# Bytes per row : -> 8060
# Bytes in source text of a stored procedure : -> Lesser of batch size or 250 MB
# Clustered indexes per table : -> 1
# Columns in GROUP BY, ORDER BY : -> Limited only by number of bytes
# Columns or expressions in a GROUP BY WITH CUBE or WITH ROLLUP statement : -> 10
# Columns per index : -> 16
# Columns per foreign key : -> 16
# Columns per primary key : -> 16
# Columns per base table : -> 1024
# Columns per SELECT statement : -> 4096
# Columns per INSERT statement : -> 1024
# Connections per client : -> Maximum value of configured connections
# Database size : -> 1,048,516 terabytes
# Databases per instance of SQL Server : -> 32767
# Filegroups per database : -> 32767
# Files per database : -> 32767
# File size (data) : -> 32 terabytes
# File size (log) : -> 32 terabytes
# Foreign key table references per table : -> 253
# Identifier length (in characters) : -> 128
# Instances per computer : -> 50
# Length of a string containing SQL statements (batch size) : -> 65,536 * Network packet size
# Locks per connection : -> Maximum locks per server
# Locks per instance of SQL Server : -> Up to 2,147,483,647
# Nested stored procedure levels : -> 32
# Nested subqueries : -> 32
# Nested trigger levels : -> 32
# Nonclustered indexes per table : -> 249
# Objects concurrently open in an instance of SQL Server : -> 2,147,483,647 per database (depending on available memory)
# Objects in a database : -> 2147483647
# Parameters per stored procedure : -> 2100
# Parameters per user-defined function : -> 2100
# REFERENCES per table : -> 253
# Rows per table : -> Limited by available storage
# Tables per database : -> Limited by number of objects in a database
# Tables per SELECT statement : -> 256
# Triggers per table : -> Limited by number of objects in a database
# UNIQUE indexes or constraints per table : -> 249 nonclustered and 1 clustered
Friday, November 28, 2008
OOPS Concepts:
1) Encapsulation: Wrapping up of data and methods in to a
single unit is called as encapsulation.
Protecting our data
2) Abstraction: Hidding our irrelavance data
3) Inheritence: Process of Aquiring properties from one
object to another without changes.
4) Polymorphism: Process of aquiring properies from one
object to anotherwith changes.Different behaviors at diff. instances
There are two types of polymorphisms.
i)Compile-time polymorphism:what object will be assigned to
the present variable.This will be evaluated at compile time.
This is known as compile-time polymorphism.
ii)Run-time polymorphism:what object will be assigned to the
present variable.This will be evaluated at runtime depending
on condition.This is known as Run-time polymorphism.
5) Message Passing:message passing is possible from one
object to another.
6) Robust and Secure: every object is strong one.
every object is secure one with their access specifiers.
Abstract, Sealed, and Static Modifiers in C#.
C# provides many modifiers for use with types and type members. Of these, three can be used with classes: abstract, sealed and static.
abstract
Indicates that a class is to be used only as a base class for other classes. This means that you cannot create an instance of the class directly. Any class derived from it must implement all of its abstract methods and accessors. Despite its name, an abstract class can possess non-abstract methods and properties.
sealed
Specifies that a class cannot be inherited (used as a base class). Note that .NET does not permit a class to be both abstract and sealed.
static
Specifies that a class contains only static members (.NET 2.0).
Virtual keyword
The virtual keyword allows polymorphism too. A virtual property or method has an implementation in the base class, and can be overriden in the derived classes.
To create a virtual member in C#, use the virtual keyword:
public virtual void Draw()
To create a virtual member in VB.NET, use the Overridable keyword:
Public Overridable Function Draw()
Override keyword
Overriding is the action of modifying or replacing the implementation of the parent class with a new one. Parent classes with virtual or abstract members allow derived classes to override them.
To override a member in C#, use the override keyword:
public override void CalculateArea()
To override a member in VB.NET, use the Overrides keyword:
Public Overrides Function CalculateArea()
What's the difference between override and new in C#?
This is all to do with polymorphism. When a virtual method is called on a reference, the actual type of the object that the reference refers to is used to decide which method implementation to use. When a method of a base class is overridden in a derived class, the version in the derived class is used, even if the calling code didn't "know" that the object was an instance of the derived class. For instance:
public class Base
{
public virtual void SomeMethod()
{
}
}
public class Derived : Base
{
public override void SomeMethod()
{
}
}
...
Base b = new Derived();
b.SomeMethod();
will end up calling Derived.SomeMethod if that overrides Base.SomeMethod.
Now, if you use the new keyword instead of override, the method in the derived class doesn't override the method in the base class, it merely hides it. In that case, code like this:
public class Base
{
public virtual void SomeOtherMethod()
{
}
}
public class Derived : Base
{
public new void SomeOtherMethod()
{
}
}
...
Base b = new Derived();
Derived d = new Derived();
b.SomeOtherMethod();
d.SomeOtherMethod();
Will first call Base.SomeOtherMethod , then Derived.SomeOtherMethod . They're effectively two entirely separate methods which happen to have the same name, rather than the derived method overriding the base method.
If you don't specify either new or overrides, the resulting output is the same as if you specified new, but you'll also get a compiler warning (as you may not be aware that you're hiding a method in the base class method, or indeed you may have wanted to override it, and merely forgot to include the keyword).
single unit is called as encapsulation.
Protecting our data
2) Abstraction: Hidding our irrelavance data
3) Inheritence: Process of Aquiring properties from one
object to another without changes.
4) Polymorphism: Process of aquiring properies from one
object to anotherwith changes.Different behaviors at diff. instances
There are two types of polymorphisms.
i)Compile-time polymorphism:what object will be assigned to
the present variable.This will be evaluated at compile time.
This is known as compile-time polymorphism.
ii)Run-time polymorphism:what object will be assigned to the
present variable.This will be evaluated at runtime depending
on condition.This is known as Run-time polymorphism.
5) Message Passing:message passing is possible from one
object to another.
6) Robust and Secure: every object is strong one.
every object is secure one with their access specifiers.
Abstract, Sealed, and Static Modifiers in C#.
C# provides many modifiers for use with types and type members. Of these, three can be used with classes: abstract, sealed and static.
abstract
Indicates that a class is to be used only as a base class for other classes. This means that you cannot create an instance of the class directly. Any class derived from it must implement all of its abstract methods and accessors. Despite its name, an abstract class can possess non-abstract methods and properties.
sealed
Specifies that a class cannot be inherited (used as a base class). Note that .NET does not permit a class to be both abstract and sealed.
static
Specifies that a class contains only static members (.NET 2.0).
Virtual keyword
The virtual keyword allows polymorphism too. A virtual property or method has an implementation in the base class, and can be overriden in the derived classes.
To create a virtual member in C#, use the virtual keyword:
public virtual void Draw()
To create a virtual member in VB.NET, use the Overridable keyword:
Public Overridable Function Draw()
Override keyword
Overriding is the action of modifying or replacing the implementation of the parent class with a new one. Parent classes with virtual or abstract members allow derived classes to override them.
To override a member in C#, use the override keyword:
public override void CalculateArea()
To override a member in VB.NET, use the Overrides keyword:
Public Overrides Function CalculateArea()
What's the difference between override and new in C#?
This is all to do with polymorphism. When a virtual method is called on a reference, the actual type of the object that the reference refers to is used to decide which method implementation to use. When a method of a base class is overridden in a derived class, the version in the derived class is used, even if the calling code didn't "know" that the object was an instance of the derived class. For instance:
public class Base
{
public virtual void SomeMethod()
{
}
}
public class Derived : Base
{
public override void SomeMethod()
{
}
}
...
Base b = new Derived();
b.SomeMethod();
will end up calling Derived.SomeMethod if that overrides Base.SomeMethod.
Now, if you use the new keyword instead of override, the method in the derived class doesn't override the method in the base class, it merely hides it. In that case, code like this:
public class Base
{
public virtual void SomeOtherMethod()
{
}
}
public class Derived : Base
{
public new void SomeOtherMethod()
{
}
}
...
Base b = new Derived();
Derived d = new Derived();
b.SomeOtherMethod();
d.SomeOtherMethod();
Will first call Base.SomeOtherMethod , then Derived.SomeOtherMethod . They're effectively two entirely separate methods which happen to have the same name, rather than the derived method overriding the base method.
If you don't specify either new or overrides, the resulting output is the same as if you specified new, but you'll also get a compiler warning (as you may not be aware that you're hiding a method in the base class method, or indeed you may have wanted to override it, and merely forgot to include the keyword).
Monday, November 24, 2008
GridView Search Revisited
in .aspx
Enter Search Keyword:
asp:TextBox ID="txtSearchBox" runat="server"
asp:Button ID="Btn_Search" OnClick="Search" runat="server" Text="Search" />
asp:GridView ID="gvProducts" runat="server" AutoGenerateColumns="false" AllowPaging="True" Font-Size="Large" OnPageIndexChanging="gvProducts_PageIndexChanging" PageSize="10">
Columns>
asp:TemplateField HeaderText="Product Name">
ItemTemplate>
asp:Label ID="lblProductName" runat="server" Text = '<%# SearchKeyWord( searchWord,(string) Eval("ProductName") ) %>' />
/ItemTemplate>
/asp:TemplateField>
/Columns>
/asp:GridView>
asp:Panel ID="Panel1" runat="server" Height="50px" Width="263px">
.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
public partial class _Default : System.Web.UI.Page
{
protected string searchWord = String.Empty;
private const int PAGE_SIZE = 10;
private Hashtable hMatches = new Hashtable();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindData();
}
CreateLinks();
}
private void CreateLinks()
{
Hashtable myHashTable = ViewState["MyHashTable"] as Hashtable;
if(myHashTable != null && myHashTable.Count > 0)
{
foreach (object key in new ArrayList(myHashTable.Keys))
{
LinkButton link = new LinkButton();
link.Command += new CommandEventHandler(link_Command);
link.CommandArgument = key.ToString();
link.Text = String.Format("There are {0} results on page {1}",myHashTable[key].ToString() , (Convert.ToInt32(key) + 1).ToString()) + "
";
Panel1.Controls.Add(link);
}
Panel1.DataBind();
}
}
private void BindData()
{
string connectionString = @"Server=CB-36A\SQLEXPRESS;Database=master;Trusted_Connection=true";
SqlConnection myConnection = new SqlConnection(connectionString);
SqlDataAdapter ad = new SqlDataAdapter("SELECT ProductName FROM Product", myConnection);
DataSet ds = new DataSet();
ad.Fill(ds);
gvProducts.DataSource = ds;
gvProducts.DataBind();
}
protected void Search(object sender, EventArgs e)
{
// clear the old results
Panel1.Controls.Clear();
Panel1.DataBind();
searchWord = txtSearchBox.Text;
SearchContainer(searchWord);
// Hmmm
BindData();
}
protected string SearchKeyWord(string searchString, string text)
{
Regex reg = new Regex(searchString.Replace(" ", "|"), RegexOptions.IgnoreCase);
return reg.Replace(text,new MatchEvaluator(ReplaceKeyWords));
}
private void SearchContainer(string searchString)
{
int index = 0;
// get the container
DataSet ds = GetDataSet();
double pageIndex = 0;
Regex reg = new Regex(searchString.Replace(" ","|"),RegexOptions.IgnoreCase);
foreach(DataRow row in ds.Tables[0].Rows)
{
if (reg.IsMatch(row["ProductName"] as String))
{
pageIndex = Math.Ceiling( Convert.ToDouble( index / PAGE_SIZE ));
if (hMatches.ContainsKey(pageIndex))
{
hMatches[pageIndex] = ((int)hMatches[pageIndex]) + 1;
}
else
{
hMatches.Add(pageIndex, 1);
}
}
index++;
}
ViewState["MyHashTable"] = hMatches;
CreateLinks();
}
void link_Command(object sender, CommandEventArgs e)
{
gvProducts.PageIndex = Convert.ToInt32( e.CommandArgument);
searchWord = txtSearchBox.Text;
BindData();
}
private DataSet GetDataSet()
{
string connectionString = @"Server=CB-36A\SQLEXPRESS;Database=master;Trusted_Connection=true";
SqlConnection myConnection = new SqlConnection(connectionString);
SqlDataAdapter ad = new SqlDataAdapter("SELECT ProductName FROM Product", myConnection);
DataSet ds = new DataSet();
ad.Fill(ds);
return ds;
}
private string ReplaceKeyWords(Match m)
{
return "" + m.Value + "";
}
protected void gvProducts_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvProducts.PageIndex = e.NewPageIndex;
searchWord = txtSearchBox.Text;
BindData();
}
}
Enter Search Keyword:
asp:TextBox ID="txtSearchBox" runat="server"
asp:Button ID="Btn_Search" OnClick="Search" runat="server" Text="Search" />
asp:GridView ID="gvProducts" runat="server" AutoGenerateColumns="false" AllowPaging="True" Font-Size="Large" OnPageIndexChanging="gvProducts_PageIndexChanging" PageSize="10">
Columns>
asp:TemplateField HeaderText="Product Name">
ItemTemplate>
asp:Label ID="lblProductName" runat="server" Text = '<%# SearchKeyWord( searchWord,(string) Eval("ProductName") ) %>' />
/ItemTemplate>
/asp:TemplateField>
/Columns>
/asp:GridView>
asp:Panel ID="Panel1" runat="server" Height="50px" Width="263px">
.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
public partial class _Default : System.Web.UI.Page
{
protected string searchWord = String.Empty;
private const int PAGE_SIZE = 10;
private Hashtable hMatches = new Hashtable();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindData();
}
CreateLinks();
}
private void CreateLinks()
{
Hashtable myHashTable = ViewState["MyHashTable"] as Hashtable;
if(myHashTable != null && myHashTable.Count > 0)
{
foreach (object key in new ArrayList(myHashTable.Keys))
{
LinkButton link = new LinkButton();
link.Command += new CommandEventHandler(link_Command);
link.CommandArgument = key.ToString();
link.Text = String.Format("There are {0} results on page {1}",myHashTable[key].ToString() , (Convert.ToInt32(key) + 1).ToString()) + "
";
Panel1.Controls.Add(link);
}
Panel1.DataBind();
}
}
private void BindData()
{
string connectionString = @"Server=CB-36A\SQLEXPRESS;Database=master;Trusted_Connection=true";
SqlConnection myConnection = new SqlConnection(connectionString);
SqlDataAdapter ad = new SqlDataAdapter("SELECT ProductName FROM Product", myConnection);
DataSet ds = new DataSet();
ad.Fill(ds);
gvProducts.DataSource = ds;
gvProducts.DataBind();
}
protected void Search(object sender, EventArgs e)
{
// clear the old results
Panel1.Controls.Clear();
Panel1.DataBind();
searchWord = txtSearchBox.Text;
SearchContainer(searchWord);
// Hmmm
BindData();
}
protected string SearchKeyWord(string searchString, string text)
{
Regex reg = new Regex(searchString.Replace(" ", "|"), RegexOptions.IgnoreCase);
return reg.Replace(text,new MatchEvaluator(ReplaceKeyWords));
}
private void SearchContainer(string searchString)
{
int index = 0;
// get the container
DataSet ds = GetDataSet();
double pageIndex = 0;
Regex reg = new Regex(searchString.Replace(" ","|"),RegexOptions.IgnoreCase);
foreach(DataRow row in ds.Tables[0].Rows)
{
if (reg.IsMatch(row["ProductName"] as String))
{
pageIndex = Math.Ceiling( Convert.ToDouble( index / PAGE_SIZE ));
if (hMatches.ContainsKey(pageIndex))
{
hMatches[pageIndex] = ((int)hMatches[pageIndex]) + 1;
}
else
{
hMatches.Add(pageIndex, 1);
}
}
index++;
}
ViewState["MyHashTable"] = hMatches;
CreateLinks();
}
void link_Command(object sender, CommandEventArgs e)
{
gvProducts.PageIndex = Convert.ToInt32( e.CommandArgument);
searchWord = txtSearchBox.Text;
BindData();
}
private DataSet GetDataSet()
{
string connectionString = @"Server=CB-36A\SQLEXPRESS;Database=master;Trusted_Connection=true";
SqlConnection myConnection = new SqlConnection(connectionString);
SqlDataAdapter ad = new SqlDataAdapter("SELECT ProductName FROM Product", myConnection);
DataSet ds = new DataSet();
ad.Fill(ds);
return ds;
}
private string ReplaceKeyWords(Match m)
{
return "" + m.Value + "";
}
protected void gvProducts_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvProducts.PageIndex = e.NewPageIndex;
searchWord = txtSearchBox.Text;
BindData();
}
}
Thursday, November 20, 2008
What is custom control? What is the difference between custom control and user control?
Custom controls are controls that are developed by the developer
or a third party vendor. Custom controls are not provided along with
.NET.
Difference between Custom Controls and User Controls.
1.User Control is a page file with extension .ascx which can only be used within
a single application. But custom controls are assemblies(dll files) that can be
used in multiple applications.
2.User Controls cannot be added to the ToolBox of VS.NET . To use a user Control with in an
aspx page u have to drag the user Control from the solution Explorer to designer page.
But Custom Controls can be added to ToolBox of VS.NET.
3.User Controls can be viewed as a sort of generic controls during the design time.
The proper GUI of user controls can be viewed only during the run time.
But Custom Controls can be viewed during the design time.
4. User controls are created from existing Webserver and html server controls .
But a developer who creates custom controls have to render every thing from the scratch.
5.Since the dll assembly of a custom control is being used,a custom control developed in C# can be used in a project developed in VB.NET or any other managed code and vice versa.
User Controls:
1.Have an ascx extension.
2.Are compiled at runtime when the page is loaded.
3.Visual design is possible, just like an aspx page and uses the ASP.Net page model with code behind file.
4.Can only be used on a host aspx page or another user control.
5.Cannot be added to the ToolBox.
6.Can only be used in the current web application (source must be copied to another application to use).
Custom Server Control:
1.Exist in precompiled assemblies.
2.Code entirely contained in .cs (or .vb)
3.No visual designer. Any HTML code needs to be declared programmatically.
4.Can be used in .aspx pages, user controls or other custom server controls.
5.Can be added to the ToolBox (drag and drop)
6.Can be shared between web applications.
or a third party vendor. Custom controls are not provided along with
.NET.
Difference between Custom Controls and User Controls.
1.User Control is a page file with extension .ascx which can only be used within
a single application. But custom controls are assemblies(dll files) that can be
used in multiple applications.
2.User Controls cannot be added to the ToolBox of VS.NET . To use a user Control with in an
aspx page u have to drag the user Control from the solution Explorer to designer page.
But Custom Controls can be added to ToolBox of VS.NET.
3.User Controls can be viewed as a sort of generic controls during the design time.
The proper GUI of user controls can be viewed only during the run time.
But Custom Controls can be viewed during the design time.
4. User controls are created from existing Webserver and html server controls .
But a developer who creates custom controls have to render every thing from the scratch.
5.Since the dll assembly of a custom control is being used,a custom control developed in C# can be used in a project developed in VB.NET or any other managed code and vice versa.
User Controls:
1.Have an ascx extension.
2.Are compiled at runtime when the page is loaded.
3.Visual design is possible, just like an aspx page and uses the ASP.Net page model with code behind file.
4.Can only be used on a host aspx page or another user control.
5.Cannot be added to the ToolBox.
6.Can only be used in the current web application (source must be copied to another application to use).
Custom Server Control:
1.Exist in precompiled assemblies.
2.Code entirely contained in .cs (or .vb)
3.No visual designer. Any HTML code needs to be declared programmatically.
4.Can be used in .aspx pages, user controls or other custom server controls.
5.Can be added to the ToolBox (drag and drop)
6.Can be shared between web applications.
Monday, November 10, 2008
Change GridView RowColor OnMouseClick
Introduction:
In this article I will demonstrate that how you can change the color of the GridView row by using simple mouse click and change it back to its original color by clicking the row twice.
The Row Created Event of the GridView:
Like my last article "Changing GridView Row Color OnMouseOver" I used the same approach in populating the GridView. The difference lies in the RowCreated event of the GridView control. Take a look at the RowCreated event below to have a better idea:
protected void MyGridView_RowCreated(object sender, GridViewRowEventArgs e)
{
string rowID = String.Empty;
if (e.Row.RowType == DataControlRowType.DataRow)
{
rowID = "row"+e.Row.RowIndex;
e.Row.Attributes.Add("id","row"+e.Row.RowIndex);
e.Row.Attributes.Add("onclick","ChangeRowColor(" +"'" + rowID + "'" + ")");
}
}
As, you can see in the method above I am assigning different ids to the rows by embedding the id attribute. This will help me distinguish one row from the other. Later, on the onclick attribute I attach the Java Script function "ChangeRowColor" which is responsible for changing the color of the GridView row. The ChangeRowColor function takes in the id of the row. Let's take a look at the ChangeRowColor function.
script language ="javascript" type="text/javascript"
document.body.style.cursor = 'pointer';
var oldColor = '';
function ChangeRowColor(rowID)
{
var color = document.getElementById(rowID).style.backgroundColor;
if(color != 'yellow')
oldColor = color;
if(color == 'yellow')
document.getElementById(rowID).style.backgroundColor = oldColor;
else document.getElementById(rowID).style.backgroundColor = 'yellow';
}
/script
The ChangeRowColor function takes in the id of the row and finds the color of the row. Then it checks that if the color is 'yellow' which, is the color of the highlight row. If it is not yellow then it simply assigns the color to the public variable oldColor which is used to save the previous color of the GridView row. If the color is yellow then we get the previous color and assign to the row so that it can come back to its original state.
In this article I will demonstrate that how you can change the color of the GridView row by using simple mouse click and change it back to its original color by clicking the row twice.
The Row Created Event of the GridView:
Like my last article "Changing GridView Row Color OnMouseOver" I used the same approach in populating the GridView. The difference lies in the RowCreated event of the GridView control. Take a look at the RowCreated event below to have a better idea:
protected void MyGridView_RowCreated(object sender, GridViewRowEventArgs e)
{
string rowID = String.Empty;
if (e.Row.RowType == DataControlRowType.DataRow)
{
rowID = "row"+e.Row.RowIndex;
e.Row.Attributes.Add("id","row"+e.Row.RowIndex);
e.Row.Attributes.Add("onclick","ChangeRowColor(" +"'" + rowID + "'" + ")");
}
}
As, you can see in the method above I am assigning different ids to the rows by embedding the id attribute. This will help me distinguish one row from the other. Later, on the onclick attribute I attach the Java Script function "ChangeRowColor" which is responsible for changing the color of the GridView row. The ChangeRowColor function takes in the id of the row. Let's take a look at the ChangeRowColor function.
script language ="javascript" type="text/javascript"
document.body.style.cursor = 'pointer';
var oldColor = '';
function ChangeRowColor(rowID)
{
var color = document.getElementById(rowID).style.backgroundColor;
if(color != 'yellow')
oldColor = color;
if(color == 'yellow')
document.getElementById(rowID).style.backgroundColor = oldColor;
else document.getElementById(rowID).style.backgroundColor = 'yellow';
}
/script
The ChangeRowColor function takes in the id of the row and finds the color of the row. Then it checks that if the color is 'yellow' which, is the color of the highlight row. If it is not yellow then it simply assigns the color to the public variable oldColor which is used to save the previous color of the GridView row. If the color is yellow then we get the previous color and assign to the row so that it can come back to its original state.
Searching Inside the GridView Control And Highlight

There was a post on ASP.NET forums where the user asked how to search inside the GridView control. I was managed to implement this feature although if you plan to use the following code then I would highly recommend that you refactor it as it lacks in performance. In my opinion since you are searching inside the GridView the whole procedure should be handled on the client side using JavaScript or VBScript. Anyhow the following code uses the server side button click event to parse the GridView and highlight the search fields.
protected void Button1_Click(object sender, EventArgs e)
{
string searchString = txtSearch.Text;
StringBuilder sb = new StringBuilder();
DataTable dt = new DataTable();
List
foreach (GridViewRow row in GridView1.Rows)
{
TableCellCollection cells = row.Cells;
foreach (TableCell cell in cells)
{
if (cell.Text.ToLower().StartsWith(searchString.ToLower()))
{
cell.BackColor = System.Drawing.Color.Yellow;
foreach (TableCell c in cells)
{
sb.Append(c.Text);
}
sb.Append("
");
}
else
{
cell.BackColor = System.Drawing.Color.White;
}
}
}
}
The code above simply goes through the GridView row by row and cell by cell. And if it finds a string that starts with the searchString then it highlights it and append it in the StringBuilder object.
Friday, September 26, 2008
Difference Between User Defined functions And Stored Procedure
1>Procedure can return zero or n values whereas function can return one value which is mandatory.
2>Procedures can have input,output parameters for it whereas functions can have only input parameters.
3>Procedure allow select as well as DML statement in it whereas function allow only select statement in it.
4>Functions can be called from procedure whereas procedures cannot be called from function.
5>Exception can be handled by try-catch block in a procedure whereas try-catch block cannot be used in a function.
6>We can go for transaction management in procedure whereas we can't go in function.
7>Procedures can not be utilized in a select statement whereas function can be embedded in a select statement.
2>Procedures can have input,output parameters for it whereas functions can have only input parameters.
3>Procedure allow select as well as DML statement in it whereas function allow only select statement in it.
4>Functions can be called from procedure whereas procedures cannot be called from function.
5>Exception can be handled by try-catch block in a procedure whereas try-catch block cannot be used in a function.
6>We can go for transaction management in procedure whereas we can't go in function.
7>Procedures can not be utilized in a select statement whereas function can be embedded in a select statement.
Thursday, September 25, 2008
DataList Custom Paging

.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.Sql;
using System.Data.SqlClient;
public partial class _Default : System.Web.UI.Page
{
PagedDataSource pds = new PagedDataSource();
DataTable dt = new DataTable();
static int lastPage = 0;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//lastPage = 0;
ddlPageSize.Items.Add("5");
ddlPageSize.Items.Add("10");
ddlPageSize.Items.Add("15");
BindGrid();
}
}
private void BindGrid()
{
string connectionString = @"Data Source =CB-36A\SQLEXPRESS ;Initial Catalog=master;Integrated Security=True";
SqlConnection myConnection = new SqlConnection(connectionString);
SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Country", myConnection);
DataTable dt = new DataTable();
da.Fill(dt);
pds.DataSource = dt.DefaultView;
pds.AllowPaging = true;
pds.PageSize = Convert.ToInt32(ddlPageSize.SelectedValue);
pds.CurrentPageIndex = CurrentPage;
lnkbtnNext.Enabled = !pds.IsLastPage;
lnkbtnPrevious.Enabled = !pds.IsFirstPage;
lnkbtnFirst.Enabled = !pds.IsFirstPage;
lnkbtnLast.Enabled = !pds.IsLastPage;
Countrydlst.DataSource = pds;
Countrydlst.DataBind();
doPaging();
}
protected void ddlPageSize_SelectedIndexChanged(object sender, EventArgs e)
{
BindGrid();
doPaging();
}
public int CurrentPage
{
get
{
if (this.ViewState["CurrentPage"] == null)
return 0;
else
return Convert.ToInt16(this.ViewState["CurrentPage"].ToString());
}
set
{
this.ViewState["CurrentPage"] = value;
}
}
private void doPaging()
{
DataTable dt = new DataTable();
dt.Columns.Add("PageIndex");
dt.Columns.Add("PageText");
for (int i = 0; i < pds.PageCount; i++)
{
DataRow dr = dt.NewRow();
dr[0] = i;
dr[1] = i + 1;
dt.Rows.Add(dr);
}
lastPage = int.Parse(dt.Rows[dt.Rows.Count - 1][0].ToString());
Pagingdlst.DataSource = dt;
Pagingdlst.DataBind();
}
protected void Pagingdlst_ItemCommand(object source, DataListCommandEventArgs e)
{
if (e.CommandName.Equals("lnkbtnPaging"))
{
CurrentPage = Convert.ToInt16(e.CommandArgument.ToString());
BindGrid();
}
}
protected void lnkbtnPrevious_Click(object sender, EventArgs e)
{
CurrentPage -= 1;
BindGrid();
}
protected void lnkbtnNext_Click(object sender, EventArgs e)
{
CurrentPage += 1;
BindGrid();
}
protected void Pagingdlst_SelectedIndexChanged(object sender, EventArgs e)
{
CurrentPage = 0;
BindGrid();
}
protected void Pagingdlst_ItemDataBound(object sender, DataListItemEventArgs e)
{
LinkButton lnkbtnPage = (LinkButton)e.Item.FindControl("lnkbtnPaging");
if (lnkbtnPage.CommandArgument.ToString() == CurrentPage.ToString())
{
lnkbtnPage.Enabled = false;
lnkbtnPage.Font.Bold = true;
}
}
protected void lnkbtnFirst_Click(object sender, EventArgs e)
{
CurrentPage = 0;
BindGrid();
}
protected void lnkbtnLast_Click(object sender, EventArgs e)
{
CurrentPage = lastPage;
BindGrid();
}
}
Tuesday, September 23, 2008
How to Export the File in to Pdf, Doc and xls Using Crystal Report
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using CrystalDecisions.Shared;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.ReportSource;
using System.IO;
public partial class _Default : System.Web.UI.Page
{
//protected CrystalDecisions.Web.CrystalReportViewer CrystalReportViewer1;
//protected System.Web.UI.WebControls.Button Button1;
ReportDocument rDoc = new ReportDocument();
protected void Page_Load(object sender, EventArgs e)
{
string FilePath = Server.MapPath("CrystalReport.rpt");
rDoc.Load(FilePath);
DataSet ds = new DataSet();
CrystalReportViewer1.ReportSource = rDoc;
CrystalReportViewer1.Visible = true;
}
protected void Button1_Click(object sender, EventArgs e)
{
MemoryStream oStream= new MemoryStream (); // using System.IO
switch (DropDownList1.SelectedItem.Text )
{
case "Pdf":
oStream = (MemoryStream)rDoc.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=SearchResult.pdf");
Response.BinaryWrite(oStream.ToArray());
Response.End();
break ;
case "Doc":
oStream = (MemoryStream)rDoc.ExportToStream(CrystalDecisions.Shared.ExportFormatType.WordForWindows);
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/doc";
Response.AddHeader("Content-Disposition", "attachment;filename=SearchResult.doc");
Response.BinaryWrite(oStream.ToArray());
Response.End();
break;
case "Excel":
oStream = (MemoryStream)rDoc.ExportToStream(CrystalDecisions.Shared.ExportFormatType.Excel);
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", "attachment;filename=SearchResult.xls");
Response.BinaryWrite(oStream.ToArray());
Response.End();
break;
}
}
}
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using CrystalDecisions.Shared;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.ReportSource;
using System.IO;
public partial class _Default : System.Web.UI.Page
{
//protected CrystalDecisions.Web.CrystalReportViewer CrystalReportViewer1;
//protected System.Web.UI.WebControls.Button Button1;
ReportDocument rDoc = new ReportDocument();
protected void Page_Load(object sender, EventArgs e)
{
string FilePath = Server.MapPath("CrystalReport.rpt");
rDoc.Load(FilePath);
DataSet ds = new DataSet();
CrystalReportViewer1.ReportSource = rDoc;
CrystalReportViewer1.Visible = true;
}
protected void Button1_Click(object sender, EventArgs e)
{
MemoryStream oStream= new MemoryStream (); // using System.IO
switch (DropDownList1.SelectedItem.Text )
{
case "Pdf":
oStream = (MemoryStream)rDoc.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=SearchResult.pdf");
Response.BinaryWrite(oStream.ToArray());
Response.End();
break ;
case "Doc":
oStream = (MemoryStream)rDoc.ExportToStream(CrystalDecisions.Shared.ExportFormatType.WordForWindows);
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/doc";
Response.AddHeader("Content-Disposition", "attachment;filename=SearchResult.doc");
Response.BinaryWrite(oStream.ToArray());
Response.End();
break;
case "Excel":
oStream = (MemoryStream)rDoc.ExportToStream(CrystalDecisions.Shared.ExportFormatType.Excel);
Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("Content-Disposition", "attachment;filename=SearchResult.xls");
Response.BinaryWrite(oStream.ToArray());
Response.End();
break;
}
}
}
Tuesday, September 16, 2008
Insert, Update, Delete with Gridview....simple way using Stored Procedure




Introduction
This is a simple way to display, Update, Delete and Insert through a single page.
This is a simple way to display, Update, Delete and Insert through a single page.
Using the code
Many of us may be encountered with Update and Delete operations with GridView. I’m explaining this with more functionality that is Inserting record through the GridView. There could me more way to achieve this functionality but I think it’s a very simple way to achieve this. I’m taking a very simple table named “quest_categories”
Many of us may be encountered with Update and Delete operations with GridView. I’m explaining this with more functionality that is Inserting record through the GridView. There could me more way to achieve this functionality but I think it’s a very simple way to achieve this. I’m taking a very simple table named “quest_categories”
CREATE TABLE [dbo].[quest_categories](
[cat_id] [int] IDENTITY(1,1) NOT NULL,
[cat_name] [varchar](150) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
CONSTRAINT [PK_quest_categories] PRIMARY KEY CLUSTERED
(
[cat_id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
[cat_id] [int] IDENTITY(1,1) NOT NULL,
[cat_name] [varchar](150) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
CONSTRAINT [PK_quest_categories] PRIMARY KEY CLUSTERED
(
[cat_id] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
Here is the Code for “Add Category”
protected void btnAdd_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings\["exam_moduleConnectionString"].ConnectionString);
SqlDataAdapter da = new SqlDataAdapter("SELECT cat_id, cat_nameFROMquest_categories",con);
DataTable dt = new DataTable();
da.Fill(dt);
// Here we'll add a blank row to the returned DataTableDataRow dr = dt.NewRow();dt.Rows.InsertAt(dr, 0);//Creating the first row of GridView to be EditableGridView1.EditIndex = 0;
// Here we'll add a blank row to the returned DataTableDataRow dr = dt.NewRow();dt.Rows.InsertAt(dr, 0);//Creating the first row of GridView to be EditableGridView1.EditIndex = 0;
GridView1.DataSource = dt;
GridView1.DataBind();//Changing the Text for Inserting a New Record((LinkButton)GridView1.Rows[0].Cells[0].Controls[0]).Text = "Insert";
}
}
And according to Text Diplays we’ll do further processing as “Update” or “Insert” record.
Here is the code for “RowUpdating” event.
Here is the code for “RowUpdating” event.
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
if (((LinkButton)GridView1.Rows[0].Cells[0].Controls[0]).Text == "Insert")
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["exam_moduleConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "INSERT INTO quest_categories(cat_name) VALUES(@cat_name)";
cmd.Parameters.Add("@cat_name", SqlDbType.VarChar).Value = ((TextBox)GridView1.Rows[0].Cells[2].Controls[0]).Text;
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
{
if (((LinkButton)GridView1.Rows[0].Cells[0].Controls[0]).Text == "Insert")
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["exam_moduleConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "INSERT INTO quest_categories(cat_name) VALUES(@cat_name)";
cmd.Parameters.Add("@cat_name", SqlDbType.VarChar).Value = ((TextBox)GridView1.Rows[0].Cells[2].Controls[0]).Text;
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Response.Redirect("quest_categories.aspx");
}
else
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["exam_moduleConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "UPDATE quest_categories SET cat_name=@cat_name WHERE cat_id=@cat_id";
cmd.Parameters.Add("@cat_name", SqlDbType.VarChar).Value = ((TextBox)GridView1.Rows[e.RowIndex].Cells[2].Controls[0]).Text;
cmd.Parameters.Add("@cat_id", SqlDbType.Int).Value = Convert.ToInt32(GridView1.Rows[e.RowIndex].Cells[1].Text);
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
GridView1.EditIndex = -1;
BindData();
}
Rest operations are same as you might have done before so I’m not explaining it further.
}
else
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["exam_moduleConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "UPDATE quest_categories SET cat_name=@cat_name WHERE cat_id=@cat_id";
cmd.Parameters.Add("@cat_name", SqlDbType.VarChar).Value = ((TextBox)GridView1.Rows[e.RowIndex].Cells[2].Controls[0]).Text;
cmd.Parameters.Add("@cat_id", SqlDbType.Int).Value = Convert.ToInt32(GridView1.Rows[e.RowIndex].Cells[1].Text);
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
GridView1.EditIndex = -1;
BindData();
}
Rest operations are same as you might have done before so I’m not explaining it further.
Wednesday, July 30, 2008
Lambda Expressions Extension Methods and LINQ in C# 3.0
The idea behind anonymous methods it to write methods inline to the code so you don't have to go through the trouble of declaring a formal named method. They are mainly used for small methods that don't require any need for reuse.
Instead of declaring a separate method IsAbe to find Abe in a list of strings:
class Program
{
static void Main(string[] args)
{
List names = new List();
names.Add("Dave");
names.Add("John");
names.Add("Abe");
names.Add("Barney");
names.Add("Chuck");
string abe = names.Find(IsAbe);
Console.WriteLine(abe);
}
public static bool IsAbe(string name)
{
return name.Equals("Abe");
}
}
You can declare an anonymous method inline to save you the trouble:
class Program
{
static void Main(string[] args)
{
List names = new List();
names.Add("Dave");
names.Add("John");
names.Add("Abe");
names.Add("Barney");
names.Add("Chuck");
string abe = names.Find(delegate(string name)
{
return name.Equals("Abe");
});
Console.WriteLine(abe);
}
}
It can get a lot fancier than that, but that is basically the gist. Declare the method inline to the code for easy stuff not needing reuse, because it saves some typing and puts the method closer to where it is being used which helps with maintenance.
Lambda Expressions
Lambda Expressions make things even easier by allowing you to avoid the anonymous method and that annoying statement block:
class Program
{
static void Main(string[] args)
{
List names = new List();
names.Add("Dave");
names.Add("John");
names.Add("Abe");
names.Add("Barney");
names.Add("Chuck");
string abe = names.Find((string name)
=> name.Equals("Abe"));
Console.WriteLine(abe);
}
}
Because Lambda Expressions are smart enough to infer variable types, I don't even have to explicity mention that name is a string above. I can remove it for even more simplicity and write it as such:
class Program
{
static void Main(string[] args)
{
List names = new List();
names.Add("Dave");
names.Add("John");
names.Add("Abe");
names.Add("Barney");
names.Add("Chuck");
string abe = names.Find(name =>
name.Equals("Abe"));
Console.WriteLine(abe);
}
}
Now there is no particular reason why I have to use name as my variable. Often developers will use 1 character variable names in Lambda Expressions just to keep things short. Here we replace name with p and all works the same.
class Program
{
static void Main(string[] args)
{
List names = new List();
names.Add("Dave");
names.Add("John");
names.Add("Abe");
names.Add("Barney");
names.Add("Chuck");
string abe = names.Find(p => p.Equals("Abe"));
Console.WriteLine(abe);
}
}
Lambda Expressions Using a Customer Class
I used a list of strings above, but you can just as easily use a list of objects to do the same thing. I will take an abbreviated form of a Customer Class:
public class Customer
{
public int Id;
public string Name;
public string City;
public Customer(int id, string name, string city)
{
Id = id;
Name = name;
City = city;
}
}
and now use Lambda Expressions to find a particular Customer with a name of "Abe".
class Program
{
static void Main(string[] args)
{
List customers = new List();
customers.Add(new Customer(1,"Dave","Sarasota"));
customers.Add(new Customer(2,"John","Tampa"));
customers.Add(new Customer(3,"Abe","Miami"));
Customer abe = customers.Find(c =>
c.Name.Equals("Abe"));
}
}
Again, we could make things more obvious by explicity saying that c is of type Customer, but I wouldn't bet on many people doing it :) You could write the above as follows:
class Program
{
static void Main(string[] args)
{
List customers = new List();
customers.Add(new Customer(1,"Dave","Sarasota"));
customers.Add(new Customer(2,"John","Tampa"));
customers.Add(new Customer(3,"Abe","Miami"));
Customer abe = customers.Find((Customer c) =>
c.Name.Equals("Abe"));
}
}
Combining Extension Methods and Lambda Expressions for Help In Finding Our Customer
Let's say we have a custom CustomerCollection Class not within our control that doesn't provide us an easy way to find a Customer:
public class CustomerCollection :
IEnumerable
{
IEnumerable _customers;
public CustomerCollection(IEnumerable
customers)
{
_customers = customers;
}
public IEnumerator GetEnumerator()
{
foreach (Customer customer in _customers)
yield return customer;
}
System.Collections.IEnumerator System.Collections
.IEnumerable.GetEnumerator()
{
return _customers.GetEnumerator();
}
}
Let's add an Extension Method to the CustomerCollection Class, called GetCustomer:
public static class CustomerExtensions
{
public static Customer GetCustomer(this
CustomerCollection customers,
Predicate isMatch)
{
foreach (Customer customer in customers)
if (isMatch(customer))
return customer;
return null;
}
}
And now, we can use the CustomerCollection Class to easily find Abe like:
class Program
{
static void Main(string[] args)
{
CustomerCollection collection = GetCustomers();
// Using my GetCustomer Method Extension...
Customer abe = collection.GetCustomer(c =>
c.Name.Equals("Abe"));
}
// Pretend We Don't See This :)
static CustomerCollection GetCustomers()
{
List customers = new List();
customers.Add(new Customer(1,"Dave","Sarasota"));
customers.Add(new Customer(2,"John","Tampa"));
customers.Add(new Customer(3,"Abe","Miami"));
return new CustomerCollection(customers);
}
}
But This Is LINQ!
But, of course, since CustomerCollection implements IEnumerable, in this case, IEnumerable, screw the Extension Methods and just use LINQ:
class Program
{
static void Main(string[] args)
{
CustomerCollection collection = GetCustomers();
// LINQ
var abe = collection.Single(c =>
c.Name.Equals("Abe"));
}
// Pretend We Don't See This :)
static CustomerCollection GetCustomers()
{
List customers = new List();
customers.Add(new Customer(1,"Dave","Sarasota"));
customers.Add(new Customer(2,"John","Tampa"));
customers.Add(new Customer(3,"Abe","Miami"));
return new CustomerCollection(customers);
}
}
Instead of declaring a separate method IsAbe to find Abe in a list of strings:
class Program
{
static void Main(string[] args)
{
List
names.Add("Dave");
names.Add("John");
names.Add("Abe");
names.Add("Barney");
names.Add("Chuck");
string abe = names.Find(IsAbe);
Console.WriteLine(abe);
}
public static bool IsAbe(string name)
{
return name.Equals("Abe");
}
}
You can declare an anonymous method inline to save you the trouble:
class Program
{
static void Main(string[] args)
{
List
names.Add("Dave");
names.Add("John");
names.Add("Abe");
names.Add("Barney");
names.Add("Chuck");
string abe = names.Find(delegate(string name)
{
return name.Equals("Abe");
});
Console.WriteLine(abe);
}
}
It can get a lot fancier than that, but that is basically the gist. Declare the method inline to the code for easy stuff not needing reuse, because it saves some typing and puts the method closer to where it is being used which helps with maintenance.
Lambda Expressions
Lambda Expressions make things even easier by allowing you to avoid the anonymous method and that annoying statement block:
class Program
{
static void Main(string[] args)
{
List
names.Add("Dave");
names.Add("John");
names.Add("Abe");
names.Add("Barney");
names.Add("Chuck");
string abe = names.Find((string name)
=> name.Equals("Abe"));
Console.WriteLine(abe);
}
}
Because Lambda Expressions are smart enough to infer variable types, I don't even have to explicity mention that name is a string above. I can remove it for even more simplicity and write it as such:
class Program
{
static void Main(string[] args)
{
List
names.Add("Dave");
names.Add("John");
names.Add("Abe");
names.Add("Barney");
names.Add("Chuck");
string abe = names.Find(name =>
name.Equals("Abe"));
Console.WriteLine(abe);
}
}
Now there is no particular reason why I have to use name as my variable. Often developers will use 1 character variable names in Lambda Expressions just to keep things short. Here we replace name with p and all works the same.
class Program
{
static void Main(string[] args)
{
List
names.Add("Dave");
names.Add("John");
names.Add("Abe");
names.Add("Barney");
names.Add("Chuck");
string abe = names.Find(p => p.Equals("Abe"));
Console.WriteLine(abe);
}
}
Lambda Expressions Using a Customer Class
I used a list of strings above, but you can just as easily use a list of objects to do the same thing. I will take an abbreviated form of a Customer Class:
public class Customer
{
public int Id;
public string Name;
public string City;
public Customer(int id, string name, string city)
{
Id = id;
Name = name;
City = city;
}
}
and now use Lambda Expressions to find a particular Customer with a name of "Abe".
class Program
{
static void Main(string[] args)
{
List
customers.Add(new Customer(1,"Dave","Sarasota"));
customers.Add(new Customer(2,"John","Tampa"));
customers.Add(new Customer(3,"Abe","Miami"));
Customer abe = customers.Find(c =>
c.Name.Equals("Abe"));
}
}
Again, we could make things more obvious by explicity saying that c is of type Customer, but I wouldn't bet on many people doing it :) You could write the above as follows:
class Program
{
static void Main(string[] args)
{
List
customers.Add(new Customer(1,"Dave","Sarasota"));
customers.Add(new Customer(2,"John","Tampa"));
customers.Add(new Customer(3,"Abe","Miami"));
Customer abe = customers.Find((Customer c) =>
c.Name.Equals("Abe"));
}
}
Combining Extension Methods and Lambda Expressions for Help In Finding Our Customer
Let's say we have a custom CustomerCollection Class not within our control that doesn't provide us an easy way to find a Customer:
public class CustomerCollection :
IEnumerable
{
IEnumerable
public CustomerCollection(IEnumerable
customers)
{
_customers = customers;
}
public IEnumerator
{
foreach (Customer customer in _customers)
yield return customer;
}
System.Collections.IEnumerator System.Collections
.IEnumerable.GetEnumerator()
{
return _customers.GetEnumerator();
}
}
Let's add an Extension Method to the CustomerCollection Class, called GetCustomer:
public static class CustomerExtensions
{
public static Customer GetCustomer(this
CustomerCollection customers,
Predicate
{
foreach (Customer customer in customers)
if (isMatch(customer))
return customer;
return null;
}
}
And now, we can use the CustomerCollection Class to easily find Abe like:
class Program
{
static void Main(string[] args)
{
CustomerCollection collection = GetCustomers();
// Using my GetCustomer Method Extension...
Customer abe = collection.GetCustomer(c =>
c.Name.Equals("Abe"));
}
// Pretend We Don't See This :)
static CustomerCollection GetCustomers()
{
List
customers.Add(new Customer(1,"Dave","Sarasota"));
customers.Add(new Customer(2,"John","Tampa"));
customers.Add(new Customer(3,"Abe","Miami"));
return new CustomerCollection(customers);
}
}
But This Is LINQ!
But, of course, since CustomerCollection implements IEnumerable
class Program
{
static void Main(string[] args)
{
CustomerCollection collection = GetCustomers();
// LINQ
var abe = collection.Single(c =>
c.Name.Equals("Abe"));
}
// Pretend We Don't See This :)
static CustomerCollection GetCustomers()
{
List
customers.Add(new Customer(1,"Dave","Sarasota"));
customers.Add(new Customer(2,"John","Tampa"));
customers.Add(new Customer(3,"Abe","Miami"));
return new CustomerCollection(customers);
}
}
Tuesday, July 29, 2008
When ASP.NET hit the street a couple of years ago, it was a real eye-opener. Microsoft's tool for creating dynamic, server side web applications introduced Web Forms, a feature with the same rapid drag and drop convenience enjoyed by Visual Basic developers, along with a method for creating XML-based web services. ASP.NET was more than an upgrade of Active Server Pages it was a quantum leap ahead. Now Microsoft has a new version of ASP.NET as part of its upcoming next generation release of the Visual Studio .NET development platform. ASP.NET 2.0 is already available in beta release, and web developers are anxious to get a good look at it. That's exactly what our new Developer's Notebook allows you to do. More than just an introduction to ASP.NET 2.0, this practical guide acquaints you with all of the new features through nearly 50 hands-on projects. Each one places emphasis on changes in the new release that can increase productivity, simplify programming tasks, and help you add functionality to your applications. For example, ASP.NET 2.0 includes master pages, themes, and skins so you can build applications with a consistent page layout and design. Other changes allow for the automatic creation of web pages for use on mobile devices, while wizards and controls allow you to perform frequent tasks (like data access) without having to write a single line of code. ASP.NET 2.0: A Developer's Notebook also includes suggestions for further experimentation, links to on-line documentation, and practical notes and warnings from the author regarding changes to the new version. The new Developer's Notebooks series from O'Reilly offers an in-depth first look at important new tools for software developers. Emphasizing example over explanation and practice over theory, they focus on learning by doing you'll get the goods straight from the masters, in an informal and code-intensive style. If you want to get up to speed on ASP.NET 2.0 before its official release, this all lab, no lecture book will get you there.
Subscribe to:
Posts (Atom)