ASP.NET Repeater control with nested repeaters - asp.net

I have a nested repeater control. Here is what the HTML looks like:
<ItemTemplate>
<div class="boxLeft">
<h4><%# DataBinder.Eval(Container.DataItem, "DisciplineName") %></h4><asp:Label runat="server" ID="lblDisciplineID" Visible="false" Text='<%# DataBinder.Eval(Container.DataItem, "DisciplineID") %>'></asp:Label>
<p><%# DataBinder.Eval(Container.DataItem, "DisciplineNarrative") %></p>
<h5 class="articles"><%# DataBinder.Eval(Container.DataItem, "InstructorCount")%> instructors</h5>
<ul>
<asp:Repeater runat="server" ID="rptRegions">
<ItemTemplate>
<li><a href='/Lessons/<%# DataBinder.Eval(Container.DataItem, "DisciplineName") %>/<%# DataBinder.Eval(Container.DataItem, "CityName") %>'><%# DataBinder.Eval(Container.DataItem, "CityName") %></a></li>
</ItemTemplate>
</asp:Repeater>
</ul>
</div>
</ItemTemplate>
As you can see, I want to access the parent DisciplineName property from the parent repeater, in my child repeater in order to build the URL. I get the following error:
DataBinding: 'GolfLessonSearch.Model.CityEntity' does not contain a
property with the name 'DisciplineName'.
This is because it is trying to get "DisciplineName" from the child repeater but I want it from the parent repeater. I thought that the properties may still be in scope but it appears not. Is there any way of getting this?

