Problem with Hyperlink in Repeater Control - asp.net

<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<li class="closed" >
<asp:HyperLink runat="server" CssClass="toggler off"
ImageUrl="/_layouts/images/NEXT.GIF"
Text="<%#Container.DataItem%>" ID="HyperLink1">
</asp:HyperLink>
</li>
</ItemTemplate>
</asp:Repeater>
I want to get the text in the hyperlink from the arraylist
in my ascx code
I am trying to do this bt its showing error
HyperLink hypl = (HyperLink)Repeater1.FindControl("HyperLink1");
hypl.Text = ar.ToString();
hypl.NavigateUrl = "http//www.yahoo.com";
Anyone is having idea how to resolve this problem

With a repeater control, you can't use FindControl to locate the hyperlink by name because there can be more than one (this is a template, and it gets rendered 0 to n times).
You need to do the assignment of values to the hyperlink multiple times, once for each item that is bound. This is a job for the repeater's ItemDataBound event. Try something like this:
<asp:Repeater ID="Repeater1" runat="server" onitemdatabound="Repeater1_ItemDataBound">
<ItemTemplate>
<li class="closed" >
<asp:HyperLink runat="server" CssClass="toggler off"
ImageUrl="/_layouts/images/NEXT.GIF"
Text="<%#Container.DataItem%>" ID="HyperLink1">
</asp:HyperLink>
</li>
</ItemTemplate>
</asp:Repeater>
Then you need to handle the event like so:
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
HyperLink hypl = (HyperLink)e.Item.FindControl("HyperLink1");
hypl.Text = ar.ToString();
hypl.NavigateUrl = "http//www.yahoo.com";
}

Related

how to set control's id dynamically in asp.net

how can is set id dynamic with Eval method and setting the id from sql database to a controller , like this
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="articlesqlfetch">
<ItemTemplate>
<strong > <%# Eval("title") %> </strong>
<br>
<-! this is the line ->
<asp:HyperLink ID="_<%# Eval("id") %>" runat="server">قراءة المزيد</asp:HyperLink>
</ItemTemplate>
when do this it give me a Parser Error
Using Eval() to provide dynamically generated ID is not allowed because you cannot bind to ID property of server controls, hence this code is wrong:
<asp:HyperLink ID="_<%# Eval("id") %>" runat="server">some text</asp:HyperLink>
Instead, use ItemDatabound event for repeater control like this (assumed your ID is auto-generated identity field):
Markup (ASPX)
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="articlesqlfetch"
OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
<%-- repeater contents --%>
<asp:HyperLink ID="Hyperlink1" runat="server">some text</asp:HyperLink>
</ItemTemplate>
</asp:Repeater>
Code-behind
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
HyperLink hyperlink = e.Item.FindControl("Hyperlink1") as HyperLink;
if (hyperlink != null)
{
hyperlink.ID = "_" + (e.Item.ItemIndex + 1).ToString(); // set ID from bound data
hyperlink.ClientIDMode = ClientIDMode.Static;
hyperlink.NavigateUrl = "some/uri/here"; // optional
// other stuff
}
}

how to understand which rows selected in repeater?

I have a slideshow that images load from sql server.
here is my html code:
<!-- Elastislide Carousel -->
<ul id="Ul1" class="elastislide-list">
<asp:Repeater ID="Repeater2" runat="server">
<ItemTemplate>
<li>
<asp:Label ID="lbl" runat="server" Text='<%#Eval("IDMusic") %>' Visible="True"></asp:Label>
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl='<%#Eval("ImageUrl") %>' Width="250px" Height="250px" OnClick="ImageButton1_Click" />
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
<!-- End Elastislide Carousel -->
<br /><br />
</div>
</div>
Now when, I run Project and user click on one of the imageButtons, I want to understand what is he/she clicked? for example he/she click on second ImageButton, Then I want to save IDMusic into a session and use this session in another page but I don't know how can i get IDmusic user clicked on?
here is my code behind :
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
foreach (RepeaterItem item in Repeater2.Items)
{
Label lbl = (Label)item.FindControl("lbl");
if (lbl != null)
{
Session["selectedmusicID"] = lbl.Text;
}
}
Response.Redirect("music.aspx");
}
There is no easy way to do so while handling click on the image itself. However you can leverage ItemCommand event here, which is a repeater event. Basically when some control is clicked inside the repeater, it generates a command in repeater which you can handle, and you can have item-specific arguments for it.
To define a command and args:
<asp:ImageButton ID="ImageButton1" ... CommandName="Select" CommandArgument='<%#Eval("IDMusic") %>' />
Command name here is custom, choose whatever you like. Now subscribe to the event of the repeater:
<asp:Repeater ID="Repeater2" runat="server"
OnItemCommand="Repeater2_ItemCommand">
And to handle:
protected void Repeater2_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Select") //just in case you have more than one
{
e.CommandArgument //here is your ID
}
}

Passing CommandArguement to LinkButton from variable

