How to bind Nested Repeaters? - c#

I have a service page, which shows service details and has a sub-section like service features and charges. I created two repeaters for features and charges. Please refer to the following sql tables image for more information:
But I have no idea how to bind this hierarchical data to nested repeaters. Here is my code:
<!--Nested Repeater Section-->
<asp:Repeater ID="ServiceDetailsRepeater" runat="server"
onitemdatabound="ServiceDetailsRepeater_ItemDataBound">
<ItemTemplate>
<asp:HiddenField ID="service_id" runat="server" Value='<%#Eval("Id")%>'/>
<h3><a name='<%#Eval("Id")%>'></a><%#Eval("Service_name")%></h3>
<img src='<%# "images/"+ Eval("ImageName")%>' alt="picture" width="48" height="48" class="img" />
<p><%#Eval("Service_desc")%></p>
<div id="Div1" class="clr" runat="server"> </div>
<div id="Div2" class="box" runat="server">
<div id="Div3" class="box_t" runat="server">
<asp:Panel ID="Panel_ServiceFeature" runat="server" class="box_b">
<h2>Features</h2>
<ul style="font-family:Arial, Helvetica, sans-serif;font-size:11px;color:#5f5f5f">
<asp:Repeater ID="ServiceFeatureRepeater" runat="server">
<ItemTemplate>
<li><%#Eval("Feature_Text")%></li>
</ItemTemplate>
</asp:Repeater>
</ul>
</asp:Panel>
</div>
</div>
<div id="Div5" class="clr" runat="server"> </div>
<div id="Div6" class="box" runat="server">
<div id="Div7" class="box_t" runat="server">
<asp:Panel ID="Panel_ServiceCharge" runat="server" class="box_b">
<h2>Charges</h2>
<table style="font-family:Arial, Helvetica, sans-serif;font-size:11px;color:#5f5f5f">
<tr><td></td>
<td>Rs.</td><td> </td><td align="left">Months</td></tr>
<asp:Repeater ID="ServiceChargeRepeater" runat="server">
<ItemTemplate>
<tr>
<td><img src="images/sub_nav.gif" width="18px" height="14px" alt=""/></td>
<td>Rs. <%#String.Format("{0:#,###}", Eval("Charges_Per_Month"))%></td>
<td> </td>
<td><%#Eval("No_Of_Month")%> Months</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
</asp:Panel>
</div>
</div>
<div id="Div9" class="clr" runat="server"></div>
</ItemTemplate>
</asp:Repeater>
<!--End Section-->
Finally, my web site page this is my live web site service page view. This page is static but now I want to bind this service details with database.

One way to do it is to simply bind the DataSource property of the inner Repeater to a suitable collection. E.g. something like:
<asp:Repeater ID="ServiceDetailsRepeater" runat="server"
DataSourceID="SqlDataSource1">
<asp:Repeater ID="ServiceFeatureRepeater" runat="server"
DataSource="<%# DatabaseHelper.GetFeatures(Eval("Id")) %>">
...
</asp:Repeater>
<asp:Repeater ID="ChargesRepeater" runat="server"
DataSource="<%# DatabaseHelper.GetCharges(Eval("Id")) %>">
...
</asp:Repeater>
</asp:Repeater>
i have also check if no features or charges are found to particular service then panel have to off. so i directly doing from code behind
UPDATE
If you're more comfortable doing it from code-behind, go ahead, but you could also do it declaratively by databinding the Repeater's Visible property, e.g.:
...
<asp:Repeater ID="ServiceFeatureRepeater" runat="server"
DataSource="<%# DatabaseHelper.GetFeatures(Eval("Id")) %>"
Visible="<%# DatabaseHelper.HasFeatures(Eval("Id")) %>"
>
...
</asp:Repeater>
....

