Monday, March 03, 2008

C#: using Timespan to caluculate the total of hours worked based on start and end times, as well as a pause

recently, I came acroos the need to get the total hours in sql. by using the CLR user defined functions freature, I was able to use this function into SQL server. The nice thing, is that I unit tested the function seperately, then used it. example :

SQL:

select dbo.GetTotalHours(TableName.StartTime, TableName.EndTime, TableName.Pause) as TotalHoursWorked;



The function is listed below with comments. also, below is a function for splitting the hour string.




example : GetTotalHours("20:00", "06:00", 120); Important: the pause is expressed in minutes (in this case, it's 120 minutes pause, or 2 hours of pause).







This function, inside an sql server project is created with the sql server attribute of [SqlFunction]. This tells sql server to execute this function
as an extension to sql server, which will make it run as any other sql function.







[Microsoft.SqlServer.Server.SqlFunction]
public
string GetTotalHours(string StartTime, string EndTime, int Pause)
{

if (StartTime == EndTime)
{
if ((StartTime == null) || (EndTime == null) || (StartTime == "00:00") || (EndTime == "00:00"))
{
StartTime = "0:0";
EndTime = "0:0";


return "00:00";
}
}
//this split gives the following example StartTime 10:30 Start[0] gives 10 and start[1] gives 30
string[] Start = this.SplitTimeString(StartTime);
string[] End = this.SplitTimeString(StartTime);


//timespan for the taking into consideration intervals similar to :
//starttime: 20:00 and endtime 01:30
TimeSpan tsTwentyFourHours = new TimeSpan(24, 0, 0);
//start time
TimeSpan tsStart = new TimeSpan(int.Parse(Start[0]), int.Parse(Start[1]), 0);
//end time
TimeSpan tsEnd = new TimeSpan(int.Parse(End[0]), int.Parse(End[1]), 0);

TimeSpan tsPause = new TimeSpan(0, Pause, 0);
TimeSpan tsHoursWorked;

if (int.Parse(End[0]) < int.Parse(Start[0]))
{
//Case when the it's overnight work like 20:00 to 01:30

//we substract start time from twenty for hours, then add the end time.
//this gives us the correct measures
tsHoursWorked = tsTwentyFourHours.Subtract(tsStart).Add(tsEnd);
//substratct the pause
tsHoursWorked = tsHoursWorked.Subtract(tsPause);
}
else
{
//normal hours example: 08:00 to 20:00
//we simply substract the start time plus the pause from the end time
tsHoursWorked = tsEnd.Subtract(tsStart.Add(tsPause));
}


return tsHoursWorked.TotalHours.ToString() + ":" + tsHoursWorked.TotalMinutes.ToString();
}





This function is used in the function above.







public string[] SplitTimeString(string Time)
{
char[] ch = new char[] { ':', '.' };
return Time.Split(ch);
}




in the next article, will see how this function can be used upgraded to be used in sql server 2008, taking advantage of its Time datatype, using Visual Studio 2010 beta version.

Comments are welcome !

Thursday, February 14, 2008

Enabling Diagram support (database schema creation) in SQL Server 2005

Diagram support for attached or backed up databases.

The solution has been put on this blog a while ago (nice post). I have tried searching before, yet, a few days ago, I search with one of my collegues, and found that this blog is very helpful on that. The reason for this post, is just to add another link on google, that gives somewhat a confirmed solution on this issue.

http://geekswithblogs.net/timh/archive/2006/07/05/84171.aspx

I tried what was suggested in the above blog, did not work for me at first (it worked for others). but what did work for me is the following reply on that same post :

Begining quote from the post above

# re: Cannot add diagram to SQL Server 2005 DB: Database diagram support objects cannot be installed because this database does not have a valid owner. 8/16/2006 9:39 AM Julius

I tried the above mentioned solution but still was not working and displaying the same error message - if you got the same error as me then just try the follwing lines in SQL Query:

EXEC sp_dbcmptlevel 'dbname', '90'; 
ALTER AUTHORIZATION ON DATABASE::dbname TO valid_login



 



End Quote From the blog post above



Comments are welcome

Thursday, February 07, 2008

asp.net 2.0 Roles DropDownList Control in C#

Translation of this post to french at :
http://s4n44.blogspot.com/2008/02/aspnet-20-dropdownlist-de-rles-enc.html

This is a user control, which encapsulates a DropDownList, an ObjectDataSource and custom, simplified roles class. The user control will connect automatically (of course), with the aspnetdb database pointed to in the web.config
for vb.net users, here's a nice converter provided by Telerik (http://www.telerik.com ) :
http://www.codechanger.com/

Here's the code for the user control :

<%@ Control Language="C#" AutoEventWireup="true" CodeFile=" ddlRoles.ascx.cs" Inherits="RoleControl" %>
<asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="sourceRoles" DataTextField="RoleName"
DataValueField="RoleName" Width="185px">
</asp:DropDownList>
<asp:ObjectDataSource ID="sourceRoles" runat="server" SelectMethod="GetRoles"
TypeName="CustomRoles"></asp:ObjectDataSource>


Code behind for the user control:


using System;

public partial class RoleControl : System.Web.UI.UserControl
{
public String SelectedValue
{
get { return this.DropDownList1.SelectedValue; }
set { this.DropDownList1.SelectedValue = value; }
}
}


The object datasource uses the class below :


using System;
using System.Web.Security;
using System.Collections.Generic;

public class CustomRoles
{
private string mRoleName;

public string RoleName
{
get { return mRoleName; }
set { mRoleName = value; }
}

/// <summary>
/// this function, loops through all roles in the database, and builds
/// a collection of CustomRoles instances into a generic list of CustomRoles
/// then we return the list as the source for the dropdown.
/// The RoleName property is used to bind the datavaluefield and datatextfield
/// in the dropdownlist
/// </summary>
/// <returns></returns>
public List<CustomRoles> GetRoles()
{
//getroles
string[] roleslist = Roles.GetAllRoles();

int i = 0;
//instance of customroles
CustomRoles br;

//create the list (or collection of CustomRoles instances)
List<CustomRoles> lstbr = new List<CustomRoles>();

//fill the list by looping through the array of strings
foreach (string brole in roleslist)
{
br = new CustomRoles();
br.RoleName = brole;
lstbr.Add(br);
}

return lstbr;

}

}


Comments are welcome !

Tuesday, January 15, 2008

asp.net 2.0 and up: DropDownList in GridView (using SQLDataSource)

To have a dropdownlist inside a gridview, we use the property "SelectedValue='<%# Eval("datakeyfield") %>' knowing that it won't show in the intellisense. To handle null values, we can have an item with a value of null. The SQLDataSource for the dropdownlist is better off put outside the gridview, so that it does not get created as many times as the dropdownlist is.

Here's the code for the DropDownList Template Field :
The Dropdownlist is Filled From a table called Categories (see schema below)

<asp:TemplateField HeaderText="Category" SortExpression="CategoryID">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="SourceCategories"
AppendDataBoundItems="true" DataTextField="CategoryName" DataValueField="CategoryID"
Width="190px" Enabled="false" SelectedValue='<%# Eval("CategoryID") %>'>
<asp:ListItem Text="No Item was Selected, to handle null values" Value="" />
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>



In the code above, Notice the property SelectedValue, and the static Item to handle null values. to this, we add the AppendDataBoundItems Property, and the dropdownlist is ready.


Here's the complete code listing with a functional gridview:





The GridView is filled from a table Called Clients (see schema below)



<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4"
DataSourceID="SourceClients" ForeColor="#333333" GridLines="Both" Font-Names="Verdana"
Font-Size="10px" AllowSorting="true">
<Columns>
<asp:BoundField DataField="ClientID" HeaderText="ClientID" InsertVisible="False"
ReadOnly="True" SortExpression="ClientID" />
<asp:BoundField DataField="FullName" HeaderText="FullName" SortExpression="FullName" />
<asp:TemplateField HeaderText="Category" SortExpression="CategoryID">
<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="SourceCategories"
AppendDataBoundItems="true" DataTextField="CategoryName" DataValueField="CategoryID"
Width="190px" Enabled="false" SelectedValue='<%# Eval("CategoryID") %>'>
<asp:ListItem Text="No Item was Selected, to handle null values" Value="" />
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>


</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SourceClients" runat="server" ConnectionString="<%$ ConnectionStrings:ClientsConnectionString %>"
SelectCommand="SELECT * FROM [Clients]"></asp:SqlDataSource>
<asp:SqlDataSource ID="SourceCategories" runat="server" ConnectionString="<%$ ConnectionStrings:ClientsConnectionString %>"
SelectCommand="SELECT * FROM [Categories]"></asp:SqlDataSource>
</div>


Here's are the table definitions: (int and varchar(50) are the datatypes used)


image


Screen Shot for the gridview


image


Comments are welcome

Friday, January 11, 2008

asp.net 2.0 : Handling Null values for checkbox columns wihout loosing the Bind expression (works for GridView and FormView)

 

I looked for this for a while (the ability to keep Bind(""), not Eval("") and Also to be able to do the check for null outside the grid, and found this technique helpful:
        Put the checkbox control inside a user control, and handle the null values inside it. works like a charm.

Here's a link to the solution where I initially found it:

http://www.telerik.com/community/forums/thread/b311D-ctttt.aspx
look for the last 3 posts to this forum page (Fabian Schulz)

To go a little further, Here's the download for the source code of the CheckBox User Controls.
CheckBoxUserControl download

Here's a sample of what the code should look like :

The EditItemTemplate is missing, but can have the same code as the ItemTemplate, since the InvalidCastException is handled by checking for null values inside the checkbox user control.  (I will update this post with an EditItemTemplate).

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<%@ Register Src="DataEntryControls/CheckBoxControl.ascx" TagName="CheckBoxControl"
TagPrefix="uc1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4"
DataSourceID="SqlDataSource1" GridLines="None">
<Columns>
<asp:BoundField DataField="ClientID" HeaderText="ClientID" InsertVisible="False"
ReadOnly="True" SortExpression="ClientID" />
<asp:BoundField DataField="FullName" HeaderText="FullName" SortExpression="FullName" />
<asp:TemplateField HeaderText="IsValid">
<ItemTemplate>
<uc1:CheckBoxControl ID="CheckBoxControl1" runat="server" Checked='<%# Bind("IsValid") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ClientsConnectionString %>"
SelectCommand="SELECT * FROM [Clients]"></asp:SqlDataSource>
</form>
</body>
</html>

The ascx has no code behind but the page load.


As for the table, it's very simple. ClientID int auto, FullName varchar(50) and IsValid int or bit


Here's is the source code for the CheckBox Control :


CheckBoxControl.ascx:



<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CheckBoxControl.ascx.cs" Inherits="Controls_DataEntryControls_CheckBoxControl" %>
<asp:CheckBox ID="CheckBox1" runat="server" />



CheckBoxControl.ascx.cs




using System;
public partial class Controls_DataEntryControls_CheckBoxControl : System.Web.UI.UserControl
{
private bool m_checked = false;
protected void Page_Load(object sender, EventArgs e)
{
m_checked = CheckBox1.Checked;
}
public object Checked
{
get { return m_checked; }
set
{
if (value.GetType() == DBNull.Value.GetType()) m_checked = false;
else if (value == null) m_checked = false;
else if (value.GetType() == typeof(bool)) m_checked = (bool)value;
else m_checked = false;
}
}
protected void Page_PreRender()
{
CheckBox1.Checked = m_checked;
}
}

Comments are welcome


This technique is based on the fact that handling null values is the concern of the control itself, not the gridview of formview, since the control forces a specific data type for its property. I beleive we could say that this is a good application of the seperation of concern pattern in asp.net.

Saturday, January 05, 2008

asp.net 2.0 : TextBox User Control with TextChanged Event (Event Bubbling from user controls)

including a textbox in a user control can save a lot of messy code in a form, as well as encapsulate validation and other functionalities (such as ajax calendar functionality). A small challenge though, it's bubbling the textchanged event from the TextBox to the top

Here's a link to a sample website with an aspx page and the TextBox user control in it :

>> TextBox Changed Event in a user control sample

Code :

TextBox User Control :

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="TextBox.ascx.cs" Inherits="Controls_ReferenceData_ChiffresTextBox" %>
<asp:TextBox ID="TextBox1" runat="server" CssClass="champ" /><br />
<asp:RequiredFieldValidator ID="RequeiredFieldValidator1" runat="server" ControlToValidate="TextBox1"
ErrorMessage="This Field is Required" Display="Dynamic" />



Code Behind :




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;

public partial class Controls_ReferenceData_ChiffresTextBox : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{

}

public string Text
{
get { return this.TextBox1.Text; }
set { this.TextBox1.Text = value; }
}

public bool AutoPostBack
{
get { return TextBox1.AutoPostBack; }
set { TextBox1.AutoPostBack = value; }
}

#region "Other properties"
public bool EnabledRfv
{
get { return this.RequeiredFieldValidator1.Enabled; }
set { this.RequeiredFieldValidator1.Enabled = value; }
}


#endregion

protected override void OnInit(EventArgs e)
{
this.TextBox1.TextChanged += new EventHandler(TextBox1_TextChanged);
base.OnInit(e);
}

void TextBox1_TextChanged(object sender, EventArgs e)
{
OnBubbleTextChanged(e);
}

public event EventHandler BubbleTextChanged;

protected void OnBubbleTextChanged(EventArgs e)
{
if (BubbleTextChanged != null)
BubbleTextChanged(this, e);

}


}



 



For Implementation in an aspx page, here's what the code looks like:



Register tag




<%@ Register Src="Controls/DataEntryControls/TextBox.ascx" TagName="TextBox" TagPrefix="uc1" %>



 


Control's tag



<uc1:TextBox ID="TextBox1" runat="server" AutoPostBack="true" OnBubbleTextChanged="OnTextChanged" />



 



Code Behind




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;

public partial class TextBoxWithTextChange : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}
protected void OnTextChanged(object sender, EventArgs e)
{
Response.Write(this.TextBox1.Text);
}

}



