하늘높이의 프로그래밍 이야기

회사에서는 여차 저차에서 Windows 2003을 사용하는데...

Visual Studio 2007 Beta를 깔고 Expression Blend를 설치하고

이곳저곳에서 받은 샘플 소스들을 돌렸더니....

이런 C# Import 문장에서 부터 오류가 줄줄줄.....

어라 아직 Windows 2003에서는 안되나?

Blend 2는 설치 조차 되지도 않더라..

Using Silverlight and RSS to Build a Hero Bar with ASP.NET
 

Laurence Moroney

Updated: May 2007

Applies to:
   Silverlight
   ASP.NET

Summary: Learn how to use Microsoft Silverlight and RSS through ASP.NET to create a simple hero bar that is easily customizable and regenerated. (11 printed pages)

Contents

Introduction
Creating the XAML Template.
Using RSS
Building an ASP.NET Application to Generate XAML from the RSS Document
Managing the URLs
Rendering the Hero Banner in Silverlight

Introduction

We have all seen hero bars on our favorite websites—you know, the banner at the top of the site that rotates around new content and provides direct linkage to it? Did you know that it is easy to create a hero bar with Silverlight? Did you also know that it is just as easy to drive that hero bar content using RSS?

In this article, you'll see how to create a simple one that is easily customizable and can be regenerated simply by editing an RSS document. As such, you can have a hero bar that highlights new blog entries (where your blog is syndicated via RSS), and all you have to do to update the bar is create a new blog entry!

Figure 1 shows an example of a hero bar in action.

Figure 1. Viewing a hero bar in Internet Explorer

This article will guide you through the following steps in order to construct a hero bar:

  1. You will create an XAML template that contains one item and any necessary resources, such as animations (Creating the XAML Template.).
  2. You will create an ASP.NET application that reads an RSS file and generates XAML using the template in Step 1 (Building an ASP.NET Application to Generate XAML from the RSS Document).
  3. You will create a second ASP.NET application that reads an RSS file and generates JavaScript code containing the URLs (Managing the URLs).
  4. You will create an HTML page that contains the Silverlight control, sourcing it from the ASP.NET application in Step 2 and from the JavaScript generator in Step 3 (Rendering the Hero Banner in Silverlight).

Creating the XAML Template

The hero bar in Figure 1 is a 960 × 150 pixel bar containing an image, a headline element with a larger font, and a details element with a smaller font. In XAML, these are collected together into a canvas such as the following:

<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>

Of course, you can use any XAML design that you like, but do take note of the element names. These names are used by the ASP.NET code to fish out the nodes using XPath.

In addition to this, you will likely want an animation that manages the transition between different banners. In the following example, the animation used is a fade in opacity from one element to the next:

<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>

This example uses a DoubleAnimationUsingKeyFrames that fades the opacity of the item from 0 (invisible) to 1 (fully visible) over five seconds, and back to 0 over 1 further second. This will be used as the template for each animation. For example, if you have five elements on your hero bar, you will have five of these storyboards set up—one for each element.

Using RSS

The RSS specification defines an <item> node, which can contain a title, a link, a description, and a resource element such as a graphic or a video in an <enclosure> tag. This example uses images, but there is no reason why you couldn't use a video hero bar by specifying videos in the <enclosure> and using <MediaElement> instead of <Image> within your XAML.

The following is an example RSS document that contains links to Silverlight samples on Channel9, which you can update with any links you like.

<?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>

If you are using RSS that is generated from your blog (for example), make sure that these nodes are supported. If they are not, you will need to amend your ASP.NET code in order to handle the structure of your RSS document.

Building an ASP.NET Application to Generate XAML from the RSS Document

The first thing you'll want to do is override the HTML output from the ASPX page—you will just want the ASPX page to write out XAML. The most straightforward way is to delete all markup on the ASPX page, except for the first line. For example, if you named your page "GenerateXaml.aspx," your page should have a line like the following:

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

You would then want to use code like the following on your Page_Load event handler:

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);
    }

Because this code takes a feed parameter, you can pass in the URI of an RSS document by calling http://server/GenerateXaml.aspx?feed=URI. Or if you omit this parameter, it will read the data from a file called rssfeed.xml in the same directory as the ASPX page.

It then reads this RSS file into an XAML document and calls the GenerateXaml helper function to create a new XmlDocument called "xmlXaml." It then writes the "xmlXaml" contents out to the response stream.

The workhorse of this application is the aforementioned GenerateXaml helper function. It's a big function, so we'll go through it step by step.

The first thing you'll need to do is to create the following:

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

// Set up the namespaces. These are necessary for XPathing an
// XML Document that contains multiple name spaces
// Note: The default namespace does not have a prefix, but
// in order to XPath it, we have to prefix it with one,
// so I use 'd' (for default)
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");

