Moving repeater in form removes serverside declaration - asp.net

I have two repeaters bound to object collections. They both work fine. But when I move repeater B to repeater A's FooterTemplate the serverside declaration of repeater B disappear.
This is not a parent/child relation.
Any ideas why this happens?
Update:
<asp:Repeater ID="myOuterRepeater" runat="server">
<ItemTemplate>
...
</ItemTemplate>
<FooterTemplate>
<asp:Repeater ID="myInnerRepeater" runat="server">
<ItemTemplate>
<asp:Button OnCommand="btnRemove_Click" ID="btnRemove" RunAt="server" />
<%#Eval("ItemId")%>
<%#String(Eval("Amount"))%>
<ItemTemplate>
</asp:Repeater>
</FooterTemplate>
</asp:Repeater>
When I bind:
myOuterRepeater.DataSource = myCollection
myOuterRepeater.DataBind()
Dim innerRepeater As Repeater =
myOuterRepeater.Controls(myOuterRepeater.Controls.Count - 1).Controls(0).FindControl("myInnerRepeater")
innerRepeater.DataSource = myInnerCollection
innerRepeater.DataBind()

When nesting a control (including a second repeater) inside a repeater, it is not longer part of the page but part of the enclosing repeater.
You will need to use FindControl(string) to get a reference to the nested repeater:
Repeater nested = enclosingRep.FindControl("nestedRepeaterId");

Related

Nested CheckBoxList using DataSet and Repeaters

I'm trying to wire up some CBL's using a repeater and dataset. The dataset contains 2 tables with the same schema and a (one, single) relation (in SQL land think of it as a self join).
When the control is rendered if I set my DataSource = the relationship, I am able to get the children elements to show; so I know the model is good, although misplaced (on purpose to test the model - see code below).
The problem is:
I am having difficulty getting the parent elements to show up at all
Not all parents have children, and the ones that don't still need to show up
Am I approaching this in the right frame of mind? i.e. Am I missing something fundamental? Implementation outside of CBL(plain text) works fine per this article
<asp:Repeater ID="ParentRepeater" runat="server">
<ItemTemplate>
<asp:CheckBoxList ID="ParentCBL" runat="server"
DataSource='<%# DataBinder.Eval(Container.DataItem,"Joined") %>'
DataTextField="TextProperty"
DataValueField="ValueProperty">
</asp:CheckBoxList>
<asp:Repeater ID="ChildRepeater" runat="server">
<ItemTemplate>
<asp:CheckBoxList ID="ChildCBL" runat="server"
DataSource='<%# DataBinder.Eval(Container.DataItem, "Joined") %>'
DataTextField="TextProperty"
DataValueField="ValueProperty">
</asp:CheckBoxList>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
Page Load is nothing spectacular
DataSet ds = Foo.foo();
ParentRepeater.DataSource = ds.Tables["Parent"];
ParentRepeater.DataBind();
In your code you don't bind ChildRepeater
If you want just change plain text to Checkbox in according to https://support.microsoft.com/en-us/kb/306154
then you don't need to use CheckBoxList. But you should only use single checkbox inside repeater.

How to get parent datasource Eval() inside a nested Repeater? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Accessing parent data in nested repeater, in the HeaderTemplate
I have a nested repeater being databound... let's say the top level repeater is an OrderRow and the inner repeaters are bound to LineItem rows from my DB. ASPX is something like this:
<asp:Repeater ID="rptOrder" runat="server">
<ItemTemplate>
<%# Eval("OrderID") %>:<br/>
<asp:Repeater ID="rptLineItems" runat="server">
<ItemTemplate>
<%# Eval("SomeColumn1"); %>
<%# Eval("SomeColumn2"); %>
<%# Eval("SomeColumn3"); %>
</ItemTemplate>
<FooterTemplate>
<asp:Button ID="btnAddLine" runat="server" CommandArgument=<%# ???? %> />
</FooterTemplate>
</asp:Repeater>
</ItemTemplate
</asp:Repeater>
Now the button on the inner footer will be used to add a new line item... but the command argument needs to be the OrderID from the outer repeater, so we know which order to add to. Obviously a regular Eval() call won't work here, because it will have the inner repeater's DataRowView as a source [actually, it won't, since it's in the footer]. How do I get this value? Am I going to have to set this dynamically in the ItemDataBound event of the outside repeater?
Since the call are serial you can use the code behind to save the last order id and use it later.
Here is the idea.
<asp:Repeater ID="rptOrder" runat="server">
<ItemTemplate>
<%#GetOrderID(Container.DataItem)%><br />
<asp:Repeater ID="rptLineItems" runat="server">
<ItemTemplate>
<%# Eval("SomeColumn1"); %>
<%# Eval("SomeColumn2"); %>
<%# Eval("SomeColumn3"); %>
</ItemTemplate>
<FooterTemplate>
<asp:Button ID="btnAddLine" runat="server" CommandArgument=<%=cLastOrderID%> />
</FooterTemplate>
</asp:Repeater>
</ItemTemplate
</asp:Repeater>
and on call behind
public int cLastOrderID = -1;
protected string GetOrderID(object oItem)
{
cLastOrderID = (int)DataBinder.Eval(oItem, "OrderID");
return cLastOrderID.ToString();
}
What I do here is that I call the GetOrderID to return the OrderID and I save it in a global value, and then later in the footer I use this global value. Hope this helps you.

