<%-- Silverlight 技術文章 - 使用 Silverlight 和 RSS 搭配 ASP.NET 建置主題榜
*
   原稿 (英文)
Silverlight 技術文章

使用 Silverlight 和 RSS 搭配 ASP.NET 建置主題榜

 

Laurence Moroney

更新日期:2007 年 5 月

適用於:
   Silverlight
   ASP.NET

摘要:了解如何使用 Microsoft Silverlight 和 RSS,透過 ASP.NET 建立容易自訂和重新產生的主題榜 (Hero bar)。(列印共 11 頁)

目錄

簡介
建立 XAML 範本
使用 RSS
建置 ASP.NET 應用程式,藉以從 RSS 文件產生 XAML
管理 URL
以 Silverlight 呈現主題橫幅 (Hero Banner)

簡介

我們都看過個人最喜愛的網站上的主題榜,您知道吧,就是那個在網站上方輪流顯示新內容、並提供內容直接連結的橫幅?您知道嗎?透過 Silverlight 建立主題榜其實不難。您知道嗎?以 RSS 來驅動主題榜的內容也很容易。

在本文中,您將了解如何建立簡單的主題榜,並可藉由編輯 RSS 文件輕鬆自訂並重新產生。因此,主題榜可以突顯全新的部落格項目 (透過 RSS 整合部落格),而且,您只要建立新部落格項目即可更新主題榜!

[圖 1] 顯示作用中主題榜的範例。

[圖 1] 在 Internet Explorer 中檢視主題榜

本文將引導您執行下列步驟來建構主題榜:

  1. 您將建立包含一個項目和任何必要資源 (例如動畫) 的 XAML 範本 (建立 XAML 範本)。
  2. 您將建立 ASP.NET 應用程式以讀取 RSS 檔案,並使用步驟 1 的範本產生 XAML (建置 ASP.NET 應用程式,藉以從 RSS 文件產生 XAML)。
  3. 您將建立第二個 ASP.NET 應用程式,以讀取 RSS 檔案,並產生包含 URL 的 JavaScript 程式碼 (管理 URL)。
  4. 您將建立包含 Silverlight 控制項的 HTML 頁面,此控制項是從步驟 2 的 ASP.NET 應用程式和步驟 3 的 JavaScript 產生器取得 (以 Silverlight 呈現主題橫幅)。

建立 XAML 範本

[圖 1] 中的主題榜是 960 × 150 像素列,其中包含影像、大字型的標題元素和小字型的詳細資料元素。在 XAML 中,這些會組合為畫布,如下所示:

<Canvas Width="960" Height="150" x:Name="cnvItem0" Opacity="0" MouseLeftButtonDown="javascript:DoClick">
      <Canvas.Background>
         <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
            <GradientStop Color="#FF310909" Offset="0"/>
            <GradientStop Color="#FFAE0000" Offset="1"/>
         </LinearGradientBrush>
      </Canvas.Background>

<Image x:Name="img0" Width="344" Height="136"
       Canvas.Left="8" Canvas.Top="8" Source=""/>

<TextBlock x:Name="hdln0" Width="576" Height="40" 
           Canvas.Left="376" Canvas.Top="8"
           FontFamily="Tahoma" FontSize="24"
           FontWeight="Normal" Foreground="#FFFFFFFF"
           Text="Headline Text 1" TextWrapping="Wrap"/>

<TextBlock x:Name="detl0" Width="576" 
           Height="96" Canvas.Left="376" 
           Canvas.Top="48" FontFamily="Tahoma" 
           FontSize="14" FontWeight="Normal" 
           Foreground="#FFFFFFFF" 
           Text="Text Details 1 Describing the stuff inside the hero bar. Clicking anywhere on the bar should 
            take us to the bar details page." TextWrapping="Wrap"/> </Canvas>

當然,您可以隨意使用任何 XAML 設計,但請特別注意元素名稱。ASP.NET 程式碼會使用這些名稱,透過 XPath 擷取節點。

除此之外,您還可以加上管理不同橫幅之間的轉換的動畫。在下列範例中,使用的是從某個元素到下一個元素的淡入不透明度動畫效果:

<Storyboard x:Name="FadeIn" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames x:Name="Step0"    
        Storyboard.TargetName="cnvItem0"     
        Storyboard.TargetProperty="(UIElement.Opacity)" >
      <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
      <SplineDoubleKeyFrame KeyTime="00:00:05" Value="1"/>
      <SplineDoubleKeyFrame KeyTime="00:00:06" Value="0"/>
  </DoubleAnimationUsingKeyFrames>
</Storyboard>

這個範例使用 DoubleAnimationUsingKeyFrames,在五秒內將項目不透明度從 0 (不可見) 淡入為 1 (完全可見),接著在下 1 秒內淡出為 0。這會做為每個動畫的範本。例如,如果主題榜有五個元素,那麼您必須設定五個腳本,每個元素一個。

使用 RSS

RSS 規格定義 <item> 節點,其中包含標題、連結、描述,並在 <enclosure> 標籤中包含資源元素 (例如圖形或視訊)。這個範例使用影像,但您也可以使用視訊主題榜,方法是在 XAML 內,在 <enclosure> 標籤中指定視訊,並使用 <MediaElement>,而非 <Image>

以下是範例 RSS 文件,它包含 Channel9 之 Silverlight 範例的連結,您可以用任何連結進行更新。

<?xml version="1.0" encoding="ISO-8859-1" ?>
<rss version="2.0"><channel>
  <title>W3Schools Home Page</title>
  <link>http://www.w3schools.com</link>
  <description>Free web building tutorials</description>
  <item>
    <title>Red v Blue, starring Scott Guthrie</title>
    <link>http://channel9.msdn.com/playground/wpfe/rvbplayer/</link>
    <description>ScottGu in Red v Blue. Can an executive shoot a gun? 
                 Can he do it again?</description>
    <enclosure 
        url="http://channel9.msdn.com/playground/wpfe/images/rvbplayer.jpg"
        length="10659" type="image/jpeg" />
  </item>
  <item>
    <title>Updated Grand Piano showing Keyboard input!</title>
    <link>http://channel9.msdn.com/playground/wpfe/grandpiano/</link>
    <description>Your chance to be the concert pianist 
                 you always wanted to be...</description>
    <enclosure 
        url="http://channel9.msdn.com/playground/wpfe/images/grandpiano.jpg"
        length="6809" type="image/jpeg" />
  </item>
  <item>
    <title>An online WPFE Pad</title>
    <link>http://channel9.msdn.com/playground/wpfe/wpfepad/</link>
    <description>A great little online notepad that allows 
                 you to write and test your XAML</description>
    <enclosure 
        url="http://channel9.msdn.com/playground/wpfe/images/wpfepad.jpg"
        length="10938" type="image/jpeg" />
  </item>
</channel>
</rss>

例如,如果您使用了從部落格產生的 RSS,請確定這些節點受到支援。如果不受支援,您將必須修改 ASP.NET 程式碼,以便處理 RSS 文件的結構。

建置 ASP.NET 應用程式,藉以從 RSS 文件產生 XAML

第一項需要執行的動作是覆寫來自 ASPX 頁面的 HTML 輸出,您將需要 ASPX 頁面寫出 XAML。最簡單的方式是刪除 ASPX 頁面上的所有標記,只保留第一行。例如,如果頁面名稱為 "GenerateXaml.aspx",此頁面應該有類似下列的一行文字:

<%@ Page Language="C#" AutoEventWireup="true" 
 CodeFile="GenerateXaml.aspx.cs" Inherits="_Default" %>

接著在 Page_Load 事件處理常式上,使用類似下列的程式碼:

protected void Page_Load(object sender, EventArgs e)
    {
        String strRSSDoc = Request.Params["feed"];
        if (strRSSDoc == null)
            strRSSDoc = Server.MapPath("rssfeed.xml");
        WebClient rssClient = new WebClient();
        Stream data = rssClient.OpenRead(strRSSDoc);
        StreamReader reader = new StreamReader(data);
        String sBuffer = reader.ReadToEnd();
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(sBuffer);
        XmlDocument xmlXaml = GenerateXaml(xmlDoc);
        Response.ContentType = "text/xml";
        Response.Write(xmlXaml.OuterXml);
    }

因為此程式碼採用 feed 參數,所以您可以呼叫 http://server/GenerateXaml.aspx?feed=URI 傳入 RSS 文件的 URI。如果省略此參數,則會從 ASPX 頁面所在目錄中讀取一個名為 rssfeed.xml 檔案的資料。

