Introduction
In every project I need a way to show the latest articles, news, weathercast, etc. Some projects process links with query strings while others not.. My ideal solution would be a quick, simple, lightweight Marquee Web Custom Control...
If you are not familiar with custom web controls, here is a partial definition from the Microsoft documentation:
Web controls run on the server and include form controls such as buttons and text boxes, as well as special purpose controls such as a calendar. This allows you to programmatically control these elements on a web page. Web controls are more abstract than HTML controls. Their object model does not necessarily reflect HTML syntax. (See MSDN.)
Features
- great design-time attributes.
- allows you to choose database: XML or SQL Server.
- you can apply your web template.
- each topic has ID, description, date, anchor URL, anchor text.
Database
In the case of XML as database:
="1.0" ="utf-8"
<marquee>
<topic tpID='1' postDate='1/1/2002'>
<url value='http://www.....com'> Link... </url>
<hint><![CDATA[]]></hint>
</topic>
</marquee>
Using the code
Our control has three classes:
Marquee: WebControl
(which renders the control).
Data
(reads data from database (XML or SQL Server) and generates a collection of topics).
Anchor
(data holder).
First, we will preview the Data
class code:
public class Data
{
public ArrayList GetNews(string str,bool _isXML)
{
ArrayList AnchorsArrayList=new ArrayList();
if(!_isXML)
{
try
{
string sqlSelectStr="SELECT text, url, id, date, title FROM links";
SqlConnection myConnection;
myConnection=new SqlConnection(str);
if(myConnection.State==ConnectionState.Closed){myConnection.Open();}
SqlCommand myCommand=new SqlCommand(sqlSelectStr,myConnection);
SqlDataReader myReader=myCommand.ExecuteReader();
while(myReader.Read())
{
Anchor anc=new Anchor();
anc.Id=Convert.ToInt32(myReader["id"]);
anc.Url=myReader["url"].ToString();
anc.Text=myReader["text"].ToString();
anc.Date=(DateTime)myReader["date"];
anc.Title=myReader["title"].ToString();
AnchorsArrayList.Add(anc);
}
myReader.Close();
myConnection.Close();
}
catch(Exception ex)
{
throw ex;
}
}
else
{
try
{
XmlDocument xmlDoc=new XmlDocument();
xmlDoc.Load(str);
XPathNavigator nav=xmlDoc.CreateNavigator();
XPathNodeIterator navIterator;
XPathNodeIterator navIterator2;
navIterator=nav.Select("marquee/topic");
int topicNo=1;
while(navIterator.MoveNext())
{
Anchor anc=new Anchor();
anc.Id=
Convert.ToInt32(navIterator.Current.GetAttribute("tpID",
"").ToString());
anc.Date=
Convert.ToDateTime(navIterator.Current.GetAttribute("postDate",
"").ToString());
navIterator2=nav.Select("marquee/topic["+topicNo+"]/url");
navIterator2.MoveNext();
anc.Url=
navIterator2.Current.GetAttribute("value",
"").ToString();
anc.Text=navIterator2.Current.Value.ToString();
navIterator2=nav.Select("marquee/topic["+topicNo+"]/hint");
navIterator2.MoveNext();
anc.Title=navIterator2.Current.Value.ToString();
AnchorsArrayList.Add(anc);
topicNo++;
}
}
catch(Exception ex)
{
throw ex;
}
}
return AnchorsArrayList;
}
}
Now we look at the Marquee
class. There are two methods:
Render(...)
AnchorsListHtmlGenerator(.....)
protected string AnchorsListHtmlGenerator(ArrayList aList)
{
StringBuilder s = new StringBuilder();
string dir;
bool pFlag;
if (arabicSupport){dir = "rtl";}else{dir = "ltr";}
switch (marqueeDirection)
{
case Direction.up:
case Direction.down:
{
pFlag = true;
break;
}
default:
{
pFlag = false;
break;
}
}
for (int i = 0; i < aList.Count; i++)
{
if (showTitle)
{
if (TitleFontBold) { s.Append("<b>"); }
if (pFlag) { s.Append("<p dir=\"" + dir + "\">"); }
s.Append("<font size=\"" + titleFontSize +
"\" color=\"" +
urlTitleForeColor.Name.ToString() +
"\"" + ">");
s.Append((((Anchor)aList[i]).Title).ToString());
s.Append("</font>");
if (pFlag) { s.Append("</p>"); }
if (TitleFontBold) { s.Append("</b>"); }
}
if (pFlag) { s.Append("<p dir=\"" + dir + "\">"); }
if (showImage)
{
s.Append("<img src=" + listItemImageSrc + ">");
}
s.Append("<A href=\"");
s.Append((((Anchor)aList[i]).Url).ToString());
s.Append("\"");
if (urlUnderLine)
{
s.Append(" style=\"text-decoration: none\" ");
}
s.Append(">");
s.Append("<font size=\"");
s.Append(linkFontSize + "\" color=\"" +
urlForeColor.Name.ToString() + "\"" + ">");
s.Append((((Anchor)aList[i]).Text).ToString());
s.Append("</font></A>");
if (pFlag) { s.Append("</p><p> </p>"); }
}
return s.ToString();
}
Render
method:
protected override void Render(HtmlTextWriter output)
{
try
{
Data myData = new Data();
output.Write("<marquee onmouseover=this.stop() " +
"onmouseout=this.start() scrollamount=1 " +
"scrolldelay=10 direction=" +
marqueeDirection.ToString() + " width=" +
width + " height=" + height + ">");
if (FontBold) { output.Write("<b>"); }
output.Write(AnchorsListHtmlGenerator(myData.GetNews(connectionStr,
isXML)));
if (FontBold) { output.Write("</b>"); }
output.Write("</marquee>");
}
catch (Exception ex)
{
output.Write(ex.Message);
}
}
How? ..
After registering the DLL file within your web solution, you must:
- Decide the database type: XML Or MS SQL Server. If your choice is XML, then set the property
IsXML=true
.
- Then specify your XML file full path
ConnectionString="C:\resources\xml\XMLFile1.xml"
or your MS SQL DB connection string in the case of IsXml=false
...