in the code behind, we create the method OnTextChanged to handle the event. This sample I picked out from a blog, and added the possiblity to add properties. Sadly, I search and can't find it easily, so I prefered to post something similar, for more search results regarding the textchanged event bubbling from a user conrol subject.



The TextChanged event does not show in the list of events for the user control. something to think about, otherwise, this technique makes it easy to develop such a functionality.



Comments are welcome.

A User Interface Data Binding Overview in asp.net

Granularity (one field, one control) :

A definition of databing could be having a link between the field in the datasource and a control.

When we talk about data binding, the first thing that should come to mind, is that we are binding fields to controls. In more detail, when we use a GridView to bind it to a table, in fact we are binding each field in the database to a specific control, present in the form of a collection, which makes us say, we are binding a table to the grid, while the granular aspect of it is that we are binding many fields to many controls.

Binding Scripting Syntax for Grids, Datalists, Formviews and detailviews:

Two way binding (very popular)

<%
   1: # Bind("fieldname") 
%>



One way Binding (ReadOnly)




<%
   1: # Eval("fieldname") 
%>


Another one is :


<%
   1: # DataBinder.Eval(Container.DataItem, "fieldname") 
%>



 



This are helper Functions. Here's how they work :



when we have a textbox inside a TemplateField, in a Gridview : We have the following Syntax :




