Remove querystring value inside repeater - c#

I have the below code (parts removed for ease of reading)
<asp:Repeater ID="rptMenu" runat="server" OnItemDataBound="rptMenu_ItemDataBound">
<ItemTemplate>
<li>
<asp:HyperLink ID="hlCountries" runat="server" class="lang__option">
<asp:Image ID="imgGut" runat="server" />
<asp:Label ID="lblName" runat="server" Text=""></asp:Label>
</asp:HyperLink>
</li>
</ItemTemplate>
</asp:Repeater>
In my Item data bound (Again some code removed for ease of reading but can show if required)
protected void rptMenu_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
//var nvc = HttpUtility.ParseQueryString(Request.Url.Query);
//nvc.Remove("c");
//string url = Request.Url.AbsolutePath + "?" + nvc.ToString();
hlCountries.NavigateUrl = string.Format("{0}/?c={1}",
System.Web.HttpContext.Current.Request.Url.AbsoluteUri, p.Id);
}
}
Page load i bind the data.
When the menu hyperlink is selected it adds a parameter to the URL load some data based on the query value passed in.
When the next item in the menu item is clicked it adds another parameter i.e.
Page load: getdata
Click first item getdata?c=1
Click second item getdata?c=1c=2
(notice how the c= is repeated) How could i avoid this from happening? I added the above commented out code but that didnt work?

You should use UriBuilder when building Uri instead of string concatenation
var builder = new UriBuilder(this.Request.Url);
var nvc = HttpUtility.ParseQueryString(this.Request.Url.Query);
nvc.["c"] = p.Id;
builder.Query = nvc.ToString();
hlCountries.NavigateUrl = builder.Uri.PathAndQuery;

Related

Nested repeater will not display bound information from list

I am trying to get a page to display information in a row layout using repeaters. I have one working that allows me to dynamically create hyperlinks, however i cant get my nested repeater to work to display the date the file was created. Is it possible to use repeaters to dynamically display multiple variables from lists as i'm trying to do below?
.aspx
<asp:Repeater id="repLinks" runat="server">
<ItemTemplate>
<tr><td>
<asp:HyperLink runat="server" NavigateUrl='<%# Container.DataItem.ToString() %>' Text="<%# Container.DataItem.ToString().Split('\\').Last() %>" />
<td>
<asp:Repeater ID="Repeater2" runat="server" OnItemDataBound="Repeater2_ItemDataBound" >
<ItemTemplate>
<%# Container.DataItem.ToString()%>
</ItemTemplate>
</asp:Repeater>
</td>
<td>
Submitted By <!--add repeater-->
</td>
<td>
Mark as Billed <!--add repeater-->
</td>
</td></tr>
</ItemTemplate>
</asp:Repeater>
.aspx.cs
public List<string> CD = new List<string>();
protected void Page_Load(object sender, EventArgs e)
{
//Welcomes User
string Uname = Environment.UserName;
UserName.Font.Size = 17;
UserName.Text = "Welcome: " + Uname;
//gives path and constructs lists for directory paths and file links
string root = "C:\\Users\\James\\Documents\\Visual Studio 2015\\WebSites";
List<string> lLinks = new List<string>();
//adds files to list
foreach (var path in Directory.GetDirectories(#root))
{
foreach (var path2 in Directory.GetFiles(path))
{
lLinks.Add(path2);
CD.Add(File.GetCreationTime(path2).Date.ToString("yyyy-mm-dd"));
}
}
//Define your list contents here
repLinks.DataSource = lLinks;
repLinks.DataBind();
}
protected void Repeater2_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Repeater Repeater2 = (Repeater)(e.Item.FindControl("Repeater2"));
Repeater2.DataSource = CD;
Repeater2.DataBind();
}
}
The issue with your code is that you are binding the nested repeater control (Repeater2) in the ItemDataBound event of Repeater2 repeater itself which will never get fired because ItemDataBound event is fired for each item in collection when it is bounded to the repeater control.
You should write the logic in ItemDataBound event of your parent repeater like this:-
<asp:Repeater id="repLinks" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
Then, write the logic in this event handler:-
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
Repeater Repeater2 = (Repeater)(e.Item.FindControl("Repeater2"));
Repeater2.DataSource = CD;
Repeater2.DataBind();
}
}
Also, In the Page_Load event you should bind the Parent Repeater Repeater1 on just the initial page load so wrap it inside !IsPostBack and populate your datasource lLinks & CD from a separate method intead of doing it in Page_Load event.