I have seen many resources on SO that say that I can use following syntax to pass value to CommandArguement of `LinkButton'
<%forearch(var comment in Comments){%>
<asp:LinkButton ID="del" CommandArguement='<%= comment.CommentId%>' onCommand="delete_click" Text="Delete"/>
<%}%>
But when I write this in my ascx file and click on the link the value passed to command argument is "<%=comment.CommentId%>" instead of commentId itself. Please guide what am I doing wrong?
Edit 1
based on answers and comments, I have moved to use repeater instead of foreach and plain code. Here is the code I have come up with
<asp:Repeater ID="commRepeater" SelectMethod="GetPageComments" runat="server">
<ItemTemplate>
<p>
<%#Eval("Comment") %>
<%if(Page.User.Identity.IsAuthenticated && Page.User.Identity.GetUserId() == Eval("UserId")){ %>
<span>
<asp:LinkButton Text="Edit" runat="server" ID="EditLink" CommandArgument='<%#Eval("CommentId")%>' OnClick="Update_Comment" />
<asp:LinkButton Text="Delete" runat="server" ID="DeleteLink" CommandArgument='<%#Eval("CommentId")%>' OnClientClick="if (!confirm('Are you sure you want delete?')) return false;" OnCommand="Delete_Comment" />
</span>
<%} %>
</p>
</ItemTemplate> </asp:Repeater>
you can see that I am trying to show the edit and delete links if user is logged in and his Id matches with user who commented but it tells me that I can on use Eval in databound controls. how would I hide/show edit/delete links conditionally within repeater
You could simply use codebehind, for example in Page_Load:
protected void Page_Load(Object sender, EventArgs e)
{
if(!IsPostBack)
{
del.CommandArgument = comment.CommentId;
}
}
Maybe a better approach would be to use the Comments-collection(which seems to be a list or array of a custom class) as DataSource of a Repeater(or other web-databound control). Then you can add the LinkButtons to the Itemtemplate.
You can then either use ItemCreated or ItemDataBound events of the repeater in codebehind or inline ASP.NET tags to bind the CommandArgument.
For example:
CommandArguement='<%# DataBinder.Eval( Container.DataItem, "CommentId" ) %>'
What you are doing currently is not recommended and is highly error prone. You can easily achieve this with ASP.NET Repeater control like this:-
<asp:Repeater ID="MyRepeater" runat="server">
<ItemTemplate>
<asp:LinkButton ID="del" CommandArguement='<%# Eval("CommentId") %>'
OnCommand="del_Command" Text="Delete" runat="server" />
</ItemTemplate>
</asp:Repeater>
In Page_Load simply bind it:-
if (!Page.IsPostBack)
{
MyRepeater.DataSource = CommentsRepository();
MyRepeater.DataBind();
}
Or Else if you are have ASP.NET 4.5 then use strongly type Data Bound controls like this:-
<asp:Repeater ID="MyRepeater" runat="server" ItemType="MyNamespace.Comment"
SelectMethod="MyRepeater_GetData">
<ItemTemplate>
<asp:LinkButton ID="del" CommandArguement='<%# Item.CommentId %>'
OnCommand="del_Command" Text="Delete" runat="server" />
</ItemTemplate>
</asp:Repeater>
And you method in code behind should be something like this(just for Demo):-
public IEnumerable<MyNamespace.Comment> MyRepeater_GetData()
{
return new List<Comment>
{
new Comment { CommentId =1, Name= "foo"},
new Comment { CommentId =2, Name= "bar"},
};
}

Change the source of image by clicking thumbnail using updatePanel

For example, i have this ImageViewer.ascx UserControl:
<div class="ImageTumbnails">
<asp:ListView ID="ImageList" runat="server" ItemPlaceholderID="ItemContainer">
<LayoutTemplate>
<asp:PlaceHolder ID="ItemContainer" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<asp:HyperLink runat="server"
NavigateUrl='<%# Link.ToProductImage(Eval("ImageFile").ToString())%>'>
<asp:Image runat="server" ImageUrl='<%# Link.ToThumbnail(Eval("ImageFile").ToString()) %>' />
</asp:HyperLink>
</ItemTemplate>
</asp:ListView>
</div>
<div class="ImageBig">
<asp:Image ID="ProductImageBig" runat="server" ImageUrl="" />
</div>
When the thumbnail is clicked it will change the source of ProductImageBig with its hyperlink target.
How can i achieve this using UpdatePanel ? ( Or will i be able to )
You are currently using a HyperLink control which will direct the user to the value of the NavigateUrl property. If it goes to a separate page, how will it modify the URL of the ProductImageBig control?
One option is to change the HyperLink control to a ImageButton and then specify a method in your codebehind for the "OnCommand" property.
In the code behind, you can cast the sender object to a the ImageButton, retrieve its ImageURL, and then set the URL of your ProductImageBig
public void DisplayPhoto(object sender, CommandEventArgs args)
{
ProductImageBig.NavigateUrl = ((ImageButton)sender).ImageUrl;
updatePanel.Update();
}
If you have the entire markup surrounded in an UpdatePanel named "updatePanel" and you have the properties set correctly, you can then update it after setting the Url.

How to get parent GridView's data-bound value

<asp:GridView DataSource="Reports">
<ItemTemplate>
<asp:TextBox Text='<%# Bind("ReportId") %>'
<asp:Repeater DataSource="Something that is different than the GridView's DS">
<a href='<%# Bind("ReportId", "reports.aspx?report={0}") %>'/>
</asp:Repeater>
</ItemTemplate>
</asp:GridView>
I know this is inachievable, I am looking for a way to use ReportId from the parent gridview in the nested repeater, is there a way to do it with server side code <%# %>?
Set the gridview
DataKeyField="ReportId"
and in the event GridView1_ItemDataBound inside it
protected void GridView1_ItemDataBound(object sender, GridViewItemEventArgs e)
((TextBox)e.Item.FindControl("TextBox1")).text = GridView1.DataKeys[0].ToString();
and in this case u set the textbox with the value of the ID, try it and hope that it will be usefull.

Resources