I've recently been developing a control to display recent news in a rotating fashion. Originally, I was using the RadRotator control from Telerik. This is a powerful control that takes a lot of the guesswork out of displaying and rotating news. However, I decided to build my own for two reasons.
First, I didn't like the way the rotator control loads ALL of the news items before running. The RadRotator works by preloading all of the elements, placing each item into its own div element, then cycling through each, toggling visibility of each one at a time. This solution works for a few elements, but if you're cyclying through a half dozen or more items, each with an image, it can be an expensive procedure, especially since the control has to finish loading in order for the page to run. This leaves users viewing half a screen while the content loads.
The other reason I decided to build my own was just out of sheer curiousity and a desire to learn, especially since this is a perfect candidate to get my feet wet in the Ajax world that I've been dying to dive into.
Anyway, enough back-story, let's get to the code! The first thing I had to do was retrieve the news items that will be displayed. I'll be storing the Guids for each news item in the ViewState for quick, on-demand retrieval. The Guids go in a Generic List, which will be accessed by a CurrentItem index, which checks to make sure that this value is always within the valid range of elements.
| protected List newsIDs
|
| { |
| get |
| { |
| if (ViewState["NewsIDs"] == null) ViewState["NewsIDs"] = new List(); |
| return (List)ViewState["NewsIDs"];
|
| } |
| set { ViewState["NewsIDs"] = value; }
|
| } |
| |
| protected int CurrentItem |
| { |
| get |
| { |
| if (ViewState["CurrentItem"] == null) ViewState["CurrentItem"] = 0;
|
| return (int)ViewState["CurrentItem"];
|
| } |
| set |
| { |
| if (value > newsIDs.Count - 1) |
| ViewState["CurrentItem"] = 0;
|
| else if (value < 0)
|
| ViewState["CurrentItem"] = newsIDs.Count - 1; |
| else |
| ViewState["CurrentItem"] = value;
|
| } |
| } |
Since I'm using
Sitefinity (my content management system of choice!), I'll need to use the NewsManager to retrieve these items. Because of the nature of the News API, it is necessary for me to retrieve the full list of news items on Page_Load. Ideally, I would only be grabbing the Guid for each item, but since the only way to retrieve them is to retrieve the full items, I'll have to do that. Fortunately, this is only in the code behind, and isn't rendering to the page so the overhead should be minimal, especially since it's only done on the initial Page_Load
| protected void Page_Load(object sender, EventArgs e) |
| { |
| if (this.manager == null) this.manager = new NewsManager("News");
|
| |
| if (!IsPostBack) |
| { |
| BindData(); |
| } |
| } |
| |
| private void BindData() |
| { |
| IMetaSearchInfo[] filters = new IMetaSearchInfo[3];
|
| filters[0] = new MetaSearchInfo(MetaValueTypes.DateTime, "Expiration_Date", DateTime.Now, SearchCondition.GreaterOrEqual);
|
| filters[1] = new MetaSearchInfo(MetaValueTypes.ShortText, "Category", "Top Story");
|
| filters[2] = new MetaSearchInfo(MetaValueTypes.DateTime, "Publication_Date", DateTime.Now, SearchCondition.LessOrEqual);
|
| |
| IList newsList; |
| newsList = manager.Content.GetContent("Publication_Date DESC", filters); |
| |
| newsNavRepeater.DataSource = newsList; |
| newsNavRepeater.DataBind();
|
| |
| foreach (IContent content in newsList)
|
| newsIDs.Add(content.ID); |
| |
| // start with the first news Item
|
| UpdateNews((IContent)newsList[0]);
|
| } |
The newsNavRepeater is simply a repeater of LinkButtons that will tie to the individual news item ids.