Issue Related to Binding Image in <asp:Repeater> Control

I have asp.net Web Application. i have following Repeater control on the .aspx Page:
<asp:Repeater ID="repHomeList" runat="server" onitemdatabound="repHomeList_ItemDataBound">
<ItemTemplate>
<div class="pro-col">
<div class="p-img">
<asp:Image runat="server" ID="imgHomeImage" />
<asp:Label runat="server" ID="lblImageName" Visible="false" Text='<%#Eval("Images") %>'></asp:Label>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
and Following Event
protected void repHomeList_ItemDataBound(object sender, RepeaterItemEventArgs e) {
if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
return;
Image imgHomeImage = (Image)e.Item.FindControl("imgHomeImage");
Label lblImageName = (Label)e.Item.FindControl("lblImageName");
if (imgHomeImage != null && lblImageName != null)
imgHomeImage.ImageUrl = Server.MapPath("PropertyImages/" + lblImageName.Text);
}
the above code compiles fine. but Image is not displaying when DataBinds in Repeater Control.
so how to set Image on ItemDatabound event ??
Thanks
Try changing it to this instead:
imgHomeImage.ImageUrl = Server.MapPath("~/PropertyImages/" + lblImageName.Text);
Please note the ~
Ps you can get the image name server side with the following:
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
YourObject anObject = (YourObject)dataItem.DataItem;
var images = anObject.Images;
imgHomeImage.ImageUrl = Server.MapPath("~/PropertyImages/" + images);
You'd have to change YourObject to your specific object.
This would avoid the need to write them out and retrieve them.

Gridview rowdatabound error : Multiple controls with the same ID 'hlLink' were found. FindControl requires that controls have unique ID

I have a gridview that has link and description to be rendered on the page.
written the below code in gridview in .aspx
<Columns>
<asp:TemplateField>
<ItemTemplate>
<p>
<asp:HyperLink ID="hlLink" runat="server" Target="_self"></asp:HyperLink></p>
</ItemTemplate>
<ItemTemplate>
<p>
<asp:Literal ID="litSummary" runat="server"></asp:Literal></p>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<AlternatingItemTemplate>
<p>
<asp:HyperLink ID="hlLink" runat="server" Target="_self"></asp:HyperLink></p>
</AlternatingItemTemplate>
<AlternatingItemTemplate>
<p>
<asp:Literal ID="litSummary" runat="server"></asp:Literal></p>
</AlternatingItemTemplate>
</asp:TemplateField>
</Columns>
and below in .aspx.csin gridview rowdataboundevent
protected void gvResults_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
SearchResultItem data = (SearchResultItem)e.Row.DataItem;
HyperLink hlLink = (HyperLink)e.Row.FindControl("hlLink");
Literal litSummary = (Literal)e.Row.FindControl("litSummary");
if (data.Description != null)
{
hlLink.Text = data.Title;
hlLink.NavigateUrl = data.Path.Replace("&", "&");
litSummary.Text = data.Description;
}
else
{
hlLink.Text = data.Path;
hlLink.NavigateUrl = data.Path.Replace("&", "&");
litSummary.Text = data.Path;
}
}
here SearchResultItem: is the result item that has link and description details.
First time when row bound event is called, it binds the data correctly, second time when called throws error "Multiple controls with the same ID 'hlLink' were found. FindControl requires that controls have unique IDs.
Please let me know whats error with the code.
Thanks
Problem : you are trying to create the same controls with same ID multiple times.
Solution : you need to remove the controls before creating them.
Try This:
void RemoveControls()
{
HyperLink l1 = (HyperLink)Page.FindControl("hlLink");
Literal l2 = (Literal)Page.FindControl("litSummary");
if(l1!= null)
Page.Controls.Remove(l1);
if(l2!= null)
Page.Controls.Remove(l2);
}
Solution 2: Pagination for Repeater control.
for implementing pagination in Repeater control you need to create PagedDataSource.
Try This:
PagedDataSource pds = new PagedDataSource();
pds.DataSource = ds.Tables[0].DefaultView;
pds.AllowPaging = true;
pds.PageSize = 8;//page sizes

Firing different linkbuttons in a Repeater and saving the value of each in an arraylist