if (!Page.IsPostBack)
{
ServiceListRepeater.DataSource = DatabaseHelper.GetSummaryOfActiveServices();
ServiceListRepeater.DataBind();
ServiceDetailsRepeater.DataSource = DatabaseHelper.GetSummaryOfActiveServices();
ServiceDetailsRepeater.DataBind();
}
protected void ServiceDetailsRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
if ((item.ItemType == ListItemType.Item) ||(item.ItemType == ListItemType.AlternatingItem))
{
HiddenField service_id = (HiddenField)item.FindControl("service_id");
Repeater service_features = (Repeater)item.FindControl("ServiceFeatureRepeater");
service_features.DataSource = DatabaseHelper.GetFeatureSummary(int.Parse(service_id.Value.ToString()));
service_features.DataBind();
if (service_features.Items.Count == 0)
{
Panel Panel_ServiceFeature = (Panel)item.FindControl("Panel_ServiceFeature");
Panel_ServiceFeature.Visible = false;
}
Repeater service_charges =(Repeater)item.FindControl("ServiceChargeRepeater");
service_charges.DataSource = DatabaseHelper.GetChargeSummary(int.Parse(service_id.Value.ToString()));
service_charges.DataBind();
if (service_charges.Items.Count == 0)
{
Panel Panel_ServiceCharge = (Panel)item.FindControl("Panel_ServiceCharge");
Panel_ServiceCharge.Visible = false;
}
}
}

Related

Get LinkButton Embedded Label value

Get LinkButton Embedded Label value?
Also issue with LinkButton on postback comes back empty.
I basically need a clickable row to run a server side function is there a better way then a LinkButton?
I'm basically creating a search dropdown.
ASPX
<asp:ListView ID="listView" runat="server" ShowFooter="true" AutoGenerateColumns="false">
<ItemTemplate>
<asp:Repeater ID="SearchResults" OnItemCommand="SetValues_ItemCommand" runat="server">
<ItemTemplate>
<div class="form-row">
<asp:LinkButton ID="MemberInfo" runat="server" class="list-group-item list-group-item-action flex-column align-items-start mb-2" OnClick="MemberInfo_Click" CommandArgument='<%# Container.ItemIndex %>'>
<div class="col-lg-12 mb-2">
<h5 class="mb-1">
<asp:Label ID="PrimaryOrganization" runat="server" Text='<%# Eval("PrimaryOrganization") %>'></asp:Label>
</h5>
</div>
</asp:LinkButton>
</div>
</ItemTemplate>
</asp:Repeater>
CS
protected void MemberInfo_Click(object sender, EventArgs e)
{
LinkButton MemberInfoBNT = (LinkButton)sender;
bool bIsConverted = int.TryParse(MemberInfoBNT.CommandArgument.ToString(), out int index);
if (bIsConverted)
{
Repeater SearchResultsObject = MemberInfoBNT.Parent.Parent as Repeater;
ListViewDataItem listViewData = MemberInfoBNT.Parent.Parent.Parent as ListViewDataItem;
int Listviewindex = listViewData.DataItemIndex;
Label PrimaryOrganization = (Label)SearchResultsObject.Items[index].FindControl("PrimaryOrganization");
TextBox registrantEmailValue = (TextBox)listView.Items[Listviewindex].FindControl("registrantEmail");
registrantEmailValue.Text = PrimaryOrganization.Text;
}
}
Image of results
Select2 provides you a customizable dropdownlist with support for searching

Find Controls nested inside Repeater Control