<TemplateField>
<EditItemTemplate>
<asp:TextBox id="txtName" runat="server" Text='<%# Bind("Name") %>' />
</EditItemTemplate>
</TemplateField>



In fact, The Bind Method is executed during the ItemDataBound Event (one popular event in the 1.1 DataGrid control used to initilize child controls in a GridView). The Bind method helps not having to write code behind syntax to bind each field during insert and update.


 


Best Practices using the SqlDataSource Control :


If we notice, using SQLDataSource, (note : thanks Adnane for the tip), there's a property named DataSourceMode :


This property is really great, since it gives us DataSet Mode and DataReader Mode. DataSet Mode is set by default, nice, that way The paging and sorting can work by default.


 


image


 


When to change the DataSourceMode property:


For better use, there' no need in using the default mode to fill a DropDownList or a ListBox, instead we choose DataReader Mode, which will be of course more efficient.


 


For differences between DataReader and DataSet, please take a look at a previous post (DataSet vs DataReader). this post includes links to msdn explaining the difference, as well as giving a breif overview of the difference.


 


Comments are welcome

Wednesday, December 26, 2007

asp.net Show Details of a gridview row using the modalpopupextender: elegant, quick and efficient (without the modal effect)

the modalpopupextender is within the gridview

Here's the gridview :

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4"
DataKeyNames="ClientID" DataSourceID="SqlSourceClientsGrid" GridLines="None"
Font-Names="Verdana" Font-Size="10px" ForeColor="#333333">
<Columns>
<asp:BoundField DataField="ClientID" HeaderText="ClientID" InsertVisible="False"
ReadOnly="True" SortExpression="ClientID" />
<asp:BoundField DataField="FullName" HeaderText="FullName" SortExpression="FullName" />
<asp:BoundField DataField="IsValid" HeaderText="IsValid" SortExpression="IsValid" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton CommandArgument='<%# Eval("FullName") %>' ID="lnkDetails" runat="server"
Text="Details" />
<ajaxToolkit:ModalPopupExtender runat="server" ID="popupDetails" TargetControlID="lnkDetails"
PopupControlID="pnlDetails" PopupDragHandleControlID="pnlHandle" CancelControlID="CancelButton" />
<asp:Panel runat="server" ID="pnlDetails" Style="display: none; background-color: #666666">
<asp:Panel ID="pnlHandle" runat="server" Style="cursor: move;" Width="200px">
<table width="100%" cellpadding="0" cellspacing="0" style="border: solid 1px #666666;">
<tr>
<td style="background-image: url(Images/GridHeaderBg.gif)">
Inspections
</td>
<td style="background-image: url(Images/GridHeaderBg.gif); text-align: right;">
<asp:Button ID="CancelButton" runat="server" Text="Close" />
</td>
</tr>
</table>
</asp:Panel>
<div id="divDetails" style="background-color: #FFFFFF; border: solid 1px gray">

