Text = str
};
//---adds the label to Panel2---
panel2.Controls.Add(label);
//---adds the Panel2 to Panel1---
panel1.Controls.Add(panel2);
return panel1;
}
For simplicity, you are hardcoding the location of panel1
(assuming that this application is running on a wide-screen device). Figure 18-12 shows the various controls forming the display panel.
Figure 18-12
Next, define the IsConnected()
function to test whether the user is connected to the Internet:
//---check if you are connected to the Internet---
private bool IsConnected() {
try {
string hostName = Dns.GetHostName();
IPHostEntry curhost = Dns.GetHostEntry(hostName);
return (curhost.AddressList[0].ToString() != IPAddress.Loopback.ToString());
} catch (Exception) {
return false;
}
}
Dns is a static class that provides simple domain name resolution. The GetHostName()
method gets the host name of the local computer, which is then passed to the GetHostEntry()
method of the Dns class to obtain an IPHostEntry
object. IPHostEntry
is a container class for Internet host address information. Using this object, you can access its AddressList
property to obtain the list of IP addresses associated with it. If the first member of the AddressList
property array is not the loopback address (127.0.0.1; represented by IPAddress.Loopback
), it is assumed that there is Internet connectivity.
Next, define the DownloadFeed()
function, which takes in the URL for the feed you want to download and a title argument (to return the title of the feed). Each post title and its corresponding description is appended to a string and returned to the calling function:
//---download feed and extract Title and Description for each post---
private string DownloadFeed(string feedURL, ref string title) {
XmlDocument xml = new XmlDocument();
//---always load from storage first---
string FileName =
appPath + @"\" + RemoveSpecialChars(feedURL) + ".xml";
if (File.Exists(FileName)) {
xml.Load(FileName);
} else {
//---check if there is network connectivity---
if (IsConnected()) {
WebRequest ftpReq = null;
WebResponse ftpResp = null;
Stream ftpRespStream = null;
StreamReader reader = null;
bool getRSSFeedFailed = false;
try {
//---download the RSS document---
ftpReq = WebRequest.Create(feedURL);
ftpResp = ftpReq.GetResponse();
ftpRespStream = ftpResp.GetResponseStream();
reader = new StreamReader(ftpRespStream, System.Text.Encoding.UTF8);
//---load the RSS document into an XMLDocument object---
xml.Load(reader);
//---save a local copy of the feed document---
xml.Save(FileName);
} catch (Exception ex) {
MessageBox.Show(ex.Message);
getRSSFeedFailed = true;
} finally {
if (ftpRespStream != null) {
ftpRespStream.Dispose();
ftpRespStream.Close();
};
if (ftpResp != null) ftpResp.Close();
}
if (getRSSFeedFailed) return String.Empty;
} else {
return String.Empty;
}
}
//---get the title of the feed---
XmlNode titleNode = xml.SelectSingleNode(@"rss/channel/title");
title = titleNode.InnerText;
//---select all elements---
XmlNodeList nodes = xml.SelectNodes("rss/channel/item");
string result = String.Empty;
foreach (XmlNode node in nodes) {
//---select each post's
result += node.SelectSingleNode("title").InnerText + ((char)3);
result += node.SelectSingleNode("description").InnerText + ((char)12);
}
return result;
}
To download the RSS feed XML documents, you use the WebRequest
and WebResponse
classes. The document is then read using a StreamReader
object and loaded into an XmlDocument
object. Each post title and its description are separated by the ASCII character 3, and each posting is separated by the ASCII character 12, like this:
Post_Title<3>Post_Description<12>Post_Title<3>Post_Description<12>
Post_Title<3>Post_Description<12>Post_Title<3>Post_Description<12>
Post_Title<3>Post_Description<12>...
Notice that after the XML feed for an URL is downloaded, it is saved onto storage. This ensures that the application continues to work in offline mode (when user disconnects from the Internet). The URL of the feed is used as the filename, minus all the special characters within the URL, with the .xml
extension appended. For example, if the feed URL is http://www.wrox.com/WileyCDA/feed/RSS_WROX_ ALLNEW.xml, then the filename would be httpwwwwroxcomWileyCDAfeedRSSWROXALLNEWxml.xml. To strip off all the special characters in the URL, define the RemoveSpecialChars()
function as follows:
//---removes special chars from an URL string---
private string RemoveSpecialChars(string str) {
string NewString = String.Empty;
Regex reg = new Regex("[A-Z]|[a-z]");
MatchCollection coll = reg.Matches(str);
for (int i = 0; i <= coll.Count - 1; i++)
NewString = NewString + coll[i].Value;
return NewString;
}
You use the Regex
(regular expression) class to extract all the alphabets from the URL and append them into a string, which will be returned to the calling function to use as a filename.
Next, define the SubscribeFeed()
function to subscribe to a feed, and then add each post to the TreeView
control (see Figure 18-13):
//---returns true if subscription is successful---
private bool SubscribeFeed(string URL) {
bool succeed = false;
try {
//---display the wait message panel---
if (displayPanel == null) {
displayPanel = CreatePanel("Downloading feed...Please wait.");
this.Controls.Add(displayPanel);
} else {
displayPanel.BringToFront();
displayPanel.Visible = true;
Cursor.Current = Cursors.WaitCursor;
//---update the UI---
Application.DoEvents();
}
//---download feed---
string title = String.Empty;
string[] posts = DownloadFeed(URL, ref title).Split((char)12);
if (posts.Length > 0 && posts[0] != String.Empty) {
Читать дальше