I'm trying to find the values of TextBoxes which are rendered in a Repeater though a UserControl, i.e. the Repeater has a Placeholder for the UserControl, and inside the UserControl is where the TextBox markup actually exists. I've done this before with TextBoxes directly inside of a Repeater before, which was fairly straight forward, and I'm wondering why this apparently can't be accomplished the same way. Here is the Default page with the Repeater, which contains a Placeholder...
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<form class="formee">
<fieldset>
<legend>Faculty Information</legend>
<div class="grid-4-12">
<asp:Label ID="lblFirstName1" runat="server" Text="First Name"></asp:Label>
<asp:Label ID="lblFirstName2" runat="server" Text="" ></asp:Label>
<asp:Label ID ="lblSalary" runat="server" Text="" ClientIDMode="Static"></asp:Label>
</div>
<div class="grid-6-12">
<asp:Label ID="lblLastName1" runat="server" Text="Last Name"></asp:Label>
<asp:Label ID="lblLastName2" runat="server" Text=""></asp:Label>
</div>
</fieldset>
</form>
<div id="repeaterDiv">
<asp:Repeater ID="rptBudget" runat="server" ClientIDMode="Static">
<ItemTemplate>
<asp:PlaceHolder ID="phBudget" runat="server" EnableViewState="true" />
<br />
</ItemTemplate>
</asp:Repeater>
<asp:Button ID="btnAddBudgetControl" runat="server" Text="Add"
CausesValidation="false" OnClick="AddBudgetControl" CssClass="addBudgetControl"/>
<asp:Button ID="btnDisplayEntries" runat="server" Text="Display Entries" CausesValidation="false" OnClick="DisplayEntries" />
</div>
<div>
<asp:TextBox ID="txtTotalPercent" runat="server" ClientIDMode="Static"></asp:TextBox>
<asp:TextBox ID="txtGrandTotal" runat="server" ClientIDMode="Static"></asp:TextBox>
<asp:Label ID="lblCtrls" runat="server" Text=""></asp:Label>
</div>
...and the UserControl which is inserted in the place of the Placeholder...
<fieldset>
<legend>Faculty Salary Form</legend>
<table cellspacing="10" id="values">
<tr>
<td>
<asp:Label ID="lblServiceType" runat="server" Text="Service"></asp:Label>
<asp:DropDownList runat="server" ID="ddlServiceType" CssClass="serviceType" />
</td>
<td>
<asp:Label ID="lblSpeedCode" runat="server" Text="Speed Code"></asp:Label>
<asp:DropDownList runat="server" ID="ddlSpeedCode" CssClass="speedType" />
</td>
<td>
<asp:Label ID="lblPercentage" runat="server" Text="Percentage"></asp:Label>
<asp:Textbox ID="txtPercentage" runat="server" CssClass="percentCommitment" ClientIDMode="Static" EnableViewState="true" />
</td>
<td>
<asp:Label ID="lblTotal" runat="server" Text="Total"></asp:Label>
<asp:TextBox ID="txtTotal" runat="server" CssClass="amountCommitment" ClientIDMode="Static" EnableViewState="true"/>
</td>
<td>
<asp:Button ID="btnRemove" runat="server" Text="Remove Item" OnClick="RemoveItem" ClientIDMode="Static" CssClass="btnRemove" />
</td>
</tr>
<tr>
</tr>
</table>
</fieldset>
...but when the following code runs for the Display button's OnClick, I always get a null value for any and all TextBoxes (and DropDowns) in the UserControl...
protected void DisplayEntries(object sender, EventArgs e)
{
foreach (RepeaterItem repeated in rptBudget.Items)
{
TextBox txtPercentage = (TextBox)repeated.FindControl("txtPercentage");
if (txtPercentage == null)
{
lblCtrls.Text += " null; ";
}
else
{
lblCtrls.Text += txtPercentage.Text + "; ";
}
}
}
What's the best way to access these values? Thanks.
txtPercentage Textbox is located inside Usercontrol, so use the following helper method to retrieve it.
Helper Method
public static Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
return root;
return root.Controls.Cast<Control>()
.Select(c => FindControlRecursive(c, id))
.FirstOrDefault(c => c != null);
}
Usage
foreach (RepeaterItem repeated in rptBudget.Items)
{
TextBox txtPercentage =
(TextBox)FindControlRecursive(repeated, "txtPercentage");
...
}
Try loading the placeholder first and then looking for the textboxes in the placeholder:
Something like this:
pseudo
var ph = repeated.FindControl("phBudget");
var txtBox = ph.FindControl("txtPercentage");
/pseudo
You need to first get the UserControl, then use FindControl on the UC itself.

Setting visibility of a link in code behind

