Monday, May 25, 2009

Gridview operations

Gridview control is one of the easiest, fastest and most flexible control to work with. But it does not come without it’s complexity, considering the amount of features it exposes

Objectives
1. Associate Datasource with Gridview ( objectdatasource and programmatically)
2. Customize display columns
3. Associate a detailed view with Gridview (through ObjectDatasource)
4. Show and Hide cells in Gridview

Associate Datasource with Gridview
To start with, there are different ways to bind the data source.
1. Use ObjectDatasource
2. Code to bind the datasource

Using ObjectDataSource
1. Create an object Datasource in the aspx page, select the type of object used as a datasource
2. Associate the function that will return the associated type. You are all set with the datasource
3. Next step is to associate the objectdatasource with Gridview

Here’s the sample code for the same
<asp:ObjectDataSource ID="os1" runat="server" TypeName="sample.FeedbackInfo"
SelectMethod="doList">
</asp:ObjectDataSource>


Association with Gridview
<asp:GridView ID="grdFeedbackList" runat="server" AllowPaging="True"
DataKeyNames="FeedbackId" AutoGenerateColumns="False"
DataSourceID="os1"
/>


If you decide to do the same through code without using object datasource, one place to do such initializations can be page_load method

FeedbackInfo fInfo = new FeedbackInfo();
grdFeedbackList.DataSource = fInfo.doList();
grdFeedbackList.DataBind();


Having now associated the datasource with the gridview, you may wish a finer level of control.

Decide on the columns to show in gridview.
Say, if the FeedbackInfo table returns the following information
Feedback ID, physician ID, Physician Name, patient Id, Patient Name, feedback Text, Attchments, Feedback Time stamp and Read time stamp. We may not be interested in all the columns. To filter the columns there are different approches
Associate appropriate view for the query
Use Databound columns to select the columns to be displayed

Using appropriate views can be an easy solution, so I’ll move on to the next option

Customize display columns

<asp:GridView ID="grdFeedbackList" runat="server" AllowPaging="True"
DataKeyNames="FeedbackId" AutoGenerateColumns="False"
DataSourceID="os1"
/>
<Columns>
<asp:BoundField DataField="FeedbackId" HeaderText="Feedback Id" SortExpression="FeedbackId" />
<asp:BoundField DataField="PhysicianId" HeaderText="Physician Id" SortExpression="PhysicianId" />
<asp:BoundField DataField="PhysicianName" HeaderText="Physician Name" SortExpression="PhysicianName" />
<asp:BoundField DataField="Speciality" HeaderText="Speciality" SortExpression="Speciality" />
<asp:BoundField DataField="PatientId" HeaderText="Patient Id" SortExpression="PatientId" />
<asp:BoundField DataField="PatientName" HeaderText="Patient Name" SortExpression="PatientName" />
</Columns>
<asp:GridView />


DataField is the field that comes out of the collection. If the collection happens to be a field from ActiveTable/ActiveRecord data pattern then use the field name defined. Or if the field is directly coming out of the DB, use the field name in the DB table.

Sort Expression is property allows you to sort on that column. This is completely managed by Gridview, if you want to override it, feel free.

If you want to associate a Detailed view to Gridview it’s even more easy
Create a new ObjectDatasource and associate the DataKeyName of gridview with the new Datasource along with type and select properties
Here’s the sample

<asp:ObjectDataSource ID="os2" runat="server"
TypeName="Novi.Common.entity.FeedbackInfo"
SelectMethod="GetFeedbackInfo" OnSelected="os2_Selected">
<SelectParameters>
<asp:ControlParameter Name="lFeedbackId" Type="Int64"
ControlID="grdFeedbackList"
PropertyName="SelectedValue" />
</SelectParameters>
</asp:ObjectDataSource>


As expected we have set the regular properties like ID, TypeName, SelectMethd for the ObjectDatasource. As Os2 should select the detialed information of the record selected in gridview, we should know the selected item in grid view. This association happens via the “DataKeyName” property in grdFeedbackList which is FeedbackId.
Method GetFeedbackInfo takes an argument lFeedbackId which is mentioed in the code above
Here is the sample code of my FeedbackInfo class

