技术开发 频道

自己动手制作多线程RSS新闻阅读器

  我们注意到DataSet对象的ReadXml方法,它将 XML 架构和数据读入 DataSet。这样获得的DataSet数据会包含多个表,以IT168的RSS为例,http://rss.it168.com/txt/16.xml被读入到DataSet中会有3个Table:rss、channel和item,我们所感兴趣的内容就全部包含在item表中,这就是目前RSS格式的一种,我们可以读取rss头部关于RSS版本的信息来判断RSS格式,具体实现我们在这里省略。

  获取了RSS内容后将其保存在rssData中备用。尤其是item表中title、description和link字段是我们最关心的,它保存了每一条RSS新闻的标题、描述和对应的内容链接。下一步就是将内容显示出来。在这里我们为了更加美观阅读器,我们使用ListBox并对其进行自定义重绘,将RSS中的每一项内容按照不同的字体样式和大小以及内容的多少,重新绘制ListBox的Item并将其绘制出来。代码如下:

private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
        {
            Graphics gfx = e.Graphics;
            if ((listBox1.Items.Count == 1) && (listBox1.Items[0].ToString().Contains("error")))
            {
                gfx.DrawString(errortext, titleFont, Brushes.SteelBlue, e.Bounds.X + leftMargines, e.Bounds.Y + topMargines);
                return;
            }
            if (listBox1.Items.Count > 0)
            {
                int number = e.Index + 1;
                string strtitle = "";
                string strdescription = "";
                strtitle = rssData.Rows[e.Index]["title"].ToString();
                strdescription = rssData.Rows[e.Index]["description"].ToString();
                if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
                {
                    //Graphics gfx = e.Graphics;
                    Pen pen = new Pen(Brushes.SteelBlue, 0.4f);
                    gfx.DrawRectangle(pen, e.Bounds.X + 4, e.Bounds.Y + 4, e.Bounds.Width - 8, e.Bounds.Height - 8);
                    gfx.FillRectangle(Brushes.LightSteelBlue, e.Bounds.X + 5, e.Bounds.Y + 5, e.Bounds.Width - 9, e.Bounds.Height - 9);
                    gfx.DrawString(number.ToString() + ".", titleFont, Brushes.Black, e.Bounds.X + leftMargines, e.Bounds.Y + topMargines);
                    SizeF f1 = gfx.MeasureString(number.ToString() + ".", titleFont);
                    gfx.DrawString(strtitle, titleFont, Brushes.SteelBlue, e.Bounds.X + leftMargines + f1.Width + 8, e.Bounds.Y + topMargines);
                    SizeF f11 = gfx.MeasureString(strtitle, titleFont);
                    Rectangle rect = new Rectangle(e.Bounds.X + leftMargines + (int)f1.Width + 8, e.Bounds.Y + topMargines + (int)f1.Height + rectDistance, this.listBox1.ClientSize.Width - leftMargines - (int)f1.Width - 8, this.ClientSize.Height);
                    StringFormat stf = new StringFormat();
                    stf.FormatFlags = StringFormatFlags.FitBlackBox;
                    gfx.DrawString(strdescription, descFont, Brushes.Black, rect, stf);
                }
                else
                {
                    gfx.FillRectangle(Brushes.White, e.Bounds.X + 4, e.Bounds.Y + 4, e.Bounds.Width - 7, e.Bounds.Height - 7);
                    gfx.FillRectangle(Brushes.SteelBlue, e.Bounds.X + 4, e.Bounds.Y + e.Bounds.Height - 8, e.Bounds.Width - 8, 1);
                    Pen pen = new Pen(Brushes.SteelBlue, 0.4f);
                    gfx.DrawString(number.ToString() + ".", titleFont, Brushes.Black, e.Bounds.X + leftMargines, e.Bounds.Y + topMargines);
                    SizeF f1 = gfx.MeasureString(number.ToString() + ".", titleFont);
                    gfx.DrawString(strtitle, titleFont, Brushes.SteelBlue, e.Bounds.X + leftMargines + f1.Width + 8, e.Bounds.Y + topMargines);
                    SizeF f11 = gfx.MeasureString(strtitle, titleFont);
                    Rectangle rect = new Rectangle(e.Bounds.X + leftMargines + (int)f1.Width + 8, e.Bounds.Y + topMargines + (int)f1.Height + rectDistance, this.listBox1.ClientSize.Width - leftMargines - (int)f1.Width - 8, this.ClientSize.Height);
                    StringFormat stf = new StringFormat();
                    stf.FormatFlags = StringFormatFlags.FitBlackBox;
                    gfx.DrawString(strdescription, descFont, Brushes.Black, rect, stf);
                }
                e.DrawFocusRectangle();
            }    
        }

        private void listBox1_MeasureItem(object sender, MeasureItemEventArgs e)
        {
            Graphics gfx = e.Graphics;
            if ((listBox1.Items.Count == 1) && (listBox1.Items[0].ToString().Contains("error")))
            {
                SizeF serrorstring = gfx.MeasureString(errortext, titleFont);
                e.ItemHeight = topMargines + (int)serrorstring.Height + rectDistance + 8 + 8;
                return;
            }
            if (listBox1.Items.Count > 0)
            {
                int number = e.Index + 1;
                string strtitle = "";
                string strdescription = "";
                strtitle = rssData.Rows[e.Index]["title"].ToString();
                strdescription = rssData.Rows[e.Index]["description"].ToString();
                SizeF f1 = gfx.MeasureString(number.ToString() + ".", titleFont);
                SizeF f11 = gfx.MeasureString(strtitle, titleFont);
                Rectangle rect = new Rectangle(leftMargines + (int)f1.Width + 8, topMargines + (int)f1.Height + rectDistance, this.listBox1.ClientSize.Width - leftMargines - (int)f1.Width - 8, e.ItemHeight);
                StringFormat stf = new StringFormat();
                stf.FormatFlags = StringFormatFlags.FitBlackBox;
                SizeF f2 = gfx.MeasureString(strdescription, descFont, rect.Width, stf);
                int Temp = e.ItemWidth;
                if (f2.Width
< (leftMargines + f1.Width + 8 + f11.Width)) Temp = leftMargines + (int)f1.Width + 8 + (int)f11.Width + 4;
                e.ItemHeight
= topMargines + (int)f1.Height + rectDistance + (int)f2.Height + 8 + 8;
            }            
        }


 

0
相关文章