Databinding by ClientID

  • Thread starter Thread starter oafyuf
  • Start date Start date
O

oafyuf

Hi,
I'm trying to learn ASP.NET by doing a pilot project:

I have a DataGrid which contains a nested DataList. I want to iterate
through the SQLDataReader for the DataGrid and populate each DataList
by binding to a fresh SQLDataReader. At the moment I can only bind to
the first instance of the DataList. If I could bind the data by the
ClientID (or UniqueID), I'm sure it would work. Is there a way of
doing this? Or maybe there is a better approach to getting nested data
from separate SQLDataReaders.

Here's the relevant part of the code with extraneous bits removed (I
hope the line breaks don't make it unreadable!):

// ######### ASPX ###########

<asp:DataGrid Border="1" Runat="server" Id="dgApplicants">
<Columns>
<asp:BoundColumn DataField="ApplicantRef" Visible="False" />

<%-- Some more BoundColumns and TemplateColumns --%>

<asp:TemplateColumn>
<ItemTemplate>
<tr>
<td width="30px">&nbsp;</td>
<td colspan="8">
<asp:DataList Border="0" Runat="server" Id="dgApplications"
AutoGenerateColumns="False" Height="0px" Width="100%"
AllowSorting="False">
<ItemTemplate>
<b>App&nbsp;<%# DataBinder.Eval(Container.DataItem,
"VendorNo")%>&nbsp;<%# DataBinder.Eval(Container.DataItem,
"ApplicationRef")%>&nbsp;v<%# DataBinder.Eval(Container.DataItem,
"Version")%>&nbsp;<%# DataBinder.Eval(Container.DataItem,
"Status")%></b>
</ItemTemplate>
</asp:DataList>
</td>
</tr>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>

// ######### ASPX ENDS ###########

// ######### CODE-BEHIND ###########
//adoApplicantReader is the outer loop
//adoApplicationReader is the inner loop

