I have a Repeater inside a Repeater, how can a use the code below:
<input type="hidden" value='<%# Container.ItemIndex %>' />
pointing to the first repeater?
This question is similar; although it talks about accessing a property from the <HeaderTemplate>, it feels like it should work from the <ItemTemplate>.
So try <%# ((RepeaterItem)Container.Parent.Parent).ItemIndex %>
If this doesn't work, you may need more .Parents. Try attaching an ItemDataBound handler to the inner repeater temporarily, and use the fact that the RepeaterItemEventArgs Item property returns the same object as Container gives in the aspx. So basically evaluate e.Item.Parent, e.Item.Parent.Parent etc. until you find the one that is another RepeaterItem. Then use the same number of .Parents in your aspx.
From MSDN: How To Display Hierarchical Data by Using Nested Repeater Controls
The article is a few years old but the content is what you're looking for.
Related
I know its maybe unusual, but i want add htmlGenericControl to a div (it's outside a repeater) in ItemDataBound from CodeBehind..
HtmlGenericControl slider = (HtmlGenericControl)e.Item.FindControl("slider");
htmlGenericControl input = new HtmlGenericControl("input");
input.Attributes.Add("type", "radio");
input.Attributes.Add("name", "slide_switch");
input.Attributes.Add("id", string.Format("projectImage-{0}", item.ProjectImageId));
slider.Controls.Add(input);
but its return null everytime. this is the aspx code:
<div class="slider">
<asp:Repeater ID="rptProjectImages" runat="server" OnItemDataBound="rptProjectImages_ItemDataBound">
<ItemTemplate>
</ItemTemplate>
</asp:Repeater>
</div>
Didnt work with asp.net too long, but probably this should help
<div id="myDiv" runat="server">...</div>
and in codebehind myDiv should be accessible.
Several issues with this code.
First, your div is client-side only, from server-side point of view it's just a string. Turn it into server-side control with:
<div class="slider" runat="server" ID="slider">
Second, FindControl looks for immediate children only, in your case children of the repeater item. slider is not one of those. Moreover, it is not a part of the repeater item template and should be accessible as in in code behind, so just
slider.Controls.Add(...
That is unless slider and the repeater you showed are a part of some other template of some "outer" control. In which case make sure to use that "outer" control to call FindControl on.
Finally, don't mess with id. I bet this is either going to be overridden by ASP.NET, or will cause issues on the page. Instead set client ID mode to static and assign ID property:
input.ClientIDMode = ClientIDMode.Static;
input.ID = string.Format("projectImage_{0}", item.ProjectImageId);
This is eventually output the same value for id you needed, but in more ASP.NET compliant way. One note though is that I replaced "-" with "_" - server side controls cannot have hyphens in ID
FindControl finds a control within another, but does so looking for the control's id. Your "slider" control has no id, it uses a class named "slider" but has no id.
You will need to define the control as
<div runat="server" id="Slider" class="slider">
<asp:Repeater ID="rptProjectImages" runat="server" OnItemDataBound="rptProjectImages_ItemDataBound">
<ItemTemplate>
</ItemTemplate>
</asp:Repeater>
</div>
The runat="server" tells the framework to instantiate that control in your code behind. The id will be the name of the object that is that control. Then in your code, you can do
htmlGenericControl input = new HtmlGenericControl("input");
input.Attributes.Add("type", "radio");
input.Attributes.Add("name", "slide_switch");
input.ID = string.Format("projectImage-{0}", item.ProjectImageId);
Slider.Controls.Add(input);
I am having a look at databinding for the first time. I understand that the databound elements are put in the aspx file between <%# and %>. I also understand that a Repeater class is used. Like so:
<asp:Repeater ID="gvEvents" runat="server">
<ItemTemplate>
<div class="eventLogItem">
<h1><%# Eval("Event")%></h1>
<time><%# Eval("Timestamp")%></time><small><%# Eval("User")%></small>
<span class="nav">mouseover to view comments</span>
<textarea disabled="disabled"><%# Eval("Comments") %></textarea>
</div>
</ItemTemplate>
<SeparatorTemplate>
<hr />
</SeparatorTemplate>
</asp:Repeater> `
But where would the aspx code get "Event", "Timestamp" and "User" and "Comments"? There does not seem to be something clear in the code-behind file. What am I missing?
In your code behind you would set the DataSource property of the repeater to some collection of object in which each of those objects contains a property named Event, Timestamp, User, and Comments. If you don't assign a data source, then there won't be anything for the repeater to display. If any of the bound items is missing one of those properties, you'll get an error at runtime.
Look in the code behind for gvEvents.DataSource = ... that is how the database is called for the databinding of the repeater class
this is definitely an easy question but I still don't know what exactly it is for. Can anybody tell me what ImageUrl='<%# Eval("FileName") %>' means? I still don't get the idea why we need to include %#.
<%# Eval("FileName") %> is used in the context of binding data from a collection to a control. Probably the value for the imageurl is coming from a property of an object in the collection
For example, List<Photo> where Photo has a property of FileName. If you are binding that to a gridview, a repeater, etc, you'll access that property for each item in the collection when binding to such controls
Asp.net data binding overview
in this Line...
ImageUrl='<%# Eval("FileName") %>'
ImageURL the attribute of your asp:ImageButton control that is used to specify the Url of the Image File to be Used
Code between '<% and %>' tags are writtent to be Executed on the Server
'#' is used to specify that the result of server side execution will be bound hear
Eval KeyWord is Used To Evaluate the perticular Column Value (that you specify ("--hear--")) from The DataSourse
When you are using a Template Control like Repeater , GridView , etc. you are actually iterating in a list of data records, and <%# Eval("FileName") %> here means give me the value of the column named FileName.
Here we have used the Eval function which is used for one way databinding. FileName is the field name you are associating. Anything that's written inside <%# %> is parsed by asp.net engine before generating the webpage source which is pure client side script and html tags.
So Eval function is executed at server end by ASP.net engine.
I need to initialize the text attribute of the text box element with a property from some where else when actually I can simply do this from code but it will be much more convenient if it possible to do it like this:
<asp:TextBox runat="server" Text="<%= new ContextItem("title").Value %>" />
Unfortunately the above can't be done..
The issue is that this text box element repeats it self several times in the page and my question is:
Are there any suggestions how to make it cleaner then to write it again and again in the code behind?
Thank,
Adler
OK so the basic problem here is that if you use an inline expression you can NOT use it to set a property of a server-side control outside of a binding context (using a binding expression). I have inferred that this is probably because of the timing of the evaluation of these inline expressions. You can, however, render client-side markup in this way. If you want to keep the functionality purely in your aspx file, this is the way to do it.
Edit: Based on input from Justin Keyes, it appears it IS possible to use a binding expression to set the property. You need to manually invoke Page.DataBind() to trigger the textbox to evaluate the expression (see answer below).
For instance this:
<asp:Label ID="lbl" runat="server" Text="<%= Now.ToShortDateString() %>" />
Will produce this output:
<%= Now.ToShortDateString() %>
On the other hand this:
<%= "<span>" & Now.ToShortDateString() & "</span>"%>
Will produce this output:
7/27/2011
The "normal" way to solve this problem is just to set the Label.Text properties in a Page.Load event handler or another appropriate event handler depending on your needs, as below. This is the way I believe most people would prefer to do it, and is most easily understandable in my opinion.
Markup:
<asp:Label ID="lbl" runat="server" />
Code:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
lbl.Text = Now.ToShortDateString()
End Sub
Option 1: don't use server controls
If you aren't accessing the value on the server, just use plain HTML instead of an ASP.NET server control:
<input ID="Textbox1" Type="Text"
Value='<%= new ContextItem("title").Value %>' />
Option 2: use Page.DataBind()
If you change your code to use <%# instead of <%= (as below) and call Page.DataBind(), it will work (I've tested it). Change your markup to this:
<asp:TextBox runat="server" Text="<%# new ContextItem("title").Value %>" />
And in your logic, call Page.DataBind() in the Load event like this:
protected void Page_Load(object sender, EventArgs e) {
Page.DataBind();
}
Even though the TextBox is not contained in a typical "data bound" control such as a Repeater or GridView, calling DataBind() on a control will force it to evaluate <%# ... %> statements.
The Moof's comment (below) is correct. This post also mentions Page.DataBind().
You can set the text on a page in a similar way.
<asp:TextBox id="TextBox1" runat="server" Text='<%#GetValue('Title)%>' />
But in order for this to work, you will need to DataBind the control on Page_Load. For multiple TextBox controls you could just loop through each and databind them so that you do not have to hard code the databinding of each.
I am not sure what your ContextItem is though, so you would have to modify my code.
The short answer is NO, you can only use this kind of code with databindings, that means inside a GridView for example. But you can use this in the head section.
I use it to prefix my urls sometimes with something predefined. Example
<script src="<%=Utils.GetGeneralPrefix()%>/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
In that case it works.
Hope it helps.
90% of the time when I try this I have to use single quotes ('') instead of double quotes ("") around the <%%>. Give that a try before you spend too much time on anything else.
I currently have a repeater control and inside the itemtemplate I have a usercontrol. This usercontrol renders correctly, but I am trying to assign a dataitem to a property in the repeater control.
<asp:Repeater ID="Repeater1" DataSourceID="EntityDataSource" runat="server">
<ItemTemplate>
<uc1:Request ID="Request1" runat="server" RequestId='<%# Eval("RequestId") %>' />
</ItemTemplate>
RequestId is just an Int32. It just doesn't assign it.
I can put the eval outside of the usercontrol just in the itemtemplate and it correctly outputs the right id.
If I remove the whole eval and just type a number in then it works fine.
Any help appreciated.
[UPDATE] : Issue Solved
I was using an EntityDataSource and this automatically binded to the repeater. It printed out all the information from the database on the screen without any codebehind. But when I put in the code behind Repeater1.DataBind(); it then started to work.
I don't know why, but hey it's solved. It now successfully passes the value through. I imagine it has something to do with the page lifecycle.
If you just bind with repeater collection of int, you need use this:
<uc1:Request ID="Request1" runat="server" RequestId='<%# Container.DataItem %>' />
And don't forget to call DataBind() for repeater or for Page where there is a repeater control.
Are you missing a ' at the end?
change following:
RequestId='<%# Eval("RequestId") %> />
to
RequestId='<%# Eval("RequestId") %>' />
You can implement this by using Repeater control's ItemDataBound event, so that you can set the dynamic property for the control.