Wednesday, December 17, 2008

Using dropdownlist in user control and to access the dropdownlist control value in .aspx page

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!

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.

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.

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.

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.