When using XAML in ASP.NET with the XML APIs, you need to use an XmlNameSpaceManager to handle the different namespaces. Some elements in Silverlight use the default namespace, while others use the extended namespace prefixed with an "x:" (i.e. "x:Name"). You need to specify a prefix for the namespace manager when using a default namespace, so the "d" prefix is used. For example, when searching for nodes in the default namespace "Image" using XPath, you will refer to it as "d:Image."

Next, you'll get the list of item nodes from the RSS document. To do this, you will use the SelectNodes API to return a NodeList of items.

// The Hero bar items are stored in the RSS 'item' node
//Get a nodelist of the items.
XmlNodeList xnItems = rssFeed.SelectNodes("//item");

Now you'll want to iterate through this list and make copies of the XAML canvas for each node:

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();
}

Now that you have your node, you’ll want to edit the details, to put the image, headline and text from the RSS Item:

// Now that we have our node, we will customize it with the details taken from the RSS Item.
//First, set up the variables holding the RSS items.
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;

// Then, edit the node with these items directly
// 1. Edit the canvas to give it a unique ID
string strCanvasName = "cnvItem" + lp;
itemCanvasTemplate.Attributes["x:Name"].Value = strCanvasName;
            
// 2. Edit the Image Name and 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. Edit the Headline Textblock name and content
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. Edit the Details Texblock name and content
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);

The process for cloning and editing the animation is very similar. You can see this in the code download for this article.

Managing the URLs

One small problem with XAML is that when you specify the JavaScript event handler for the page, you cannot parameterize it. Thus, you cannot put the individual URI for an element in the hero banner into your XAML like this:

MouseLeftButtonDown="javascript:DoClick(MyURI)"

To instead determine the URI, you will have to call a generic DoClick function and use the ID of the canvas that raised the event. A second ASPX page will read the RSS and generate a JavaScript array. The page containing the Silverlight banner can then reference this and the JavaScript event handler will use this JavaScript array.

The following is the C# code to write out a JavaScript array:

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");
}

And here is an example of a JavaScript array that it writes out:

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/';

Rendering the Hero Banner in Silverlight

Now that you have all the pieces in place, it is a simple matter to render the hero banner using Silverlight.

The complete code for an HTML page that implements it, along with the JavaScript to handle the URLs follows:

<!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>

Notice the reference to the GenerateJS.aspx page is a <script> reference. This will call the GenerateJS.aspx page, which in turn generates a JavaScript array (as in the previous section).

The <Canvas> elements in the XAML specifies that DoClick should handle the mouse left button down, and this function is implemented here. It creates n, a new var. It also sets it to the value of the sender, replacing the string cnvItem with an empty string.

The sender contains the name of the canvas that raised the event, such as cnvItem0, cnvItem1. Replacing cnvItem with an empty string then assigns n to 0 or 1 in these cases. Then, to navigate to a URL specified in the urls array (generated by GenerateJS.aspx), you use Window.Open(urls[n]).

Finally, it sets up the Silverlight control using the call with createSilverlight(). This is present in the createSilverlight.js javascript library that was included at the top of the page. This contains the instantiation code for the Silverlight control that you can see here:

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);
}

The first parameter is GenerateXaml.aspx, which generates the XAML as we saw earlier. Silverlight then renders it. As such, you'll now have a hero banner on your page, which you can easily amend using different XAML, and easily update by updating your RSS.

This shows how Silverlight fits nicely into the overall developer ecosystem of Microsoft tools—using RSS, ASP.NET, XAML and Silverlight to mash-up a new application!


'Web Tech > Silverlight' 카테고리의 다른 글

실버라이트 RC1  (0) 2007.08.06
실버라이트 한글 사용하기  (0) 2007.08.01
Windows 2003에서의 실버라이트  (0) 2007.07.30
실버라이트 링크 모음  (0) 2007.07.23
From A to Z... 50 Silverlight Applications  (2) 2007.07.23

공식사이트

실버라이트
http://silverlight.net/

실버라이트 코리아
http://www.microsoft.com/korea/silverlight/

MS 에반젤리스트

준서아빠가 생각하는 행복한 UX 이야기
http://uxkorea.net

황리건 블로그 시즌2 :: UX Factory
www.uxfactory.net
계속 업데이트 됩니다.

개인 블로그

UX엔지니어 - MS MVP
http://winkey.tistory.com

유령 회사 공도소프트
http://gongdo.tistory.com

From A to Z... 50 Silverlight Applications

Tim Sneath의 블로그 에 있는 글입니다.

실버라이트 어플리케이션의 From A to Z 50 입니다.
실버라이트로 무엇을 할수 있을까 자꾸 머리를 짜내어 보는데 가끔 깜짝 놀래는 서비스들이 많습니다.

관심있으신분은 한번 보세요.

'Web Tech > Silverlight' 카테고리의 다른 글

실버라이트 RC1  (0) 2007.08.06
실버라이트 한글 사용하기  (0) 2007.08.01
Windows 2003에서의 실버라이트  (0) 2007.07.30
실버라이트를 이용하여 RSS 리더 만들기  (0) 2007.07.25
실버라이트 링크 모음  (0) 2007.07.23