Nested Repeater not being recognised in code behind - asp.net

I have a nested repeater set up but the child repeater control is not being recognised in the code behind. It's not even being added to the designer file. I've tried this on an aspx and an ascx page but both gives the same problem.
<asp:Repeater ID="RepeaterParent" runat="server">
<ItemTemplate>
<asp:Repeater ID="RepeaterChild" runat="server">
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
with this on the page the code behind only recognises the RepeaterParent but not RepeaterChild.
Can anyone help me out here?
Many thanks!

Like any other control that is used within a repeater (or template) control, you need to retrieve the control using FindControl.
So, in your item data bind event handler for the parent, you would do:
var childRepeater = RepeaterParent.FindControl("RepeaterChild") as Repeater;

The RepeaterChild will be accessible when you use FindControl("RepeaterChild") on the parent repeater I think. Can't remember the exact syntax.
Also note that the FindControl method will also take the context of the current item of the parent repeater, as the name you specify will repeat. Naming containers do some work in the background to provide unique naming, but it is hard to track sometimes.

Related

Eval inside an ASP.net repeater doesn't work inside another control

I have a Reapter control with a custom server side control inside of it. When I place the code:
<%# Eval("DateAdded") %>
inside the item template of the repeater it works fine, but when I place it inside the custom server control inside the repeater, it doesn't work.
Is it possible to do something like Parent.Eval() or Container.Eval() to get back to the context of the Reapeter rather than the custom control?
The repeater is databound, the control that you are placing this eval statement in isn't. You'll need to pass the value to the control using a property.
For Example:
<uc1:MyControl MyProperty='<%# Eval("DateAdded") %>' />
You can now access the MyProperty property inside your control to access this value.
It should work. Can you supply more context/code for the server control?
Also, are you using single quotes to set properties on a control dynamically using eval? Double quotes should throw an error, not just be ignored.
MyProperty='<%# Eval("DateAdded") %>'

vb asp.net : A way to avoid repeating a code in common in ItemTemplate and EditItemTemplate

I'm a newbie in asp.net.
When using FormView, there is a big amount of code in ItemTemplate, EditItemTemplate and InsertItemTemplate which is almost identical.
For example:
<asp:ListBox ID="ListBox2" runat="server" Rows="1" CssClass="field"
DataSourceID="StatusList" DataTextField="DESCRIPTION"
DataValueField="STAT_ID" SelectedValue='<%# Bind("STAT_ID") %>'>
</asp:ListBox>
(Note: at the exception that Eval() would be used instead of Bind() in ItemTemplate)
I've been trying to avoid repeating this code but without the expecting result:
ListView allows the use of LayoutTemplate - but I didn't see any examples that insert this kind of code in LayoutTemplate. And inserting this code in LayoutTemplate would result in an error.
DetailView allows to produce code automatically but I'd like to use a specific design (for ex. using "fieldset" that encompasses some fields).
What would be the best way to avoid repeating this kind of code ?
You don't have to much choice about seperately specifying the Bind/Eval part, but you do have some control over the other pieces. You can make a custom UserControl that contains your layout.
Usually I include a property on this usercontrol called "Mode" which I either set to Edit or View, then based off of this property I change enabled/visible properties on the controls. You'll also need to include a property for each value you want bound/displayed in the usercontrol.
Put some labels, textboxes, etc... in your designer and hook them up to properties in your code behind, put the usercontrol on your page in your item/edit template and eval/bind to your data to the various properties (make sure to set the mode so it displays right).

How to implement LayoutTemplate with a PlaceHolder

In my own server control, I would like to implement something similar to the ListView:
<asp:ListView runat="server">
<LayoutTemplate>
<asp:PlaceHolder runat="server" id="itemPlaceholder" />
</LayoutTemplate>
</asp:ListView>
I have created an ITemplate property, I can set the layout in the aspx page, and I am doing ITemplate.InstantiateIn(myControl).
But I can't figure out how to insert controls at the placeholder. I'm guessing it would be something like MyTemplate.FindControl("itemPlaceholder").Controls.Add(myControl). I tried casting to the type of my ITemplate, but I get the error:
Unable to cast object of type 'System.Web.UI.CompiledTemplateBuilder' to type 'MyNamespace.MyLayoutTemplate'
What am I missing?
Edit: I just found this: http://www.nikhilk.net/SingleInstanceTemplates.aspx Control developers can define templates to be single instance using metadata which causes the ID'd controls within the template contents to be promoted to the page level... The parser and code-generator together work behind the scenes to add member fields, and initialize them at the right time.. It seems to be only for user controls? I tried Page.FindControl() after doing this but it didn't find anything.
Ok, this was simply a matter of user error. I instantiated the ITemplate in a Panel, so obviously Page.FindControl() (which is not recursive) wouldn't work. Once I did Panel.FindControl(), everything worked.
In the past I have used this library with sucess
http://www.denisbauer.com/ASPNETControls/DynamicControlsPlaceholder.aspx