Insert a User Control within an ASP:Repeater

I need to insert a user control into a repeater
<asp:Repeater runat="server" ID="rptAdditionalPages">
<ItemTemplate>
<div id="<%# ((ftj.com.AdditionalPageForProductDetail)Container.DataItem).DivID %>" class="tab_content">
<h1><%# ((ftj.com.AdditionalPageForProductDetail)Container.DataItem).Title %></h1>
<%# ((ftj.com.AdditionalPageForProductDetail)Container.DataItem).Body %>
<uc:EnrollmentMethod ID="EnrollmentMethod2" runat="server" />
</div>
</ItemTemplate>
</asp:Repeater>
When the user control is inserted with this method the code behind cannot find EnrollmentMethod2. Is it possible to add user controls in repeaters?
You can't find it because it's nested in the repeater. You will need to dig into the repeater to find it.
foreach (RepeaterItem item in Repeater1.Items)
{
EnrollmentMethod control = (EnrollmentMethod )item.FindControl("EnrollmentMethod2");
}

Handling a DropDownList in a Nested ListView

I have two nested .net ListViews. I need to filter the contents of the inner listview by selecting from a dropdown list in the outer listview. The layout of the control is like this:
<asp:listview id="lvOuter" runat="server" onitemdatabound="lvOuter_OnItemDataBound"
onitemcommand="lvOuter_OnItemCommand" onitemcreated="lvOuter_ItemCreated" onselectedindexchanged="lvOuter_SelectedIndexChanged">
<layouttemplate>
<ul>
<asp:placeholder id="itemPlaceholder" runat="server" />
</ul>
</layouttemplate>
<itemtemplate>
<asp:dropdownlist id="ddlTest" runat="server" onselectedindexchanged="ddlTerm_SelectedIndexChanged" autopostback="true" >
<asp:listitem text="6" value="6"/>
<asp:listitem text="9" value="9"/>
</asp:dropdownlist>
<asp:listview id="lvInner" runat="server" onselectedindexchanging="lvInner_SelectedIndexChanging"
onitemdatabound="lvInner_ItemDataBound" onitemcommand="lvInner_OnItemCommand">
<layouttemplate>
<asp:placeholder id="itemPlaceholder" runat="server" />
</layouttemplate>
<itemtemplate>
<!--Results displayed here-->
</itemtemplate>
</asp:listview>
</itemtemplate>
</asp:listview>
On the page load I bind data to the outer listview and on OnItemDataBound I bind the inner listview. This is all working fine, but what I need to do now is to re-bind the inner listview with a new query that includes the parameter from the drop down list. This should happen when the user selects a new value in the drop downlist. (OnSelectedIndexChanged) I can access the value easily enough through the sender, as so:
protected void ddlMyDropDown_OnSelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddlMyDropDown = sender as DropDownList;
string value = ddlMyDropDown.SelectedValue;
}
but I'm unable to then find the inner listview relating to that dropdown in order to bind the results of the new query with the added where clause. I'm sure this must be a pretty common requirement. Any pointers would be greatly appreciated.
Have you tried using something like <%# Eval("value", "{0}") %> as seen here
I seem to recall doing something akin to yours with this. It has been awhile since I have done this so sorry if this is not accurate.

Databinding exception with entity navigation property

I have two Entity classes: Order and OrderItem. Order contains a navigation property OrderItemSet of type
System.Data.Objects.DataClasses.EntityCollection<OrderItem>
On an aspx page is a FormView bound to this EntityDataSource:
<asp:EntityDataSource ID="EntityDataSourceOrder" runat="server"
ConnectionString="name=EntitiesContext"
DefaultContainerName="EntitiesContext"
EntitySetName="Order"
Include="OrderItemSet"
// stuff to define a query
</asp:EntityDataSource>
The FormView is bound to the DataSource and the ItemTemplate of this FormView contains a ListView which I try to bind to the OrderItemSet. It looks this way:
<asp:FormView ID="FormViewOrder" runat="server" DataKeyNames="OrderID"
DataSourceID="EntityDataSourceOrder" AllowPaging="True" >
<ItemTemplate>
...
<asp:ListView ID="ListViewOrderItems" runat="server"
DataSource='<%# Eval("OrderItemSet")%>' >
...
</asp:ListView>
</ItemTemplate>
</asp:FormView>
When I run the application I get an exception pointing to the line DataSource='<%# Eval("OrderItemSet")%>' in markup and telling me:
DataBinding: System.Web.UI.WebControls.EntityDataSourceWrapper does not contain a property with name 'OrderItemSet'
What is wrong here?
(I've done the same with other navigation properties which are not lists but single object references, and that works.)
Thank you for help!
It seems to me that you are trying to evaluate a collection from within a datasource, without first binding to that datasource.
Why don't you try binding directly to the datasource? E.g.
<asp:ListView ID="ListViewOrderItems" runat="server"
DataSourceID="EntityDataSourceOrder"
...
</asp:ListView>

Resources