I have three repeaters with a parent child relationship (so we have a parent repeater, and child repeater, and a child-child repeater) with the inner-most repeater not being triggered. here is my aspx page for the layout:
<asp:Repeater ID="rptMission" runat="server">
<HeaderTemplate>
<ul id="acc1" class="ui-accordion-container">
</HeaderTemplate>
<ItemTemplate>
<li>
<div class="ui-accordion-left"></div>
<a class="ui-accordion-link acc1"><%# Eval("Name") %><span class="ui-accordion-right"></span></a>
<div>
<ul class="ui-accordion-container" id="acc2">
<asp:Repeater ID="rptActivity" runat="server">
<ItemTemplate>
<li>
<div class="ui-accordion-left"></div>
<a class="ui-accordion-link acc2"><%# Eval("Name") %>
<span class="ui-accordion-right"></span></a>
<div>
<asp:Repeater ID="rptProject" runat="server">
<ItemTemplate>
<%# Eval("Name") %><br/>
</ItemTemplate>
</asp:Repeater>
</div>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
</div>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
The top two repeaters work great but the 'rptProject' repeater doesn't get triggered. Here is my code behind:
protected void Page_Load(object sender, EventArgs e)
{
_presenter = new TierTypesPresenter(this);
rptMission.ItemDataBound += new RepeaterItemEventHandler(rptMission_ItemDataBound);
RaiseStartUp();
}
void rptMission_ItemDataBound(Object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
Mission row = (Mission)item.DataItem;
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
var rptActivity = (Repeater)item.FindControl("rptActivity");
var activity = _presenter.GetActivitiesByMission(row.Id);
rptActivity.DataSource = activity;
rptActivity.DataBind();
}
}
void rptActivity_ItemDataBound(Object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
Activity row = (Activity)item.DataItem;
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
var rptProject = (Repeater)item.FindControl("rptProject");
var project = _presenter.GetProjectsByActivities(row.Id);
rptProject.DataSource = project;
rptProject.DataBind();
}
}
public void SetMissions(IEnumerable<Mission> missionList)
{
rptMission.DataSource = missionList;
rptMission.DataBind();
}
If I could trigger the second ItemDataBound event 'rptActivity_ItemDataBound' I think it would work fine but it gets skipped over. Thanks for any insight!
I solved my problem by putting the third repeater binding into the second repeaters ItemBoundEvent. Here is the updated code for any interested:
void rptMission_ItemDataBound(Object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
Mission row = (Mission)item.DataItem;
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
var rptActivity = (Repeater)item.FindControl("rptActivity");
var activity = _presenter.GetActivitiesByMission(row.Id);
var i = 0;
foreach (Activity data in activity)
{
RepeaterItem activityItem = rptActivity.Items[i];
var rptProject = (Repeater)activityItem.FindControl("rptProject");
var project = _presenter.GetProjectsByActivities(data.Id);
rptProject.DataSource = project;
rptProject.DataBind();
i++;
}
rptActivity.DataSource = activity;
rptActivity.DataBind();
}
}
I guess you are missing this line of code:
rptActivity .ItemDataBound += new RepeaterItemEventHandler(rptActivity_ItemDataBound);
It is easier to set the events in the asp file by the way...
Related
I'm trying to get a column value of the first element on a repeater, and use it on the repeater's HeaderTemplate. After searching and trying many ways of achieving this through intellisense, I gave up and decided to post this question here.
My code is as follows:
Frontend
<asp:Repeater ID="states" runat="server">
<HeaderTemplate>
<h1>Stage: <asp:Literal ID="stageName" runat="server"></asp:Literal></h1>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><%# DataBinder.Eval(Container.DataItem, "StateName") %></li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
Backend
protected void BindStageStates()
{
List<StagesStatesModel> statesList = App.Services.Stages.StagesService.GetStatesByStage(Page.DefaultApp, 1, Page.DefaultCultureId).Where(p => p.StateActive == true).ToList();
states.ItemDataBound += new RepeaterItemEventHandler(rptStagesStatesDataBound);
states.DataSource = statesList;
states.DataBind();
}
void rptStagesStatesDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Header)
{
Literal stageName = (Literal)e.Item.FindControl("stageName");
stageName.Text = // Something to go here..
}
}
Thanks in advance!
Try OnItemCreated
protected void Repeater_OnItemCreated(Object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Footer)
{
e.Item.FindControl(ctrl);
}
if (e.Item.ItemType == ListItemType.Header)
{
e.Item.FindControl(ctrl);
}
}
By:
How to find controls in a repeater header or footer
I have this code for a blog which is nesting a repeater control within a datalist.
I'm trying to assign the alt tags of the repeater control images to be the title of the post coming through the datalist however, it will not let me though this because it has a different data source.
Any suggestions as to how I can do this?
Here's my code:
<asp:DataList runat="server" ID="DataList1" ItemStyle-CssClass="row1BackgroundBlock" OnItemDataBound="DataList1_ItemDataBound" >
<ItemTemplate>
<!-- <%#Eval("PostId")%> post -->
<div class="dateBox"><asp:Label ID="Label1" runat="server" ForeColor="#ffffff" Font-Bold="False" Text='<%# Eval("PublicationDate","{0:dd/MM/yyyy}") %>' CssClass="postmetadata"></asp:Label></div>
<div class="roundPanelStack">
<h2><asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Engine2010.Blog.BlogLinksManager.GetFullPostsLinks((int)Eval("PostId"), (object)Eval("FURL")) %>'><%# Eval("Title") %></asp:HyperLink></h2>
<ul><li class="postBy">Posted in <%#Eval("CategoryName")%> by <%#Eval("Author")%></li><li class="last">{<%# Engine2010.Blog.PostComment.GetAllByPostId(int.Parse(Eval("PostId").ToString()), 766).Rows.Count.ToString()%> comments}</li></ul>
<div class="thumbWindow">
<div style="border:7px solid #fff;display:block;height:95px;left:1px;position:absolute;top:1px;width:95px;z-index:5;"></div>
<asp:Repeater ID="repImgs" runat="server">
<ItemTemplate>
<img class="thumb_view" src="/uploads/images/Blog/<%# Eval("Directory").ToString().Substring(Eval("Directory").ToString().LastIndexOf("\\")+1) %>/<%# Eval("Name") %>" alt="" border="0" width="143" height="143" />
</ItemTemplate>
</asp:Repeater>
<asp:PlaceHolder ID="PlaceHolder1" runat="server" Visible="false">
<img src="/includes/images/general/default.jpg" alt="Default" border="0" width="110" height="110" />
</asp:PlaceHolder>
</div>
<p>
<asp:Label ID="Label2" runat="server" Text='<%#CommonFunctions.Remove_HTML_Tags(Eval("Description").ToString()) %>' CssClass="entry"></asp:Label>
</p>
<div class="linksMore">
<asp:HyperLink ID="FullStoryLink" runat="server" NavigateUrl='<%# Engine2010.Blog.BlogLinksManager.GetFullPostsLinks((int)Eval("PostId"), (object)Eval("FURL")) %>' CssClass="fullstory">Read Full Post</asp:HyperLink><a class="spacer"> // </a><asp:HyperLink ID="CommentsLink" runat="server" NavigateUrl='<%# Engine2010.Blog.BlogLinksManager.GetFullPostsLinks((int)Eval("PostId"), (object)Eval("FURL")) + "#comment" %>' CssClass="comments">Comment</asp:HyperLink>
</div>
</div>
<!-- /first post -->
</ItemTemplate>
</asp:DataList>
Backend:
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Repeater repImages = (Repeater)e.Item.FindControl("repImgs"); // Child repeater with images for room
string amenText = ((DataRowView)e.Item.DataItem).Row.ItemArray[7].ToString();
DirectoryInfo folderBr = new DirectoryInfo(Server.MapPath("~/uploads/images/Blog/") + amenText);
// List<Engine2010.ImageObj> imageObjs = folderBr.GetImagesInPath();
if (folderBr.Exists)
{
repImages.DataSource = folderBr.GetFiles("thumb*.*"); // Bind room images to child repeater
repImages.DataBind();
if (repImages.Items.Count == 0)
{
PlaceHolder placeholder1 = (PlaceHolder)e.Item.FindControl("PlaceHolder1");
placeholder1.Visible = true;
}
}
else {
PlaceHolder placeholder1 = (PlaceHolder)e.Item.FindControl("PlaceHolder1");
placeholder1.Visible = true;
}
}
}
In the ItemDataBound event of your DataList1 after binding repImages repater control, iterate through each item by using RepeaterItem and then find your img control and assign title in alt tag like this -
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Repeater repImages = (Repeater)e.Item.FindControl("repImgs");
string amenText = ((DataRowView)e.Item.DataItem).Row.ItemArray[7].ToString();
DirectoryInfo folderBr = new DirectoryInfo(Server.MapPath("~/uploads/images/Blog/") + amenText);
if (folderBr.Exists)
{
repImages.DataSource = folderBr.GetFiles("thumb*.*"); // Bind room images to child repeater
repImages.DataBind();
if (repImages.Items.Count == 0)
{
PlaceHolder placeholder1 = (PlaceHolder)e.Item.FindControl("PlaceHolder1");
placeholder1.Visible = true;
}
// Iterate thru each item of your child repeate control.
foreach (RepeaterItem repeaterItem in repImages.Items)
{
if (repeaterItem.ItemType == ListItemType.Item ||
repeaterItem.ItemType == ListItemType.AlternatingItem)
{
((HtmlImage)(repeaterItem.FindControl("imgId"))).Alt = amenText; // Assume amenText is the title of your post
}
}
}
else
{
PlaceHolder placeholder1 = (PlaceHolder)e.Item.FindControl("PlaceHolder1");
placeholder1.Visible = true;
}
}
}
good luck...
I am using Bootstrap's Progress Bar inside a repeater to show score of different items. The aspx is like this:
<asp:Repeater ID="rptFinalScore" runat="server" OnItemDataBound="rptFinalScore_ItemDataBound">
<ItemTemplate>
<div class="row">
<div class="col-sm-2">
<asp:Label ID="rpt_Score" runat="server" Text='<%#Eval("TotalScore") %>'>></asp:Label>
</div>
<div class="col-sm-10">
<div class="progress">
<div id="rpt_proBar" class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" runat="server">
</div>
</div>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
and the codebehind is:
protected void rptFinalScore_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
foreach (RepeaterItem item in rptFinalScore.Items)
{
if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
{
var Score = item.FindControl("rpt_Score") as Label;
var ProgBar = item.FindControl("rpt_proBar") as HtmlGenericControl;
string BuildingScore = ((Label)Score).Text;
ProgBar.Attributes.Add("style", string.Format("width:{0}%;", BuildingScore));
}
}
}
The problem I am facing is that if suppose there are 5 items in the repeater then it will correctly apply the style="width:x%" to first 4 items but not for the last item. The output is like this. Can someone please help me out with this.
Why are you looping in each ItemDataBound event handler call ? You have to set styles for the corresponding item that's stored in e argument. Last item's style is not set because repeater doesn't have that item in its Items collection when ItemDataBound event is fired.
You have to change your ItemDataBound handler to something like this:
protected void rptFinalScore_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var Score = e.Item.FindControl("rpt_Score") as Label;
var ProgBar = e.Item.FindControl("rpt_proBar") as HtmlGenericControl;
string BuildingScore = ((Label)Score).Text;
ProgBar.Attributes.Add("style", string.Format("width:{0}%;", BuildingScore));
}
}
ASPX PAGE:
<asp:Repeater ID="GeneralRepeater" runat="server"
OnItemDataBound="GeneralRepeater_OnItemDataBound">
<ItemTemplate>
<tr>
<td>
DxPoc:
<asp:DropDownList ID="GeneralDDL" DataTextField="DiagnosisCode"
DataValueField="DiagnosisCode" runat="server" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
CODE BEHIND:
protected void GeneralRepeater_OnItemDataBound(object sender,
RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
DropDownList myDDL = (DropDownList)e.Item.FindControl("GeneralDDL");
Diagnosis oDiagnosis = new Diagnosis();
DataView dv = new DataView(oDiagnosis.GetDiagnosis());
myDDL.DataSource = dv;
myDDL.DataTextField = "DiagnosisCode";
myDDL.DataValueField = "DiagnosisCode";
myDDL.DataBind();
}
}
The given shown above is not working properly. During page load it nothing happens on the
dropdownlist inside the repeater.
QUESTIONS:
a.) How I'll get the values of my dropdownlist with list of objects inside the repeater?
thanks!
if(!IsPostBack)
{
BindRepeater();
}
I know how to use a simple If statement wrapped in the <%# tags to hide something, but I don't know how to do it in a repeater when I need to access Container.DataItem, as in I need the dataItem currently being 'repeated'
eg
if (CurrentValidationMessage.Link != "")
{
show a hyperlink
}
Markup:
<asp:Repeater ID="repValidationResults" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<a href='<%# ((MttImportValidationMessage)Container.DataItem).EditLink %>'> Link to erroneous Milestone </a>
<%# ((MttImportValidationMessage)Container.DataItem).Message %>
<br />
</ItemTemplate>
</asp:Repeater>
It might be more maintainable if you just tagged the controls in the repeater with id's and runat='server' and reference the DataItem in the ItemDataBound event by using e.Item.DataItem.
Then use e.Item.FindControl to reference your controls in the ItemTemplate and perform your logic.
protected void repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
Domain.Employee employee = (Domain.Employee)e.Item.DataItem;
Control myControl = (Control)e.Item.FindControl("controlID");
//Perform logic
}
}
use ItemDataBound Event with repeater, and make the "a" tag with a runat="server" property and ID
protected void repValidationResults_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
if (item.ItemType == ListItemType.AlternatingItem || item.ItemType == ListItemType.Item)
{
HyperLink link = (HyperLink) item.FindControl("link");
//Do all your logic here :)
}
}
MarkUp:
<asp:Repeater ID="repValidationResults" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<a runat="server" ID="link"> Link to erroneous Milestone </a>
<%# ((MttImportValidationMessage)Container.DataItem).Message %>
<br />
</ItemTemplate>
</asp:Repeater>