I have a Repeater Control using an XMLDataSource to produce a list of movies (Movies.aspx). I need to link to a detailed page via query parameters like MovieDetails.aspx?movie=Matrix. What control do I use on the MovieDetails.aspx page to render a single movie, preferably using ItemTemplate and my own HTML.
My data source:
<asp:XmlDataSource ID="MoviesXmlDataSource" runat="server"
DataFile="~/Movies.xml" XPath="movies/movie"></asp:XmlDataSource>
I read the StackOverflow post Send string with QueryString in Repeater Control in ASP.net and list my items via a repeater like this:
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="MoviesXmlDataSource">
<HeaderTemplate>
<ul class="productlist">
</HeaderTemplate>
<ItemTemplate>
<li>
<img src="Images/<%#Eval("image") %>" /><br/>
<b><%#Eval("title") %></b>
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
On my MovieDetail.aspx I get the query string parameter as expected. However, I don't know how to fetch this item from my XMLDataSource and render it nicely. I figured out how to do this using GridView and then render a DetailsView depending on what you click in the grid, but it's so ugly. Repeater lets me specify my own HTML, but only for a list and not a single item.
The whole idea of the Repeater control is to display a set of data in a consistent manner. And the HTML you apply is actually for a single item in a list of items. And if i were you, i would be using a table to display the items. Title in one column, Image in another, details in another etc. Or you could use a
Title
--------
Image | Description Line 1
| Description Line 2
| Description Line 3
| Description Line 4
--------
Title
--------
Image | Description Line 1
| Description Line 2
| Description Line 3
| Description Line 4
--------
approach.
The only thing that is stopping you from getting a nice list of movies is the knowledge of HTML (which you already know) and creativity! Let your imagination run wild ;)
Lists
would
definitely
suck
in
this
scenario
:(
I just figured this out myself. I didn't realize that I could simply access my XMLDataSource from my code behind. I don't have to bind it to any control. Here is my solution:
Upon PageLoad, get the url parameter movie
Convert MoviesXMLDataSource to an XmlDocument
Fetch the single node where title matches my movie parameter
Fetch title, description and image link and store as variables
In the aspx, render normal HTML and insert <%=title %> and so on...
protected void Page_Load(object sender, EventArgs e)
{
this.movieTitle = Request["movie"];
string xpath = String.Format("/movies/movie[#title=\"{0}\"]", movieTitle);
XmlDocument doc = MoviesXmlDataSource.GetXmlDocument();
XmlNode node = doc.SelectSingleNode(xpath);
this.title = node.Attributes["title"].Value;
this.description = node.Attributes["description"].Value;
this.image = node.Attributes["image"].Value;
}
And in the aspx I render stuff as normal:
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:XmlDataSource ID="MoviesXmlDataSource" runat="server"
DataFile="~/Movies.xml" XPath="movies/movie">
</asp:XmlDataSource>
<h1><%=title %></h1>
<p>
<img src="<%=image %>"/><br />
<%=description %>
</p>
</asp:Content>
In the end this was really simple. I just got confused by forcing myself to use a control.
Related
Hello and thanks for taking your time to help me.
I'm trying to change the text of a textbox thats located inside my repeater.
<asp:Repeater runat="server" ID="rpCategories">
<HeaderTemplate>
<ul id="nav_down" class="nav_down">
</HeaderTemplate>
<ItemTemplate>
<li><%# Eval("Title") %></li>
</ItemTemplate>
<FooterTemplate>
<li></li>
<li>Contact</li>
<li><a id="cart_logo"></a>
<asp:Panel runat="server" ID="pnlBasket">
<asp:textbox runat="server" id="txtTotalCount" Enabled="false" CssClass="ltTotalCount"></asp:textbox>
</asp:Panel>
</li>
</ul>
</FooterTemplate>
</asp:Repeater>
It's the asp:textbox with the id="txtTotalCount" that I want to change the text of.
Here is my C# code:
TextBox ltTotalCount = (TextBox)FindControl("lblTotalCount");
ltTotalCount.Text = "1";
But if I run the code I get this error : Object reference not set to an instance of an object.
Would be so happy if someone could tell me what I'm doing wrong.
Becuase lblTotalCount is inside a parent control - the repeater, you have to reference it through the repeater.
You should be able to just add the id of your repeater before FindControl, like this...
TextBox ltTotalCount = (TextBox)rpCategories.FindControl("lblTotalCount");
You have to specify the repeater as the parent control to look for the text box and also since it's repeater its quite possible to have more than one text box with that Id so you have to specify which repeater item to look into like so:
TextBox ltTotalCount = rpCategories.Items[0].FindControl("txtTotalCount") as TextBox;
This will return the textbox in the first row of the repeater.
And you should use the Id value not the CssClass value
The ID is probably being 'enhanced' to prevent duplicate IDs in the rendered HTML. You can verify this by looking at the html.
You can add this to the textbox: ClientIDMode="Static" to make the ID stay the same.
You are getting the error because FindControl is returning a null but you are trying to access it anyway.
[Edit] Someone pointed out that this shouldn't work. I agree, here is what does work:
Control FooterTemplate = rpCategories.Controls[rpCategories.Controls.Count - 1].Controls[0];
TextBox MyTextBox = FooterTemplate.FindControl("txtTotalCount") as TextBox;
Totally new to webforms user controls, I am bit confused, on how to create a user control and fill some data on it.
for(int i = 0; i < Price.EpList.Count(); i++)
{
Price.EpList[i].Amount.ToString();
Price.EpList[i].Code.ToString();
Price.EpList[i].Desc.ToString();
Price.EpList[i].ID.ToString();
}
EpList is a list that contains info that i want to display in webpage on tabular format with checkboxes on each row.
Take a look at the Repeater Control. You don't have to loop through your list, you just bind the list to the repeater and define the html template you want for each repeated item.
http://www.w3schools.com/aspnet/aspnet_repeater.asp
EDIT: That article uses Visual Basic, so here's the C# translation:
Assuming this repeater:
<asp:Repeater runat="server" ID="uxEpList">
<ItemTemplate>
<%--Html goes here--%>
<%# Eval("Amount")%>
<%# Eval("Code")%>
<%# Eval("Desc")%>
<%# Eval("ID")%>
</ItemTemplate>
</asp:Repeater>
In code behind:
uxEpList.DataSource = Price.Eplist;
uxEpList.DataBind();
If you need to nest a repeater inside another one (using the Desc property from your comment) you can do it like this, by setting the DataSource property declaratively (note the single quotes):
<asp:Repeater runat="server" ID="uxEpList">
<ItemTemplate>
<asp:Repeater Datasource='<%# Eval("Desc")%>' runat="server">
<ItemTemplate>
//etc...
I have several links that look like the following:
<ul>
<li><asp:HyperLink ID="lnk1" NavigateUrl="~/section/sub-section/page1" runat="server">My Link</asp:HyperLink></li>
<li><asp:HyperLink ID="lnk2" NavigateUrl="~/section/sub-section/page2" runat="server">My Link</asp:HyperLink></li>
</ul>
What I want to do is in the code-behind is add a class of selected if the link url matches the url of the page that is currently being viewed.
How would I do this? Thanks
Place your hyperlinks in Panel like this
<asp:Panel id="pnl" runat="server">
<ul>
<li><asp:HyperLink ID="lnk1" NavigateUrl="~/section/sub-section/page1" runat="server">My Link</asp:HyperLink></li>
<li><asp:HyperLink ID="lnk2" NavigateUrl="~/section/sub-section/page2" runat="server">My Link</asp:HyperLink></li>
</ul>
</asp:Panel>
Then in your code behind iterate through each HyperLink control:
foreach (Control lnk in pnl.Controls)
{
if (lnk is HyperLink)
{
HyperLink href = (HyperLink)lnk;
if (Request.Url.AbsoluteUri.Equals(href.NavigateUrl))
href.Attributes.Add("class", "selected");
}
}
Hope this will help..
in the Page.Request object you do have properties to get the RawUrl of the current page, doing a loop in the Page.Controls you could find all your hyper links, you can then compare the NavigateUrl attributes with the page url and you are set.
Keep in mind that if you want to change an attribute of the server controls from code behind you better do it only in the Page_PreRender method because if you it before your changes could be overwritten...
You can get current file name on Master page
string currentpage = Request.FilePath;
It will be something like (you'll need to tweek the equality comparison):
if (Request.Url.AbsoluteUri == lnk1.NavigateUrl) { lnk1.Attributes.Add("class", "selected"); }
I use asp.net 4 and C#.
I have some nested Master Pages; I display in my Content Page a list of Links using a repeater.
This is a sample of code generated by ASP.NET as read in the Source code in the Browser.
As you can see the ID is very lengthy.
My question:
How can I have control on the ID generated, so I can chose another format much shorter?
Please keep in mind that I cannot get rid of Master Pages for my layout.
Thanks for your help on this!
<li>
<a id="ContentBody_ContentColumn2_latestArticle_uxRepeaterLatestArticles_uxLink_0" href="Category.aspx?CategoryId=8">AAAAA</a>
</li>
<li>
<a id="ContentBody_ContentColumn2_latestArticle_uxRepeaterLatestArticles_uxLink_1" href="Category.aspx?CategoryId=12">BBBBB</a>
</li>
I would like instead an ID like:
ID="CB_CC_LA_R_0"
ID="CB_CC_LA_R_1"
Useful article:
http://www.west-wind.com/weblog/posts/2009/Nov/07/ClientIDMode-in-ASPNET-40
http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode.aspx
http://beyondrelational.com/blogs/hima/archive/2010/07/16/all-about-client-id-mode-in-asp-net-4.aspx
Replace the asp:HyperLink with plain HTML anchor tag and use following markup for it:
<a id='CB_CC_LA_R_<%# Container.ItemIndex %>' href='<%# Eval("IndexPropertyName", "Category.aspx?CategoryId={0}") %>' >
<%# Eval("TextPopertyName") %>
</a>
I am just a beginner in ASP.NET. My question is simple, I wanna add list items dynamically from the code behind file and I want each item to have a text and couple of images as hyperlinks. The HTML sample should be like,
<ul>
<li>do foo <img src="some_image.png" /></li>
<li>do bar <img src="some_image.png" /></li>
...
</ul>
The number of items is dependent on the collection retrieved by the code behind file.
P.S. my code behind file is written in C#
The Repeater control is the simplest way to create a customized bulleted list, plus it gives you complete control over the HTML you generate. To use it, set up a template like this:
<ul>
<asp:Repeater runat="server" ID="ListRepeater">
<ItemTemplate>
<li>do foo <a href='#'><img src='<%# Eval("ImageSource") %>' /></a></li>
</ItemTemplate>
</asp:Repeater>
</ul>
Then in your code-behind (or declaratively in your markup, depending on your preference), set the repeater's data source and bind it:
void Page_Load(object sender, EventArgs e) {
// Some method you've defined to get your images
List<string> imageList = GetImages();
ListRepeater.DataSource = imageList;
ListRepeater.DataBind();
}
ASP.NET renders the template once for each item in your data source.
The Repeater control has more features than what I've shown here, but this should get you started. Good luck!
Edit: a year after writing this answer, I still think repeaters are the best option among server controls, but more and more I prefer foreach statements right in my .aspx templates:
<ul>
<% foreach(Image image in this.Images) { %>
<li>do foo <a href='#'><img src='<%= image.Source %>' /></a></li>
<% } %>
</ul>
Just use the Repeater control. Simply and easy. :)
ASP.Net BulletedList. MSDN