Im using a repeater to display some products in an online shop for a school project. This is how the front end looks with the repeater
<asp:Repeater ID="Repeater1" runat="server" OnItemCommand="rptList_ItemCommand">
<ItemTemplate>
<span style="float:left; padding:25px;" class="backgrnd">
<asp:ImageButton ID="imgProd" runat="server" style="width:150px; height:150px;" ImageUrl='<%# DataBinder.Eval(Container.DataItem, "productImg")%>' CommandArgument='<%# DataBinder.Eval(Container.DataItem, "productID")%>' CommandName="ViewIndividProd"/><br />
<p style="clear:left;">
<asp:Label ID="lbName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "productName")%>' /><br />
<asp:Label ID="lbUnitPrice" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "unitPrice")%>'/><br />
<asp:Label ID="lbRatings" runat="server" Text=''>Ratings</asp:Label><br />
<asp:LinkButton ID="linkCart" runat="server" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "productID")%>' CommandName="AddToCart">Add to Cart</asp:LinkButton>
</p>
</span>
</ItemTemplate>
</asp:Repeater>
As you can see I've added on the OnItemCommand in the Repeater tag so that this is invoked whenever one of the buttons(image/link) is fired. That works perfectly fine for both commandname AddToCart and ViewIndividProd. However, i want to store the the productid of a specific item that was invoked by the particular button. In my case now, it only stores ONE productid in the arraylist at a time and 'forgets' the productid that was stored previously when another linkbutton is clicked.
Question How do i make it such that everytime a linkbutton in the repeater is fired, it remembers the productid pertaining to the linkbutton that was fired and save these ids into the arraylist?
This is how the back end looks
ArrayList cart = new ArrayList();
protected void rptList_ItemCommand(object sender, RepeaterCommandEventArgs e) {
if (e.CommandName == "ViewIndividProd") {
Session["productID"] = e.CommandArgument.ToString();
Response.Redirect("IndividProduct.aspx");
}
if (e.CommandName == "AddToCart") {
string prodid = e.CommandArgument.ToString();
cart.Add(prodid);
Session["ShoppingCart"] = cart;
Response.Redirect("IndividCat.aspx");
}
msg.Text = "Shopping cart: " + String.Join(",", cart.ToArray());
}
Your feedback would be much appreciated.
You need to understand the Asp.net Page life cycle.
A new instance of your Page object is created on every request.
Values from your input are populated into it.
Your array list is getting recreated every time.
If you want the values to persist, you will have to store your arraylist in the ViewState or the Session
Refer: How to: Save Values in View State
void Page_Load(object sender, EventArgs e)
{
if (ViewState["arrayListInViewState"] != null)
{
PageArrayList = (ArrayList)ViewState["arrayListInViewState"];
}
else
{
// ArrayList isn't in view state, so we need to create it from scratch.
PageArrayList = CreateArray();
}
// Code that uses PageArrayList.
}
We can store comma separated or JSON value in either Session or hidden variable (If you are on the same page and opening new page in different tab then we can use hidden variable also). So every time an button has been click we can append the product id.

Repeater which Event to use to find a control inside the repeater

I use asp.net and c#4.
I have a repeater within inside a HyperLink Control.
I need to Find the HyperLink Control and change some of its properties with some logic before rendering it on the page.
With my code here posted I get a null value for the control so I'm not able to get it.
Any idea what I'm doing wrong? Thanks for your time on this.
<asp:Repeater ID="RepeaterEditorsChoice" runat="server" DataSourceID="ObjectDataSourceEditorsChoice"
OnItemCreated="RepeaterEditorsChoice_ItemCreated" OnItemDataBound="RepeaterEditorsChoice_ItemDataBound">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:HyperLink ID="uxLink" runat="server"></asp:HyperLink>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
CODE BEHIND:
protected void RepeaterEditorsChoice_ItemCreated(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
HyperLink myLink = (HyperLink)((Repeater)sender).FindControl("uxLInk"); // ERROR: it is null
dynamic o = e.Item.DataItem;
if (o.TypeContent == "AR")
{
myLink.Text = #"'<%# Eval(\""Title\"") %>'";
myLink.NavigateUrl = #"'<%# GetRouteUrl(""ArticleDetails"", new {ContentId = Eval(""ContentId""), TitleUrl = Eval(""TitleUrl"")}) %>'";
}
if (o.TypeContent == "BP")
{
myLink.Text = #"'<%# Eval(\""Title\"") %>'";
myLink.NavigateUrl = #"'<%# GetRouteUrl(""BlogPostDetails"", new {ContentId = Eval(""ContentId""), TitleUrl = Eval(""TitleUrl"")}) %>'";
}
}
}
On item data bound
then just (YourClass)e.Item.FindControl("its name");

Categories