i have this in source code:
<a href="CreateAlbum.aspx" id="createalbumlink">
Create New Album
</a>
now i want to set its visibility in code behind. How can i do so? I have this link within ListView Control.
I replaced the above with
<asp:LinkButton ID="LinkButton1" runat="server" PostBackUrl="~/CreateAlbum.aspx"> Create New Album1</asp:LinkButton>
still couldnt detect in codebehind.
SOurce code:
<form id="form1" runat="server">
<asp:ListView ID="lvAlbums" runat="server"
DataSourceID="SqlDataSource1" GroupItemCount="3"
InsertItemPosition="LastItem">
<LayoutTemplate>
<table border="1">
<tr ID="groupPlaceholder" runat="server">
</tr>
</table>
</LayoutTemplate>
<GroupTemplate>
<tr>
<td ID="itemPlaceholder" runat="server">
</td>
</tr>
</GroupTemplate>
<ItemTemplate>
<td id="Td3" width="150px" height="150px" align="center" style="background-color: #e8e8e8;color: #333333;">
<asp:HiddenField ID="hfPhotoID" runat="server" Value='<%# Eval("DefaultPhotID") %>' />
<a href='<%# "Photos.aspx?AlbumID="+Eval("AlbumID") %>'>
<asp:Image CssClass="Timg" runat="server" ID="imPhoto" ImageUrl='<%# "ThumbNail.ashx?ImURL="+Eval("Photo") %>' />
</a>
<br />
<b><asp:Label ID="lblAlbumName" runat="server" Text='<%# Eval("AlbumName") %>'></asp:Label> </b>
</td>
</ItemTemplate>
<InsertItemTemplate>
<td id="Td3" width="150px" height="150px" runat="server" align="center" style="background-color: #e8e8e8;color: #333333;">
<asp:LinkButton ID="LinkButton1" runat="server" PostBackUrl="~/CreateAlbum.aspx"> Create New Album1</asp:LinkButton>
<%-- <a href="CreateAlbum.aspx" id="createalbumlink" runat="server">
Create New Album
</a>--%>
</td>
</InsertItemTemplate>
</asp:ListView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:SLIITComDBConnectionString %>"
SelectCommand="SELECT Album.AlbumID, Album.DefaultPhotID, Album.AlbumName, PhotAlbum.Photo FROM Album INNER JOIN PhotAlbum ON Album.DefaultPhotID = PhotAlbum.PhotoID where album.userid=#userid">
<SelectParameters>
<asp:QueryStringParameter Name="userid" Type="int32" QueryStringField="id" />
<%--<asp:SessionParameter Name="userid" Type="String" SessionField="UserId" />--%>
</SelectParameters>
</asp:SqlDataSource>
</form>
Well you can't access the LinkButton directly since its inside a ListView, you can iterate through each item in the ListView and find the link button using FindControl and then set the Visible property. Something like:
foreach (ListViewItem item in listView.Items)
{
LinkButton linkButton = item.FindControl("LinkButton1") as LinkButton;
if (linkButton != null)
linkButton.Visible = false;
}
the above will disable LinkButton for all the items.
Use the OnClick event handler of the LinkButton and toggle the visibility there.
Somewhere in the code behind do this:
LinkButton1.Visible = false;
LinkButton1.Visible = false; //control will not rendered
LinkButton1.Attribute["styles"] = "display:none"; // control will be hidden
You can alse use tag, but you have to add runat="server" param
Edit
Try using FindControl:
LinkButton LinkButton1 = (LinkButton)ListView1.FindControl("LinkButton1");
LinkButton1.Visible = false;

Pass value back to server in asp.net?

