Problem binding DataGrid nested inside Repeater

  • Thread starter Thread starter Stephen Miller
  • Start date Start date
S

Stephen Miller

I am using the OnItemDataBound event of Repeater control to nest a
DataGrid within the Repeater. When I attempt to bind to the DataGrid
using the DataSource method I get the error message "Object reference
not set to an instance of an object". This error message commonly
occurs when a server control is incorrecly declared, so naturally I
have double checked this.

To test this, I moved the aspx code for the DataGrid
('myNestedDataGrid') outside the Repeater ('myRepeater') and it bound
without problem.

I know that you can nest a DataGrid within a Repeater, but I must be
missing something:

<code_behind>

'-- Declare server controls
Protected WithEvents myRepeater As System.Web.UI.WebControls.Repeater
Protected WithEvents myNestedDataGrid As
System.Web.UI.WebControls.DataGrid

'-- Define page wide variable to hold nested data source
Private mDataView As DataView

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim myDataSet As DataSet = getRepeater

mDataView = myDataSet.Tables("myTable").DefaultView

myRepeater.DataSource() = mDataView
myRepeater.DataBind()

End Sub

Public Sub myRepeater_ItemBound(ByVal sender As System.Object, ByVal
e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles
myRepeater.ItemDataBound

Dim lngIdx As Integer = e.Item.ItemIndex
If lngIdx > -1 Then

myNestedDataGrid.DataSource =
getNestedDataGrid(mDataView(lngIdx).Row("ItemID")).Tables("myNestedTable").DefaultView
myNestedDataGrid.DataBind()

End If

End Sub

Private Function getRepeater() As DataSet
'-- Return DataSet
End Function

Private Function getNestedDataGrid(ByVal ItemID As Long) As DataSet
'-- Return DataSet, using ItemID as primary key
End Function

</code_behind>

<aspx_that_fails>

<asp:Repeater id="myRepeater" runat="Server"
OnItemDataBound="myRepeater_ItemBound">
<ItemTemplate>
<b><%# DataBinder.Eval(Container.DataItem, "ItemName") %></b>
<asp:datagrid id="myNestedDataGrid">
<columns>
<asp:boundcolumn datafield="Field1"></asp:boundcolumn>
<asp:boundcolumn datafield="Field2"></asp:boundcolumn>
<asp:boundcolumn datafield="Field3"></asp:boundcolumn>
</columns>
</asp:datagrid>
</ItemTemplate>
</asp:Repeater>

</aspx_that_fails>

<aspx_that_works>

<asp:Repeater id="myRepeater" runat="Server"
OnItemDataBound="myRepeater_ItemBound">
<ItemTemplate>
<b><%# DataBinder.Eval(Container.DataItem, "ItemName") %></b>
</ItemTemplate>
</asp:Repeater>
<asp:datagrid id="myNestedDataGrid">
<columns>
<asp:boundcolumn datafield="Field1"></asp:boundcolumn>
<asp:boundcolumn datafield="Field2"></asp:boundcolumn>
<asp:boundcolumn datafield="Field3"></asp:boundcolumn>
</columns>
</asp:datagrid>

</aspx_that_works>
 
are you sure that you can an control inside another and yet still be able to
reference it??
i think i have tried this before without success either.
 
It can be done (sort of)
In the HTML of your datagrid put a reference to a data source...
<asp:DataGrid id=DataGrid1 runat="server" AutogenerateColumns="False"
DataSource='<%# getGridDataSource( ctype(DataBinder.Eval(Container.DataItem,
"CustomerID"),string) ) %>'

Whats going on here is... When a row of your repeater binds, a data grid is
created & the data source calls a function called getGridDataSource. THE
IMPORTANT BIT is the DataBinder.Eval(Container.DataItem, "CustomerID") that
is passed to getGridDataSource. The Container.DataItem is the Current
Reapeater Row. so... You key together a piece of data from the current
Repeater row with the datasource of the data grid - so that the content of
the data grid is relevant to the current repeater row!

Now, when the datagrids bind, you can have a handler for
OnItemDataBound='<%# whatever....%> & get a reference to the grid.
 
Back
Top