<table>
<tr>
<td>
FullName :
</td>
<td>
<%
   1: # Eval("FullName") 
%>
</td>
</tr>
<tr>
<td>
Is Valid :
</td>
<td>
<%
   1: # Eval("IsValid") 
%>
</td>
</tr>
</table>
</div>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<RowStyle BackColor="#EFF3FB" />
<PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<EditRowStyle BackColor="#2461BF" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>



The most important port of the code, is the Template Field Below is its code :




<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton CommandArgument='<%# Eval("FullName") %>' ID="lnkDetails" runat="server"
Text="Details" />
<ajaxToolkit:ModalPopupExtender runat="server" ID="popupDetails" TargetControlID="lnkDetails"
PopupControlID="pnlDetails" PopupDragHandleControlID="pnlHandle" CancelControlID="CancelButton" />
<asp:Panel runat="server" ID="pnlDetails" Style="display: none; background-color: #666666">
<asp:Panel ID="pnlHandle" runat="server" Style="cursor: move;" Width="200px">
<table width="100%" cellpadding="0" cellspacing="0" style="border: solid 1px #666666;">
<tr>
<td style="background-image: url(Images/GridHeaderBg.gif)">
Inspections
</td>
<td style="background-image: url(Images/GridHeaderBg.gif); text-align: right;">
<asp:Button ID="CancelButton" runat="server" Text="Close" />
</td>
</tr>
</table>
</asp:Panel>
<div id="divDetails" style="background-color: #FFFFFF; border: solid 1px gray">