In an asp.net application, I have the follow code in the aspx page:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% foreach (var questionPaper in QuestionPapers) { %>
<div style="border-bottom: 1px solid; padding-bottom:20px">
<%= questionPaper.University %><br/>
<%= questionPaper.CourseName %>: <%= questionPaper.CourseCode %><br/>
<%= questionPaper.Type %><br/>
<%= questionPaper.Year %><br/>
<asp:Button ID="View_Paper" runat="server" OnClick="ViewPaper" Text="View Paper"/>
</div>
<% } %>
</asp:Content>
I want to pass questionPaper.ID back to the ViewPaper() event handler on the server side, how do I do that?
public void ViewPaper(object sender, EventArgs e)
{
}
My recommendation is to use a Repeater or a ListView control
Use a Repeater if the data will be used as read-only
Use a ListView if you want to page your results and/or allow the end user to perform CRUD operation over your data
For example, your code would look like this when using a Repeater and an ObjectDataSource controls:
ASPX
<asp:ObjectDataSource ID="ods" runat="server"
SelectMethod="GetQuestionPapers"
TypeName="Your_Namespace.PapersRepository">
</asp:ObjectDataSource>
<asp:Repeater runat="server" DataSourceID="ods" ID="r" OnItemCommand="r_ItemCommand">
<ItemTemplate>
<div style="border-bottom: 1px solid; padding-bottom:20px">
<asp:HiddenField runat="server" ID="paperID" Value='<%# Eval("PaperID") %>'/>
<asp:Label runat="server" ID="university" Text='<%# Eval("University") %>'/><br />
<asp:Label runat="server" ID="courseName" Text='<%# Eval("CourseName") %>'/>:<asp:Label runat="server" ID="courseCode " Text='<%# Eval("CourseCode ") %>'/><br />
<asp:Label runat="server" ID="paperType" Text='<%# Eval("Type") %>' /><br />
<asp:Label runat="server" ID="year" Text='<%# Eval("Year") %>' /><br />
<asp:Button ID="View_Paper" runat="server" Text="View Paper" CommandName="ViewPaperCommand"
/>
</div>
</ItemTemplate>
<SeparatorTemplate>
<hr />
</SeparatorTemplate>
</asp:Repeater>
ASPX code behind
protected void r_ItemCommand(object sender, RepeaterCommandEventArgs e)
{
switch (e.CommandName)
{
case "ViewPaperCommand":
var hidden = e.Item.FindControl("paperID") as HiddenField;
var myPaperID = hidden.Value;
break;
}
}
Papers repository class
namespace Your_Namespace
{
public class PapersRepository
{
public IEnumerable < QuestionPaper > GetQuestionPapers()
{
return QuestionPapers.AsEnumerable();
}
}
}
You could bind it to a control and then reference that control directly?
I know you have multiple questions papers being output, so that in itself is the issue. It's been a while since I have used webforms, but could you not use a repeater control which would give you a row context within which you could get the specific question paper id you are looking for?
Use a repeater. That kind of old skool ASP classic code has no place in ASP.Net projects. Here's an example: http://www.dotnetcurry.com/ShowArticle.aspx?ID=663
It is possible to customise a repeater to make a lightweight DataGrid or ListView equivalent too.

How to hide() first element in a <asp:repeater>

This is my code :
<asp:Repeater runat="server" ID="rpUbicazione">
<ItemTemplate>
<div class="Field" style="margin-bottom:20px;">
// elements
</div>
</ItemTemplate>
</asp:Repeater>
and I'd like to hide first element. So I tried changing first line with :
<asp:Repeater runat="server" ID="rpUbicazione" Visible="<%# (Container.ItemIndex != 0) %>">
but seems it doesnt works : ItemIndex it is not a method.
How can I do it?
Try this:
<asp:Repeater runat="server" ID="rpUbicazione">
<ItemTemplate>
<div class="Field" style='margin-bottom: 20px; display: <%# Container.ItemIndex == 0 ? "none" : "block" %>'>
// elements
</div>
</ItemTemplate>
</asp:Repeater>
or you can do something like this:
<script runat="server">
protected void rpUbicazione_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemIndex == 0)
{
e.Item.FindControl("divElement").Visible = false;
}
}
</script>
<asp:Repeater runat="server" ID="rpUbicazione" onitemdatabound="rpUbicazione_ItemDataBound">
<ItemTemplate>
<div id="divElement" runat="server" class="Field" style="margin-bottom: 20px;">
// elements
</div>
</ItemTemplate>
</asp:Repeater>

Categories

Resources