接著程式碼將此 RSS 檔案讀入 XAML 文件,並呼叫 GenerateXaml Helper 函數,以建立名為 "xmlXaml" 的新 XmlDocument。接著將 "xmlXaml" 內容寫出至回應資料流。

此應用程式的主力是上述的 GenerateXaml Helper 函數。這是重要函數,以下將針對它進行逐步說明。

第一項需要執行的動作是進行建立,如下列所示:

XmlDocument xmlXaml = new XmlDocument();
xmlXaml.Load(Server.MapPath("template.xml"));

// 設定命名空間。在以 XPath
// 處理包含多個命名空間的 XML Document 時,這是必須進行的步驟
// 注意:預設命名空間不具備前置詞,但是
// 為了以 XPath 處理,我們必須加上前置詞,
// 我使用的是 'd' (預設)
NameTable myn = new NameTable();
XmlNamespaceManager mng = new XmlNamespaceManager(new NameTable());
mng.AddNamespace("d", 
        "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
mng.AddNamespace("x", "http://schemas.microsoft.com/winfx/2006/xaml");

與 XML API 搭配使用 ASP.NET 的 XAML 時,您必須使用 XmlNameSpaceManager 來處理不同的命名空間。Silverlight 的某些元素使用預設命名空間,有些則會使用以 "x:" 開頭的延伸命名空間 (即 "x:Name")。在使用預設命名空間時,您必須為命名空間管理員指定前置詞,因此會使用 "d" 前置詞。例如,使用 XPath 在預設命名空間 "Image" 中搜尋節點時,您會將此命名空間參照為 "d:Image"。

接下來,從 RSS 文件中取得項目節點的清單。若要執行這項動作,您必須使用 SelectNodes API,傳回項目的 NodeList

// 儲存在 RSS「項目」節點中的主題榜項目
//取得項目的節點清單。
XmlNodeList xnItems = rssFeed.SelectNodes("//item");

現在,逐一查看此清單,並為每個節點建立 XAML 畫布複本:

for (int lp = 0; lp < xnItems.Count; lp++)
{
  if (lp == 0)
  {
    itemCanvasTemplate = 
        xmlXaml.SelectSingleNode("//d:Canvas[@x:Name='cnvItem0']", mng);
  }
  else
  {
    XmlNode xNodeToCopy = 
        xmlXaml.SelectSingleNode("//d:Canvas[@x:Name='cnvItem0']", mng);
    itemCanvasTemplate = xNodeToCopy.Clone();
}

現在有了節點,您便可以編輯詳細資料,放置來自 RSS 項目的影像、標題和文字:

// 取得節點後,我們就可以使用取自 RSS 項目的詳細資料進行自訂。
//首先,設定包含 RSS 項目的變數。
string strItemTitle = xnItems[lp].SelectSingleNode("title").InnerText;
string strItemLink = xnItems[lp].SelectSingleNode("link").InnerText;
string strItemDescription = 
    xnItems[lp].SelectSingleNode("description").InnerText;
string strItemPicture = 
    xnItems[lp].SelectSingleNode("enclosure").Attributes["url"].InnerText;

// 接著,直接使用這些項目編輯節點
// 1. 編輯畫布,為它指派一個唯一的 ID
string strCanvasName = "cnvItem" + lp;
itemCanvasTemplate.Attributes["x:Name"].Value = strCanvasName;
            
// 2. 編輯 Image Name 和 Source
XmlNode xNode = 
    itemCanvasTemplate.SelectSingleNode("//d:Image[@x:Name='img0']", mng);
string strImageName = "img" + lp;
xNode.Attributes["x:Name"].Value = strImageName;
xNode.Attributes["Source"].Value = strItemPicture;

// 3. 編輯 Headline Textblock 名稱和內容
xNode = 
  itemCanvasTemplate.SelectSingleNode("//d:TextBlock[@x:Name='hdln0']", mng);
string strHeadlineName = "hdln" + lp;
xNode.Attributes["x:Name"].Value = strHeadlineName;
xNode.Attributes["Text"].Value = strItemTitle;

// 4. 編輯 Details Texblock 名稱和內容
xNode = 
  itemCanvasTemplate.SelectSingleNode("//d:TextBlock[@x:Name='detl0']", mng);
string strDetailsName = "detl" + lp;
xNode.Attributes["x:Name"].Value = strDetailsName;
xNode.Attributes["Text"].Value = strItemDescription;

xmlXaml.DocumentElement.AppendChild(itemCanvasTemplate);

複製和編輯動畫的程序非常類似。您可以從本文的程式碼下載中看到範例。

管理 URL

XAML 的一個小問題是,當您指定頁面的 JavaScript 事件處理常式時,就無法將它參數化。因此,您無法將主題橫幅元素的個別 URI 放入 XAML,如下所示:

MouseLeftButtonDown="javascript:DoClick(MyURI)"

若要決定 URI,您必須呼叫一般 DoClick 函數,並使用引發事件之畫布的 ID。第二個 ASPX 頁面將讀取 RSS,並產生 JavaScript 陣列。包含 Silverlight 橫幅的頁面就可以參照此頁面,而且 JavaScript 事件處理常式將會使用此 JavaScript 陣列。

以下是寫出 JavaScript 陣列的 C# 程式碼:

XmlNodeList xnItems = xmlDoc.SelectNodes("//item");

Response.Write("var urls = new Array()\n");

for (int lp = 0; lp < xnItems.Count; lp++)
{
  string strItemLink = xnItems[lp].SelectSingleNode("link").InnerText;
  Response.Write("urls[" + lp + "]='" + strItemLink + "';\n");
}

以下是其寫出的 JavaScript 陣列範例:

var urls = new Array()
urls[0]='http://channel9.msdn.com/playground/wpfe/rvbplayer/';
urls[1]='http://channel9.msdn.com/playground/wpfe/grandpiano/';
urls[2]='http://channel9.msdn.com/playground/wpfe/wpfepad/';

以 Silverlight 呈現主題橫幅

只要將所有必須的資料都準備妥當,使用 Silverlight 呈現主題橫幅就十分簡單。

以下是實作 HTML 頁面的完整程式碼,連同處理 URL 的 JavaScript:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html  >
<head>
    <title>Untitled Page</title>
    <script type="text/javascript" src="js/silverlight.js"></script>
    <script type="text/javascript" src="js/createSilverlight.js"></script>
    <script type="text/javascript" src="GenerateJS.aspx"></script>
    <script type="text/javascript">
        function DoClick(sender,args)
        {
            var n = sender.name.replace(/cnvItem/,"");
            window.open(urls[n]);
        }
    </script>
</head>
<body>
<div id='slControlHost'>
<script type="text/javascript">
    createSilverlight();
</script>   
</div>
</body>
</html>

請注意,GenerateJS.aspx 頁面的參照是 <script> 參照。它會呼叫 GenerateJS.aspx 頁面以產生 JavaScript 陣列 (如上節所述)。

XAML 中的 <Canvas> 元素指定了 DoClick 來處理滑鼠左鍵點選事件,並且在此實作此函數。它會建立新變數 n,也會將其設為 sender 的值,並將 cnvItem 字串取代為空字串。

sender 包含引發事件的畫布名稱,例如 cnvItem0cnvItem1。在這些範例中將 cnvItem 取代為空字串,並將 n 指派給 01。接著,若要瀏覽至 url 陣列 (由 GenerateJS.aspx 產生) 指定的 URL,請使用 Window.Open(urls[n])

最後,透過 createSilverlight() 使用呼叫,設定 Silverlight 控制項。此控制項出現在 createSilverlight.js Javascript 程式庫中 (包含在頁面上方)。它包含 Silverlight 控制項的執行個體化程式碼,如下所示:

function createSilverlight()
{  
    Sys.Silverlight.createObject("GenerateXaml.aspx", 
        slControlHost, "slControl1",
        {width:'960', height:'150', inplaceInstallPrompt:true, 
         background:'black', isWindowless:'true', 
         framerate:'24', version:'0.8'
        },
        {onError:null, onLoad:null},
        null);
}

第一個參數是 GenerateXaml.aspx,如上所述,它會產生 XAML。Silverlight 會接著呈現它。因此,現在頁面上會有主題橫幅,您可透過不同 XAML 輕鬆進行修改,並可透過更新 RSS 輕鬆更新。

這表示 Silverlight 完全適用於 Microsoft 開發人員工具生態系統。一起使用 RSS、ASP.NET、XAML 和 Silverlight 來建立新應用程式吧!

--%>