If the objects behind your DataItems have the same parent/child relationship as you are trying to represent them in the repeater, you can always fully qualify the property name so that your child repeater is calling
DataBinder.Eval(Container.DataItem, "Parent.DisciplineName")
If this isn't the case, my gut would be to create a ViewModel object (even though it's not mvc) of your child object to fake that relationship...
EDIT
Just a note that when I said "Parent.DisciplineName", I meant to replace "Parent" with the object name... (I only qualify because "Parent" is a reserved word in so many other places in asp.net...

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.

Repeater: databind server-side ID in item control?

When binding a datasource to a Repeater control, is it possible to databind to the ID property of a server-side control inside the ItemTemplate? like so:
<asp:Repeater ID="rptToolTips" runat="server">
<ItemTemplate>
<telerik:RadToolTip ID="tt<%# Eval("Name") %>" ClientIDMode="Static" runat="server">
<div class="tip">
<div class="segName">Segment #<%# Eval("Name") %></div>
<div>Flow:<%# Eval("Flow", "{0:N}") %></div>
</div>
</telerik:RadToolTip>
</ItemTemplate>
</asp:Repeater>
...here I'm trying to set the RadToolTip's ID property to "tt[name-value]". I've tried a few variants but they're invalid:
ID="tt<%# Eval("Name") %>"
ID='tt<%# Eval("Name") %>'
ID="tt<%# Eval('Name') %>"
It's not possible. A server control's ID is set at the time it's being created or at design time. Once it's set you cannot reset it during the data binding.
But, if you are trying to use this ID value in JQuery or JavaScript you could employ the following hack.
Add a custom property to your control (give it any name you like and in this case I'll use myId)
myId='<%# Eval("Name") %>'
No you can find this element by this myId property
Hope this helps.
Try this to assign ID
ID=' "tt" + <%# Eval("Name") %>'
Also see this answer by me to one of the questions at SO for another way (using pure JavaScript's this object rather than using a custom property to get the clientID) of doing this.
Just thought of keeping these linked for future reference.

Creat dynamic menu in asp.net

I am trying to create a side menu with all the categories (and later on sub menu with subcategories)
found this code online but I am not exactly sure what is going on
asp:Repeater id="MenuRepeater" runat="server">
<headertemplate>
<ul>
</headertemplate>
<itemtemplate>
<li></a></li>
</itemtemplate>
<footertemplate>
</ul>
</footertemplate>
</asp:Repeater>
what should I enter between the li tags and what code is needed using LINQ?
Repeater is DataBound Control so it needs IDataSource to bind the data in/out it, you can write your LINQ query to get the menu from the database and call .ToList() method and bind it to the repeater control.
For example:
<asp:Repeater id="MenuRepeater" runat="server">
<headertemplate>
<ul>
</headertemplate>
<itemtemplate>
<li><%# Bind("MenuItem") %></li>
</itemtemplate>
<footertemplate>
</ul>
</footertemplate>
</asp:Repeater>
in the code behind you'll create your IQueryable object and convert it to IList by calling .ToList() like this:
var query = from m in Context
select m.MenuItem;
MenuRepeater.DataSource = query.ToList();
MenuRepeater.DataBind();

Databinding to a View Model not working

I have an AJAX Accordion Control sitting on my Web Form. I have a Asp.Net Label sitting inside an Accordion Pane. I want to databind the text property of the label to a View Model I have running.
The Label Text Property never seems to databind with the View Model? It will work perfectly if I pull the label outside of the Accordion Pane, but not inside?
This works:
<asp:Label runat="server" Text='<%# Model.Program.NameVisible.ToString() %>' />
This does not:
<asp:AccordionPane ID="AccordionPane2" runat="server">
<Header>
Advanced Search
</Header>
<Content>
<asp:Panel ID="pnlAdvancedSearch" runat="server">
<table cellpadding="2" cellspacing="0" width="100%" runat="server">
<tr>
<td align="right">
<asp:Label runat="server" Text='<%# Model.Program.NameVisible.ToString() %>' />
</td>
</tr>
</table>
</asp:Panel>
</Content>
</asp:AccordionPane>
Any ideas or workarounds?
Thanks.
Update: This apparently does not work when nested inside any AJAX Controls. I have had the same issue with the binding not taking place inside a ModalPopUpExtender as well.
The DataBind of the Accordion control does not invoke DataBind for each of the explicitly defined, custom AccordionPane controls. It instead will build the panes, as per the answer provided by Jupaol, using templates.
In your example, you will need to explicitly call DataBind on the control you want bound, or on a parent which will invoke databinding on all children. So, in your example, calling pnlAdvancedSearch.DataBind() would suffice to bind your label, and any other controls within the search panel.
I feel it worthwhile to add, however, that it also seems like it would be simpler to replace your <asp:Label> control entirely with a simple:
<%: Model.Program.NameVisible.ToString() %>
I just found a way
First of all the Accordion control does support data binding:
The Accordion can also be databound. Simply specify a data source through the DataSource or DataSourceID properties and then set your data items in the HeaderTemplate and ContentTemplate properties.
Source
Example:
Output
ASPX
<ajax:Accordion runat="server" ID="ajax22" RequireOpenedPane="true"
HeaderCssClass="accordionHeader"
HeaderSelectedCssClass="accordionHeaderSelected"
ContentCssClass="accordionContent"
>
<ContentTemplate>
Even cooler content
<br />
<asp:Label Text='<%# DataBinder.Eval(Container.DataItem, "Something") %>' ID="lbl" runat="server" />
</ContentTemplate>
<HeaderTemplate>
Cool header
<br />
<asp:Label Text='<%# DataBinder.Eval(Container.DataItem, "Something") %>' ID="lbl" runat="server" />
</HeaderTemplate>
</ajax:Accordion>
ASPX code behind
You need to specify the Accordion.DataSource property, this property only supports IEnumerable or IListSource, therefore you would need to bind your accordion as follows:
this.ajax22.DataSource = new[] { this.Model };
this.DataBind();
Model
public class MyModel
{
public MyModel()
{
this.Something = "plop!";
}
public string Something { get; set; }
}
When you bind your Accordion, a number of AccordionPanes are created to represent each bound item.
If you specify additional custom AccordionPanes, when you apply binding as specified above, these AccordionPanes will be ignored and won't be rendered.

Passing Value Through Link Button in ASP.NET

Conditions :
I have two tables,
category(id_kat,name_kat)
book(id_book,id_kat,name_book)
id_kat has a child and parent relations.
I'm a little bit confused using ASP.NET, especially when passing value between pages.
Now, i'm showing the category's datas with
<asp:listview id="listview1" runat="server" datakeynames"id_kat" datasourceID="sdskat">
//FYI sdskat is datasource for category table
<itemtemplate>
<li>
<asp:linkbutton id="linking" runat="server" ><%# Eval("name_kat") %></asp:linkbutton>
</li>
</itemtemplate>
</asp:listview>
The problem is, i wanted to pass "id_kat" value when i click the hyperlink. (but redirected to self page).
I want it as a query string (or another way if able).
Thanks a lot.
If you're linking to the same page with different query string parameters, you only need to include ? and after.
<%# Eval("name_kat") %>
You could use <asp:hyperlink id="linking" runat="server" ><%# Eval("name_kat") %></asp:hyperlink> instead. You can then add your url in the navigateURL attribute and append your id_kat on there.
Something like this should work:
<asp:hyperlink id="linking" runat="server" navigateURL="~/page.aspx?id_kat=<%# Eval('id_kat') %>" ><%# Eval("name_kat") %></asp:hyperlink>
the <asp:hyperlink> tag is essentially the tag but using a server side control.
If you have to use a linkbutton then in your code behind you can append the id_kat to the querystring and then response.redirect(url) to the new page.
Why not use a regular anchor?
<a href='foo.aspx?id=<%# Eval("id_kat") %>'><%# Eval("name_kat") %></a>

Resources