How to get at repeater Item from jQuery

I've got a repeater on the page. The repeater is actually in an .ascx. In the repeater each item has a few things such as an Add button, and a couple of other fields.
What I am trying to the Container.DataItem but the one that relates to the Add button that was clicked. If the user clicks the add button in the repeater list, give me reference to the Container.DataItem for that related to the button in that ItemTemplate that the user just clicked.
The add button is really just a regular HTML hyperlink wrapped around a regular HTML image. I added an ID to the hyperlink but don't know how to really link the two and gain reference to the DataItem.
I'm all set and can fly with jQuery and do whatever client-side stuff I want.
Example of what I started:
<script type="text/javascript">
$(document).ready(function()
{
$(myUserControl.MyRepeater).
}
</script>
The repeater doesn't generate any HTML of its own. It'll only write what you tell it to write.
So what you'll have to do is somehow identify each item, preferably with unique id's in the HTML. That way you can gain access to it through the DOM.
For example, if the rendered markup looked like this then you could actually access "item1" via jquery:
<div id="item1">abc</div>
<div id="item2">def</div>
To accomplish this you might try something like this in your ItemTemplate :
<ItemTemplate>
<div id="item<%#Container.ItemIndex %>">bla</div>
</ItemTemplate>
The Repeater and the DataItems are server-side control which is available from the code-behind of your pages/controls. You cannot access it from client-side code (javascript).

How to populate UpdatePanel in Repeater in ASPX (not code-behind)?

I have a Repeater which displays a list of items (in a grid-like/table view). When a user clicks an item, I display an UpdatePanel under this item with additional information relevant to the item (similar to Accordion control). I know how to populate the elements of the UpdatePanel in code-behind (I pass the ID of the selected element in the Repeater control as CommandArgument, get additional info for this ID, and set up the text fields of the active UpdatePanel controls). But I'm wondering if I could set up binding directly in the ASPX (instead of code-behind). When I used the <%= %> syntax to assign text fields of the UpdatePanel control the values of the page properties, e.g. <%= Comment %>, it sort of worked, but it changed the fields of all UpdatePanels in the repeater. Is there any way to bind the active UpdatePanel to the current values and leave already bound UpdatePanels unchanged?
Are you looking to display a container that displays additional information? Is there other activity in the "box" that requires it be an updatepanel?
<asp:repeater>
<itemtemplate>
<%# Eval("Name") %> <%# Eval("LastName") %><br />
<span onclick="$get('<%# Eval("Id") %>')">View Age</span>
<div id="<%# Eval("Id")%>" style="display:none;">
Age: <%# Eval("Age") %>
</div>
<itemtemplate>
</asp:repeater>
Ithink that's right, some syntax may be off a bit (typing without intellisense). Would that work?
I used ID as a unique identifier for the div id and the onclick command. You could also use jquery, asp:controls or whatever else you wanted.
Easiest way is to nest a FormView inside the update panel. Then the only thing you need to do in the code behind is get the additional info, assign it to the FormView.DataSource, and call FormView.DataBind(). Everything in the FormView will use the <%# Eval("SomeColumn") %> syntax. You'll probably need to use a FindControl() to get a reference to the FormView. I'd type up the code for you but I'll save you some headaches down the road and say DON'T DO THIS.
The update panel is about the most inefficient way to do any ajax stuff. The only way to get it all to wire up correctly with this repeater and server side code is to either have a gigantic viewstate or to rebind the repeater in your page load. You are turning a request that could be 300ms into something that will take over a second...or longer! Get familiar with a good ajax framework and don't be afraid to write real html. At the very least, use a webservice that loads a usercontrol with your markup.
I know the update panel is easy, and it's built in. It might even be adequate for what you are doing, but you must resist. You'll be glad you did.

Resources