<table>
<tr>
<td>
FullName :
</td>
<td>
<%
   1: # Eval("FullName") 
%>
</td>
</tr>
<tr>
<td>
Is Valid :
</td>
<td>
<%
   1: # Eval("IsValid") 
%>
</td>
</tr>
</table>
</div>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>



The code in the template field contains, the modalpopupextender as well as the panels and buttons related to it. this makes it a great details window.



Here's the complete code listing:




<%@ Page Language="C#" AutoEventWireup="true" CodeFile="ModalPopupExtenderDemo.aspx.cs"
Inherits="ModalPopupExtenderDemo" %>


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Modal Popup Extender Demo</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager runat="server" ID="script1" />
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4"
DataKeyNames="ClientID" DataSourceID="SqlSourceClientsGrid" GridLines="None"
Font-Names="Verdana" Font-Size="10px" ForeColor="#333333">
<Columns>
<asp:BoundField DataField="ClientID" HeaderText="ClientID" InsertVisible="False"
ReadOnly="True" SortExpression="ClientID" />
<asp:BoundField DataField="FullName" HeaderText="FullName" SortExpression="FullName" />
<asp:BoundField DataField="IsValid" HeaderText="IsValid" SortExpression="IsValid" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton CommandArgument='<%# Eval("FullName") %>' ID="lnkDetails" runat="server"
Text="Details" />
<ajaxToolkit:ModalPopupExtender runat="server" ID="popupDetails" TargetControlID="lnkDetails"
PopupControlID="pnlDetails" PopupDragHandleControlID="pnlHandle" CancelControlID="CancelButton" />
<asp:Panel runat="server" ID="pnlDetails" Style="display: none; background-color: #666666">
<asp:Panel ID="pnlHandle" runat="server" Style="cursor: move;" Width="200px">
<table width="100%" cellpadding="0" cellspacing="0" style="border: solid 1px #666666;">
<tr>
<td style="background-image: url(Images/GridHeaderBg.gif)">
Inspections
</td>
<td style="background-image: url(Images/GridHeaderBg.gif); text-align: right;">
<asp:Button ID="CancelButton" runat="server" Text="Close" />
</td>
</tr>
</table>
</asp:Panel>
<div id="divDetails" style="background-color: #FFFFFF; border: solid 1px gray">

<table>
<tr>
<td>
FullName :
</td>
<td>
<%
   1: # Eval("FullName") 
%>
</td>
</tr>
<tr>
<td>
Is Valid :
</td>
<td>
<%
   1: # Eval("IsValid") 
%>
</td>
</tr>
</table>
</div>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<RowStyle BackColor="#EFF3FB" />
<PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<EditRowStyle BackColor="#2461BF" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
<asp:SqlDataSource ID="SqlSourceClientsGrid" runat="server" ConnectionString="<%$ ConnectionStrings:ClientsConnectionString %>"
DeleteCommand="spDeleteClients" DeleteCommandType="StoredProcedure" SelectCommand="spGetClients"
SelectCommandType="StoredProcedure">
<DeleteParameters>
<asp:Parameter Name="ClientID" Type="Int32" />
</DeleteParameters>
</asp:SqlDataSource>
</div>
</form>
</body>
</html>



I'll put the code up for the download soon.



here's the database table used for samples:



image



the ModalPopupExtender makes it a great and easy way to show the details of a row. Here's a screen shot for what it looks like :



image


Comments are welcome