[Serializable]
public class FeedbackInfo
{
private long feedbackId;
public long FeedbackId
{
get { return feedbackId; }
set { feedbackId = value; }
}

private string patientId;
public string PatientId
{
get { return patientId; }
set { patientId = value; }
}

private string patientName;
public string PatientName
{
get { return patientName; }
set { patientName = value; }
}

private string physicianId;
public string PhysicianId
{
get { return physicianId; }
set { physicianId = value; }
}

private string physicianName;
public string PhysicianName
{
get { return physicianName; }
set { physicianName = value; }
}

private string speciality;
public string Speciality
{
get { return speciality; }
set { speciality = value; }
}

private string subject;
public string Subject
{
get { return subject; }
set { subject = value; }
}

private string feedback;
public string Feedback
{
get { return feedback; }
set { feedback = value; }
}

private DateTime timeStamp;
public DateTime TimeStamp
{
get { return timeStamp; }
set { timeStamp = value; }
}

private DateTime readTimestamp;
public DateTime ReadTimeStamp
{
get { return readTimestamp; }
set { readTimestamp = value; }
}

private string SortField;
private string SortOrder;

public FeedbackInfo()
{
SortField = "feedback_id";
SortOrder = "DESC";
}

public FeedbackInfo(string sPatientId, string patientName,
string sSpeciality, string sPhysicianId, string sPhysicianName, string sfeedbackText,
string sSubject, DateTime dtTimeStamp, string fileLocation)
{
this.patientId = sPatientId;
this.patientName = patientName;
this.physicianId = sPhysicianId;
this.physicianName = sPhysicianName;
this.speciality = sSpeciality;
this.subject = sSubject;
this.feedback = sfeedbackText;
this.timeStamp = dtTimeStamp;
}

public FeedbackInfo(long lFeedbackId, string sPatientId,
string patientName, string sPhysicianId, string sPhysicianName, string sSpeciality,
string sSubject, string sfeedbackText,
DateTime dtTimeStamp)
{
this.feedbackId = lFeedbackId;
this.patientId = sPatientId;
this.physicianName = sPhysicianName;
this.patientName = patientName;
this.physicianId = sPhysicianId;
this.speciality = sSpeciality;
this.subject = sSubject;
this.feedback = sfeedbackText;
this.timeStamp = dtTimeStamp;
}

public FeedbackInfo(string sPatientId, string patientName,
string sPhysicianId, string sPhysicianName, string sSpeciality, string sSubject,
string sfeedbackText, DateTime dtTimeStamp)
{
this.feedbackId = 0;
this.patientId = sPatientId;
this.patientName = patientName;
this.physicianId = sPhysicianId;
this.physicianName = sPhysicianName;
this.speciality = sSpeciality;
this.subject = sSubject;
this.feedback = sfeedbackText;
this.timeStamp = dtTimeStamp;
}

public void SetSortOptions(string sSortField, string sSortOrder)
{
SortField = sSortField;
SortOrder = sSortOrder;
}

public FeedbackInfo GetFeedbackInfo(long lFeedbackId)
{
if (lFeedbackId <= 0)
return null;
this.feedbackId = lFeedbackId;
return GetFeedbackInfo();
}
}


Associate a detailed view with Gridview

Use the Datasource configured in the step to display data in Detailsview
<asp:DetailsView ID="dvFeedback" runat="server"
HeaderText="Physician Feedback - Detailed Information" EmptyDataText="No matching details found"
DataSourceID="os2" Height="33px" Width="473px" AutoGenerateRows="true">
</asp:DetailsView>


Show Hide cells in Gridview

This is a tricky operation. Let’s say I want to highlight certain rows in the gridview. Condition can be, if the value in read_time_stamp column is empty or has a default value (01/01/000 12:00:00 AM) then highlight the row.

This requires some amount of work
Generate RowDataBound event for gridview. And when every row is being bound, investigate the value in the row for the column for customization. Please note that the column that you are looking for need not be bound. It could have been part of the results returned by your select method (datasource property of gridview or select property of objectdatasource)

protected void grdFeedbackList_RowDataBound(object sender, GridViewRowEventArgs e)
{
if(e != null)
{
FeedbackInfo fInfo = e.Row.DataItem as FeedbackInfo;
if(fInfo != null)
{
if (string.IsNullOrEmpty(fInfo.ReadTimeStamp.ToString()))
{
e.Row.Font.Bold = true;
}
else if (fInfo.ReadTimeStamp.Equals(new DateTime()))
{
e.Row.Font.Bold = true;
}
}
}
}


You can extend the same logic to display/hide images, rows etc.

I’ll have a separate blog to explain the detailview integration with Gridview in my next blog. I hope you found this useful.