if(objDuplicatePartiesApplicant.ListParties(inputSurname, inputTown,
inputMainCPH, inputBusinessName, inputPostcode, inputOrderBy, ref
adoApplicantReader) == MyAssembly.AESIS.ReturnCodes.Success)
{
// OK, the SQL data layer object returned "success", but did we get
some results?
if(adoApplicantReader.HasRows)
{
// successful search: hide prompt and display Update button
lblPrompt.Visible = false;
btnUpdate.Visible = true;

// databinding method
this.dgApplicants.DataSource = adoApplicantReader;
this.dgApplicants.DataBind();
adoApplicantReader.Close();

// with the firehose cursor (SQLDataReader), we have to do the query
again after it is bound to pass it's members...
if(objDuplicatePartiesApplicant.ListParties(inputSurname, inputTown,
inputMainCPH, inputBusinessName, inputPostcode, inputOrderBy, ref
adoApplicantReader) == MyAssembly.AESIS.ReturnCodes.Success)
{
// SQL data layer object returned "success"
if(adoApplicantReader.HasRows)
{
while (adoApplicantReader.Read())
{
int intOrd = adoApplicantReader.GetOrdinal("ApplicantRef");
int intApplicantRef = (int)adoApplicantReader.GetValue(intOrd);

SqlDataReader adoApplicationReader = null;

if(objDuplicatePartiesApplication.ListPartyApplications(intApplicantRef,
ref adoApplicationReader) == MyAssembly.AESIS.ReturnCodes.Success)
{
// did we get some results?
if(adoApplicationReader.HasRows)
{
// find a reference to the nested DataList
foreach(DataGridItem dgItem in dgApplicants.Items)
{

DataList dgSelected =
(DataList)dgItem.FindControl("dgApplications");

// here I need to find the reference name of each nested
datagrid
// and assign data to that...
Response.Write("<tr><td><font color=#cc0000>ClientID:
"+dgSelected.ClientID+"</font></td></tr>"); // debug
dgSelected.DataSource = adoApplicationReader;
dgSelected.DataBind();

}
}
adoApplicationReader.Close();
}
}
}
}
else
{
lblPrompt.Text = "No records returned for this search. Please try
again.";
}
// tidy up before the garbage collector gets a chance to do it...
adoApplicantReader.Close();
}
else
{
lblPrompt.Text = "DATABASE ERROR:<br/><font color=#ff0000>\"" +
objDuplicatePartiesApplicant.NativeError + "\"</font><br/>Please
report this error to AESIS support.";
}
}
// ######### CODE-BEHIND ENDS ###########

The whole thing looks ugly to me because I have to keep on getting
fresh data, is there a more flexible cursor that I can use?

My next step is to investigate using DataSets, combining the XML DOMs
and doing all the manipulation of the presentation layer via
client-side JavaScript. Is this the recommended method?

Thanks,
oafyuf
 
Hi Oafyuf,

You need to use the datagrid's ItemDataBound event to populate the inner
datalist. Here is a sample based on the Pubs sample database.

I placed a datagrid on a form and added a template column (the rest are
autogenerate). I added a datalist to the template column. Then I added the
following code.

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
If Not IsPostBack Then
Bind()
End If
End Sub

Private Sub Bind()
Dim Qry1 As System.Data.SqlClient.SqlDataReader
Dim connectionString As String = "server='localhost';
trusted_connection=true; Database='pubs'"
Dim sqlConnection As System.Data.SqlClient.SqlConnection = New
System.Data.SqlClient.SqlConnection(connectionString)
Dim queryString As String = "SELECT au_id, au_lname, au_fname FROM
authors"
Dim sqlCommand As System.Data.SqlClient.SqlCommand = New
System.Data.SqlClient.SqlCommand(queryString, sqlConnection)
sqlConnection.Open()
Qry1 =
sqlCommand.ExecuteReader(System.Data.CommandBehavior.CloseConnection)
DataGrid1.DataSource = Qry1
DataGrid1.DataBind()
Qry1.Close()
sqlCommand.Dispose()
sqlConnection.Close()
sqlConnection.Dispose()
End Sub

Private Sub DataGrid1_ItemDataBound(ByVal sender As Object, ByVal e As
System.Web.UI.WebControls.DataGridItemEventArgs) Handles
DataGrid1.ItemDataBound
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType =
ListItemType.AlternatingItem Then
Dim list As ListBox
list = e.Item.Cells(0).Controls(1)
Dim Qry1 As System.Data.SqlClient.SqlDataReader
Dim connectionString As String = "server='localhost';
trusted_connection=true; Database='pubs'"
Dim sqlConnection As System.Data.SqlClient.SqlConnection = New
System.Data.SqlClient.SqlConnection(connectionString)
Dim queryString As String = "SELECT title FROM titles t inner
join titleauthor ta on t.title_id = ta.title_id inner join authors a on
ta.au_id = a.au_id where a.au_id = '" & e.Item.Cells(1).Text & "'"
Dim sqlCommand As System.Data.SqlClient.SqlCommand = New
System.Data.SqlClient.SqlCommand(queryString, sqlConnection)
sqlConnection.Open()
Qry1 =
sqlCommand.ExecuteReader(System.Data.CommandBehavior.CloseConnection)
list.DataSource = Qry1
list.DataTextField = "title"
list.DataBind()
If list.Items.Count = 0 Then list.Visible = False
list.Height = list.Height.Point(30 * list.Items.Count)
Qry1.Close()
sqlCommand.Dispose()
sqlConnection.Close()
sqlConnection.Dispose()
End If
End Sub

---
I hope this helps.

Thank you, Mike
Microsoft, ASP.NET Support Professional

Microsoft highly recommends to all of our customers that they visit the
http://www.microsoft.com/protect site and perform the three straightforward
steps listed to improve your computer’s security.

This posting is provided "AS IS", with no warranties, and confers no rights.


--------------------
 
Back
Top