<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Design with Silverlight</title>
	<link>http://designwithsilverlight.com</link>
	<description>Silverlight... you're soaking in it.</description>
	<pubDate>Thu, 26 Jun 2008 16:04:20 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.2</generator>
	<language>en</language>
			<item>
		<title>Silverlight Etch-A-Sketch</title>
		<link>http://designwithsilverlight.com/2008/06/24/silverlight-etch-a-sketch/</link>
		<comments>http://designwithsilverlight.com/2008/06/24/silverlight-etch-a-sketch/#comments</comments>
		<pubDate>Tue, 24 Jun 2008 15:16:01 +0000</pubDate>
		<dc:creator>jeff</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[Etch-A-Sketch]]></category>

		<category><![CDATA[game]]></category>

		<category><![CDATA[Silverlight 2]]></category>

		<guid isPermaLink="false">http://designwithsilverlight.com/2008/06/24/silverlight-etch-a-sketch/</guid>
		<description><![CDATA[It&#8217;s funny - I work on Silverlight all day and then I come home and work on&#8230; Silverlight. I was working on a project last night, and my wife said &#8220;Oh, that&#8217;s kind of like an Etch-A-Sketch&#8221;. I then felt compelled to build a Silverlight Etch-A-Sketch, so here it is. The whole project took me [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s funny - I work on Silverlight all day and then I come home and work on&#8230; Silverlight. I was working on a project last night, and my wife said &#8220;Oh, that&#8217;s kind of like an Etch-A-Sketch&#8221;. I then felt compelled to build a Silverlight Etch-A-Sketch, so here it is. The whole project took me a total of 45 minutes, and the majority of that was spent trying to find a background image that was big enough to suit my needs.</p>
<p>The application starts out by setting the X and Y values of a point to the center of the drawing surface. Each time one of the arrow keys is pressed, the &#8220;cursor&#8221; moves in that direction, leaving a point on the drawing surface. I initially had the project set up to use a polyline object, and add points to the PointCollection as the arrows were pressed, but I found a quirk with that functionality. Instead, I created a &#8220;pointEllipse&#8221; user control, which is a 1&#215;1 pixel ellipse the color of the &#8220;pen&#8221; that draws on the drawing surface. Each time you press a key, an instance of the pointEllipse is placed on the drawing surface at the appropriate location.</p>
<p>Here&#8217;s how the code breaks down:</p>
<p>I set up a new point object to hold the next coordinates assigned each time the cursor moves. X and Y store the current X and Y location of the cursor. Step defines the distance the cursor will travel each time a key is pressed.</p>
<p>Point nextPoint = new Point();<br />
double x;<br />
double y;<br />
double step = 1;</p>
<p>Next, I get the center of the drawing canvas and place a copy of the pointEllipse element there. Also, a few event listeners are wired up. One to take user input on KeyDown, one when the &#8220;Shake It!&#8221; button is pressed to clear the drawing, and one when the &#8220;OK&#8221; button is pressed on the instruction pane.</p>
<p>public Page()<br />
{<br />
InitializeComponent();</p>
<p>x = drawingCanvas.Width / 2;<br />
y = drawingCanvas.Height / 2;<br />
nextPoint.X = x;<br />
nextPoint.Y = y;</p>
<p>pointEllipse pE = new pointEllipse();<br />
pE.SetValue(Canvas.LeftProperty, x);<br />
pE.SetValue(Canvas.TopProperty, y);<br />
drawingCanvas.Children.Add(pE);</p>
<p>this.KeyDown += new KeyEventHandler(Page_KeyDown);<br />
clearButton.Click += new RoutedEventHandler(clearButton_Click);<br />
okButton.Click += new RoutedEventHandler(okButton_Click);<br />
}</p>
<p>When the app loads, the background is drawn and the center point is added. The instruction pane is shown. When the &#8220;OK&#8221; button is pressed, the instructions are hidden with the following event handler.</p>
<p>void okButton_Click(object sender, RoutedEventArgs e)<br />
{<br />
instructions.Visibility = Visibility.Collapsed;<br />
}</p>
<p>When keys are pressed, the event handler code adjusts the X or Y value depending upon which key was pressed. If the X or Y values go beyond the boundaries of the drawing canvas, they are not permitted to advance. The adjustments you see in the boundary code checks are because I got a little sloppy when I put the drawing canvas in place. Once the keyboard input is handled, a function called doDraw() is called.</p>
<p>void Page_KeyDown(object sender, KeyEventArgs e)<br />
{<br />
switch (e.Key)<br />
{<br />
case Key.Up:<br />
y -= step;<br />
if (y &lt;= 17) y = 17;<br />
break;<br />
case Key.Left:<br />
x -= step;<br />
if (x &lt;= 17) x = 17;<br />
break;<br />
case Key.Right:<br />
x += step;<br />
if (x &gt; drawingCanvas.Width - 10) x = drawingCanvas.Width - 10;<br />
break;<br />
case Key.Down:<br />
y += step;<br />
if (y &gt;= drawingCanvas.Height - 10) y = drawingCanvas.Height - 10;<br />
break;<br />
default:<br />
// do nothing<br />
break;<br />
}<br />
doDraw();<br />
}</p>
<p>The doDraw function creates an instance of the pointEllipse object and drops it on the drawingCanvas object after positioning it based on the current values of X and Y.</p>
<p>void doDraw()<br />
{<br />
pointEllipse pE = new pointEllipse();<br />
pE.SetValue(Canvas.LeftProperty, x);<br />
pE.SetValue(Canvas.TopProperty, y);<br />
drawingCanvas.Children.Add(pE);<br />
}</p>
<p>The last function is the event handler for when the &#8220;Shake It!&#8221; button is pressed. If you remember on an Etch-A-Sketch, shaking them is how you erase your drawing. To do that, I clear all the children off of the drawing canvas and reset the cursor to the center of the drawing canvas.</p>
<p>void clearButton_Click(object sender, RoutedEventArgs e)<br />
{<br />
drawingCanvas.Children.Clear();<br />
x = drawingCanvas.Width / 2;<br />
y = drawingCanvas.Height / 2;<br />
nextPoint.X = x;<br />
nextPoint.Y = y;<br />
}</p>
<p>If you want to see the game, you can check it out <a target="blank" href="http://designwithsilverlight.com/csharp/etchasketch/">here</a>.</p>
<p>If you would like to play with the project, you can download all the code <a href="http://designwithsilverlight.com/csharp/etchasketch/etchasketch.zip">here</a>.</p>
<p>If someone has the patience/ability to draw something really cool, send me a screen shot. =)</p>
]]></content:encoded>
			<wfw:commentRss>http://designwithsilverlight.com/2008/06/24/silverlight-etch-a-sketch/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Software Development Meme</title>
		<link>http://designwithsilverlight.com/2008/06/22/software-development-meme/</link>
		<comments>http://designwithsilverlight.com/2008/06/22/software-development-meme/#comments</comments>
		<pubDate>Sun, 22 Jun 2008 19:55:08 +0000</pubDate>
		<dc:creator>jeff</dc:creator>
		
		<category><![CDATA[Main]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[meme]]></category>

		<guid isPermaLink="false">http://designwithsilverlight.com/2008/06/22/software-development-meme/</guid>
		<description><![CDATA[OK, Dave&#8217;s picking on me, so I&#8217;ll bite. =)
How old were you when you first started programming?
I was 12 or 13. This was back in 1982 or 1983. My dad got an Apple ][+ that I started plugging away on, in GW-Basic, I believe. Once I got rolling, I started grabbing all the books and [...]]]></description>
			<content:encoded><![CDATA[<p>OK, <a href="http://geekswithblogs.net/WynApseTechnicalMusings/archive/2008/06/21/123053.aspx" title="Software-Development Meme" target="blank">Dave&#8217;s picking on me</a>, so I&#8217;ll bite. =)</p>
<p><strong>How old were you when you first started programming?</strong><br />
I was 12 or 13. This was back in 1982 or 1983. My dad got an Apple ][+ that I started plugging away on, in GW-Basic, I believe. Once I got rolling, I started grabbing all the books and magazine subscriptions I could. Back then, a lot of program listings were provided in Assembly, so I would literally spend HOURS typing in lines of hex code to get programs out of the magazines to run.</p>
<p><strong>How did you get started in programming?</strong><br />
I don&#8217;t remember what actually got me into programming on our Apple. I do remember when I was very young, my father would bring me into work with him on the weekends sometimes - he worked at Tandem Computers, which was later acquired by Compaq. I would sit there at a terminal and play Eliza or one of the football games the programmers there had created. If I can point to anything that piqued my interest along the way, that would be it.</p>
<p><strong>What was your first language?</strong><br />
<a href="http://en.wikipedia.org/wiki/GW-BASIC" target="blank">GW-Basic</a>.</p>
<p><strong>What was the first real program you wrote?</strong><br />
When I was 13, I remember all I wanted to do was be a programmer. Somewhere along the way, I grew away from that desire and did other things for a while until getting into web development in my early 20s. So, &#8220;real&#8221; program, I don&#8217;t know. I wrote a pretty kick-ass Star Trek program back in &#8216;83 or &#8216;84, using graphic sprites and audio through a Mockingboard on the Apple, which by then had been chipped to upgrade to an Apple //e.</p>
<p><strong>What languages have you used since you started programming?</strong><br />
Once you get going, you just can&#8217;t get enough. I&#8217;ve done Assembler, C, Cobol (bleh), Pascal, C++, Basic, Fortran, Java, C# and VB. At the time, C was my favorite - we&#8217;d write Assembler code inline for video card initialization. Boy have times changed! I like C# now. Go figure&#8230;</p>
<p><strong>What was your first professional programming gig?</strong><br />
I worked for a bit doing Java for an online domain name acquisition company, but never got deeply into it. There&#8217;s been bits and pieces through my web development here and there, but I suppose I consider my current job the &#8220;real deal&#8221;, since it&#8217;s almost purely coding most of the time.</p>
<p><strong>If you knew then what you know now, would you have started programming?</strong><br />
Yes, and I&#8217;d have been rich from Yahoo stock, too! The only thing I would have changed was that I would not have let my desire to be a developer get away from me for so long, but hey, that&#8217;s life.</p>
<p><strong>If there is one thing you learned along the way that you would tell new developers, what would it be?</strong><br />
Find a mentor. The amount of information can be overwhelming, and if you&#8217;re lucky, you can find someone willing to help bring you along. You don&#8217;t want someone to give you the answers, but it&#8217;s great to have people to bounce ideas off of when you hit a spot where you could use some input.</p>
<p><strong>What&#8217;s the most fun you ever had programming?</strong><br />
What can I say? Silverlight. The variety of programs I get to produce in my current role keeps it interesting and fun. Anyone that is a challenge but gets done on time is the most fun. =)</p>
<p><strong>What’s the most fun you’ve ever had … programming?</strong><br />
I&#8217;m sure there&#8217;s a road trip or two that would rank highly as &#8220;most fun&#8221;, but programming is fun - I can look forward to getting up and going to work each day to dig into whatever project we have on the board.</p>
<p><strong>Who are you calling out?</strong><br />
<a href="http://web-snippets.blogspot.com/" target="blank">Rob Houweling</a><br />
<a href="http://adamkinney.com/" target="blank">Adam Kinney</a> (how did he slip by this?)<br />
<a href="http://dnnsilverlight.adefwebserver.com/Home/tabid/36/Default.aspx" target="blank">Michael Washington</a> (that&#8217;s two, Michael!)</p>
]]></content:encoded>
			<wfw:commentRss>http://designwithsilverlight.com/2008/06/22/software-development-meme/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Toys for Tweets, Take (beta) 2&#8230;</title>
		<link>http://designwithsilverlight.com/2008/06/13/toys-for-tweets-take-beta-2/</link>
		<comments>http://designwithsilverlight.com/2008/06/13/toys-for-tweets-take-beta-2/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 14:14:13 +0000</pubDate>
		<dc:creator>jeff</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[Beta 2]]></category>

		<category><![CDATA[HttpWebRequest]]></category>

		<category><![CDATA[Tweme]]></category>

		<category><![CDATA[WebClient]]></category>

		<guid isPermaLink="false">http://designwithsilverlight.com/2008/06/13/toys-for-tweets-take-beta-2/</guid>
		<description><![CDATA[Generally speaking, I&#8217;ve had decent luck upgrading my beta 1 applications to beta 2. The one exception to that was the Twemes client I wrote, which currently resides at http://www.toysfortweets.com. The changes made to the cross-domain policy seemed simple enough - include a &#8220;headers&#8221; attribute when using HttpWebRequest. Unfortunately, *nothing* I was doing seemed to [...]]]></description>
			<content:encoded><![CDATA[<p>Generally speaking, I&#8217;ve had decent luck upgrading my beta 1 applications to beta 2. The one exception to that was the Twemes client I wrote, which currently resides at <a target="_blank" href="http://www.toysfortweets.com/">http://www.toysfortweets.com</a>. The changes made to the cross-domain policy seemed simple enough - include a &#8220;headers&#8221; attribute when using HttpWebRequest. Unfortunately, *nothing* I was doing seemed to help.</p>
<p>This is one of those situations where I don&#8217;t have control over the target domain name, but the people who run it were kind enough to place a Flash policy file up there for me. I didn&#8217;t want to keep asking them to make changes, so I placed the files on another domain we have control of, and worked from that. I installed the <a target="_blank" href="http://projects.nikhilk.net/WebDevHelper/" title="Web Development Helper">Web Development Helper</a> recommended in this <a target="_blank" href="http://timheuer.com/blog/archive/2008/06/10/silverlight-services-cross-domain-404-not-found.aspx" title="Cross Domain 404 in Silverlight">great post </a>by Tim Heuer. This gave total visibility into what was happening when I loaded the page, and there were a couple of problems. Eventually I got the problems fixed, but still no love.</p>
<p>The site loaded the application, the application called out to check for the Silverlight cross-domain policy file, which returned a 406 (Not Acceptable), then called out to check for the Flash cross-domain policy which returned a 200 (OK). Having that, the app called out for the RSS feed, which returned 200, and 19K of data. After that, silence. The callback function was not executing. This leads me to believe there may be a quirk in Silverlight when the Flash cross-domain policy file is in play. Silverlight took the file as OK, but it didn&#8217;t recognize the data needed to make the app go had come back. I tried several variations of the file based on different posts I found on the Silverlight.net forums, but nothing worked.</p>
<p>Finally, out of frustration, I created a simple version of the project that was still failing to execute the callback and sent it off to Tim Heuer for a more experienced set of eyes. He didn&#8217;t have any insight as to why HttpWebRequest was not executing the callback, but suggested I use WebClient instead. There is an <a target="_blank" href="http://timheuer.com/blog/archive/2008/03/14/calling-web-services-with-silverlight-2.aspx" title="Calling web services with Silverlight 2">older post </a>on Tim&#8217;s site describing how to call web services. The example code was a big help in changing over to WebClient from HttpWebRequest.</p>
<p>The Flash cross-domain policy on the target domain currently looks like this:</p>
<p>&lt;cross-domain-policy&gt;<br />
  &lt;allow-access-from domain=&#8221;*&#8221; /&gt;<br />
&lt;/cross-domain-policy&gt; </p>
<p>The code to call out for the file now looks like this:</p>
<p>WebClient rest = new WebClient();<br />
rest.DownloadStringCompleted += new DownloadStringCompletedEventHandler(rest_DownloadStringCompleted);<br />
rest.DownloadStringAsync(new Uri(&#8221;<font color="#ff0000">RSS FILE NAME</font>&#8220;));</p>
<p>This returns the data as e.Result in the DownloadStringCompleted event handler:</p>
<p>XDocument doc = XDocument.Parse(e.Result);</p>
<p>This now means I can use the information in &#8220;doc&#8221;:</p>
<p>var items = from g in doc.Descendants(&#8221;item&#8221;)<br />
    select new<br />
    {<br />
         title = g.Element(&#8221;title&#8221;).Value,<br />
         description = g.Element(&#8221;description&#8221;).Value,<br />
         pubDate = g.Element(&#8221;pubDate&#8221;).Value,<br />
         guid = g.Element(&#8221;guid&#8221;).Value,<br />
         link = g.Element(&#8221;link&#8221;).Value,<br />
    };</p>
<p>Once the data was organized, I populate arrays based on the data I need. The reason why I did it this way is because the app displays random posts, so it&#8217;s easy to reach in and grab an element out of the array.</p>
<p>foreach (var item in items)<br />
{<br />
    i++;<br />
    rssDescriptions[i] = item.description;<br />
    rssLinks[i] = item.link;<br />
    rssPubDates[i] = item.pubDate;<br />
}</p>
<p>I was going to use a multidimensional array, but I&#8217;m not tracking that much data, so it&#8217;s easier to keep track of this way. So now whenever a new post is detected in the RSS, the app will display the first post, then generate 4 random numbers to grab other posts out of the feed for display.</p>
]]></content:encoded>
			<wfw:commentRss>http://designwithsilverlight.com/2008/06/13/toys-for-tweets-take-beta-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Silverlight Beta 2 Updates</title>
		<link>http://designwithsilverlight.com/2008/06/07/silverlight-beta-2-updates/</link>
		<comments>http://designwithsilverlight.com/2008/06/07/silverlight-beta-2-updates/#comments</comments>
		<pubDate>Sat, 07 Jun 2008 16:48:39 +0000</pubDate>
		<dc:creator>jeff</dc:creator>
		
		<category><![CDATA[Main]]></category>

		<category><![CDATA[Beta 2]]></category>

		<guid isPermaLink="false">http://designwithsilverlight.com/2008/06/07/silverlight-beta-2-updates/</guid>
		<description><![CDATA[I have updated both the Bird Hunt and Tank Combat games to run in beta 2. The downloadable zip files were also updated.
]]></description>
			<content:encoded><![CDATA[<p>I have updated both the Bird Hunt and Tank Combat games to run in beta 2. The downloadable zip files were also updated.</p>
]]></content:encoded>
			<wfw:commentRss>http://designwithsilverlight.com/2008/06/07/silverlight-beta-2-updates/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Silverlight Twitter</title>
		<link>http://designwithsilverlight.com/2008/06/04/silverlight-twitter/</link>
		<comments>http://designwithsilverlight.com/2008/06/04/silverlight-twitter/#comments</comments>
		<pubDate>Wed, 04 Jun 2008 15:55:11 +0000</pubDate>
		<dc:creator>jeff</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[Tweet]]></category>

		<category><![CDATA[Tweme]]></category>

		<category><![CDATA[Twitter]]></category>

		<guid isPermaLink="false">http://designwithsilverlight.com/2008/06/04/silverlight-twitter/</guid>
		<description><![CDATA[I recently put together a proof of concept app for displaying &#8220;twemes&#8221; - hash-tagged tweets from Twitter (spell check is having a field day!). Twemes.com is a site that aggregates posts made to Twitter that contain various hash (#) tagged terms into RSS feeds.  We wanted to do something for TechEd (#teched08) and this app was the [...]]]></description>
			<content:encoded><![CDATA[<p>I recently put together a proof of concept app for displaying &#8220;twemes&#8221; - hash-tagged tweets from Twitter (spell check is having a field day!). Twemes.com is a site that aggregates posts made to Twitter that contain various hash (#) tagged terms into RSS feeds.  We wanted to do something for TechEd (#teched08) and this app was the end result.</p>
<p>This was a fun project to work on. It&#8217;s the first time I&#8217;ve done any cross-domain work. I initially ran into trouble grabbing the RSS feed due to the lack of a cross-domain policy file. I was using Yahoo Pipes and had good luck with that, but through ongoing conversations with the people that run twemes.com, got a cross-domain policy put in place that allows me to consume the feed. Very cool of them to help me out.</p>
<p>The app displays 5 chat bubbles. The one with the orange time stamp is always the top post from the feed, the other 4 are selected at random. The app periodically checks the feed for new posts and if one is found, the bubbles disappear and then reappear with new data. Unfortunately, TechEd attendees are not Twittering heavily (or not using the tag), so you might have to watch it for a while to see it change (or post if you have a Twitter account).</p>
<p>You can see it live at <a target="_new" href="http://www.toysfortweets.com" title="http://www.toysfortweets.com">http://www.toysfortweets.com</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://designwithsilverlight.com/2008/06/04/silverlight-twitter/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Timeline Infographic Deconstructed</title>
		<link>http://designwithsilverlight.com/2008/05/23/timeline-infographic-deconstructed/</link>
		<comments>http://designwithsilverlight.com/2008/05/23/timeline-infographic-deconstructed/#comments</comments>
		<pubDate>Fri, 23 May 2008 15:03:42 +0000</pubDate>
		<dc:creator>jeff</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[Photos]]></category>

		<category><![CDATA[slider]]></category>

		<category><![CDATA[timeline]]></category>

		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://designwithsilverlight.com/2008/05/23/timeline-infographic-deconstructed/</guid>
		<description><![CDATA[I wanted to take an opportunity to go over some of the code from the timeline I linked to in my last post. Even though it&#8217;s a Silverlight 1.0 app, there&#8217;s still some interesting aspects to the code there.
Right out of the gate, one of the things the app does is use two downloaders. The first [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted to take an opportunity to go over some of the code from the <a target="_blank" href="http://www.microsoft.com/presspass/events/ceosummit/history.mspx" title="CEO Summit History">timeline</a> I linked to in my last post. Even though it&#8217;s a Silverlight 1.0 app, there&#8217;s still some interesting aspects to the code there.</p>
<p>Right out of the gate, one of the things the app does is use two downloaders. The first one happens invisibly - meaning I don&#8217;t give any user feedback that I&#8217;m doing it - and is used to download the graphics to display the main downloader with the progress bar. I&#8217;ve done this with the last couple of apps I&#8217;ve built, and it works well. The idea is to make the graphics the downloader will need available before the downloader is used. This avoids graphics that &#8220;pop&#8221; on screen as soon as they&#8217;re done downloading and creates a smoother experience for the user. In this case, the downloading graphic was zipped to a file that&#8217;s about 80K. Once it&#8217;s on the client, I grab the image out of the zip for the background, and show the progress bar over the top.</p>
<p>The progress bar on the app is also interesting. When the application is loading, it looks like a graphical version of the timeline is building from left to right as the app downloads. The actual animated piece there is the blue bar. The progress bar rectangle was scaled -1 along the X-axis to flip it, and then had its width manipulated programmatically, collapsing the bar from left to right. The code looks like this:</p>
<p>percentage = Math.floor(sender.downloadProgress * 100);<br />
var newWidth = Math.floor(572.282 - (percentage * 5.72282));<br />
sender.findName(&#8221;progressBar&#8221;).Width = newWidth;</p>
<p>The &#8220;newWidth&#8221; calculation calculates the width by figuring out how wide the bar should be, and subtracting it from how wide the bar will be when it&#8217;s complete - basically creating a progress bar that works in reverse of the usual way - rather than increasing the width, it&#8217;s decreasing. Since the bar is flipped along the X-axis, the width decreases to the right instead of the usual left.</p>
<p>The main timeline is made up of 3 layers - the background, the logos, and the photos. Amazingly, each of these layers is over 8100 pixels wide. The background layer contains the background image as well as the year headers and gradients across the top of the timeline.  The logos layer contains the large graphical logos. The photos layer contains all of the text blurbs for the app, as well as the buttons for the video player. This was done so that the layers could move independently of one another, to create a little more of an organic look when you drag the slider. As you drag the slider, the current position of the slider is calculated and pushed to storyboards for each layer, and then the storyboard is triggered with the Begin() method. The storyboards were all similar, except that they have different durations and ease to make them slide at slightly varied speeds. The storyboards look like this:</p>
<p>&lt;Storyboard x:Name=&#8221;movePhotos&#8221;&gt;<br />
&lt;DoubleAnimationUsingKeyFrames BeginTime=&#8221;00:00:00&#8243; Duration=&#8221;00:00:01&#8243; Storyboard.TargetName=&#8221;photos&#8221; Storyboard.TargetProperty=&#8221;(Canvas.Left)&#8221;&gt;<br />
&lt;SplineDoubleKeyFrame x:Name=&#8221;photosValue&#8221; KeyTime=&#8221;00:00:01&#8243; Value=&#8221;0&#8243; KeySpline=&#8221;0,0.497,0.504,1&#8243;/&gt;<br />
&lt;/DoubleAnimationUsingKeyFrames&gt;<br />
&lt;/Storyboard&gt;</p>
<p>The code to update the storyboard value property looks like this:</p>
<p>sender.findName(&#8221;photosValue&#8221;)[&#8221;Value&#8221;] = -scaledBackgroundLocation;</p>
<p>&#8220;scaledBackgroundLocation&#8221; figures out where the various layers should be relative to the viewport - the timeline thumb across the bottom allows you to move across a very large timeline that is not entirely visible. For each pixel the thumb slider moves to the right, the main timeline background and images need to move an appropriate number of pixels to the left. To figure that out, we needed a scaling factor, which was the maximum left offset value the background images would need to move to display the end of the timeline, divided by the size of the preview timeline across the bottom. That code looks like this:</p>
<p>var scalingFactor = 7502 / 580;</p>
<p>The app width was 630px, so the 7502 comes from subtracting the width of the app from the width of the background images. 8132-630 = 7502. When one of the background images is set to -7502x, the last 630 pixels of the timeline will be visible in the viewport.</p>
<p>The video player is a reskinned Encoder template. I needed to instance the video player and start the app at the same time, so I created a function called &#8220;createSLObjects&#8221; that is called from the install experience if Silverlight is found. The function looks like this:</p>
<p>function createSLObjects() {<br />
createSilverlight();<br />
var player = new StartPlayer_0();<br />
}</p>
<p>The video player has two animations associated with it. One to scale it up and fade it in when a video button is clicked, and one to scale it down and fade it out when the close button on the player is clicked. There is only a single instance of the video player in the application, and the media element source is manipulated by code when a button is clicked. The video URLs were assigned to variables at the top of the script file to make them easily editable during the development process. As an example, when the button for the Al Gore video is clicked, the following code is executed:</p>
<p>sender.findName(&#8221;VideoWindow&#8221;).Source = goreVideo;</p>
<p>After which a function is called to make the player visible, set the starting scale and opacity, play the &#8220;show&#8221; storyboard, and start the video:</p>
<p>function showVideoPlayerCanvas(sender)<br />
{<br />
 sender.findName(&#8221;videoPlayerCanvas&#8221;).Visibility = &#8220;Visible&#8221;;<br />
 sender.findName(&#8221;videoPlayerScale&#8221;)[&#8221;ScaleX&#8221;] = 0;<br />
 sender.findName(&#8221;videoPlayerScale&#8221;)[&#8221;ScaleY&#8221;] = 0;<br />
 sender.findName(&#8221;videoPlayerCanvas&#8221;).Opacity = 0;<br />
 sender.findName(&#8221;showVideoPlayer&#8221;).Begin();<br />
}</p>
<p>Some of the videos were external to the app. For those, I just called window.open, and passed the video&#8217;s URL - they will open in the client&#8217;s default player.</p>
<p>The last step was the install experience graphic. We work hard to ensure that we&#8217;re offering a compelling reason for visitors without Silverlight to click the badge and install. Tim Heuer posted a great <a target="_blank" href="http://www.timheuer.com/blog/archive/2008/03/25/creating-a-great-silverlight-deployment-experience.aspx" title="Silverlight deployment experience">tip</a> on how to test out the experience in IE without uninstalling Silverlight.</p>
<p>Overall, the entire project from start to finish took just over two days. I was working very closely with the designer to pull all the pieces together and create a look that was similar to the original Flash piece, but also made sure we had an opportunity to update some of the visual elements.</p>
]]></content:encoded>
			<wfw:commentRss>http://designwithsilverlight.com/2008/05/23/timeline-infographic-deconstructed/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Timeline Infographics</title>
		<link>http://designwithsilverlight.com/2008/05/10/timeline-infographics/</link>
		<comments>http://designwithsilverlight.com/2008/05/10/timeline-infographics/#comments</comments>
		<pubDate>Sat, 10 May 2008 15:23:03 +0000</pubDate>
		<dc:creator>jeff</dc:creator>
		
		<category><![CDATA[Main]]></category>

		<category><![CDATA[Flash]]></category>

		<category><![CDATA[timeline]]></category>

		<guid isPermaLink="false">http://designwithsilverlight.com/2008/05/10/timeline-infographics/</guid>
		<description><![CDATA[One of the things I&#8217;ve wanted to do in Silverlight for a really long time is create a timeline infographic. Not for anything more than the practice really, but I just think that the different ways of presenting information via an interactive timeline are kind of interesting to see.
The majority of my work involves creating Silverlight [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things I&#8217;ve wanted to do in Silverlight for a really long time is create a timeline infographic. Not for anything more than the practice really, but I just think that the different ways of presenting information via an interactive timeline are kind of interesting to see.</p>
<p>The majority of my work involves creating Silverlight applications, and I love it. So imagine how happy I was when a timeline project came in. This one was interesting because it was a conversion from a Flash version to an updated Silverlight (1.0) version. The company I work for had created the Flash version, so we still had all the base assets used in the timeline, which was helpful.</p>
<p>The schedule was a little challenging - I didn&#8217;t have a lot of time to complete the work in - and the new version lives in a template that was a significantly narrower width than the Flash version, so there were some adjustments to make.</p>
<p>In the end, I was very pleased with the result. Interestingly enough, the overall performance of the Silverlight piece seems smoother than the Flash version. I had expected the Silverlight one to bog down a bit as I added text, due to the antialiasing, but that didn&#8217;t happen.</p>
<p>Anyways, for those of you that are interested, here is the original Flash version:<br />
<a href="http://www.microsoft.com/ceosummit/history.mspx" target="new">Flash CEO Summit timeline</a></p>
<p>The updated Silverlight version is here:<br />
<a href="http://www.microsoft.com/presspass/events/ceosummit/history.mspx" target="new">Silverlight CEO Summit timeline</a></p>
]]></content:encoded>
			<wfw:commentRss>http://designwithsilverlight.com/2008/05/10/timeline-infographics/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Silverlight Games - Tank Combat</title>
		<link>http://designwithsilverlight.com/2008/05/03/silverlight-games-tank-combat/</link>
		<comments>http://designwithsilverlight.com/2008/05/03/silverlight-games-tank-combat/#comments</comments>
		<pubDate>Sun, 04 May 2008 03:23:44 +0000</pubDate>
		<dc:creator>jeff</dc:creator>
		
		<category><![CDATA[Main]]></category>

		<category><![CDATA[combat]]></category>

		<category><![CDATA[Silverlight 2]]></category>

		<category><![CDATA[silverlight games]]></category>

		<category><![CDATA[tank game]]></category>

		<guid isPermaLink="false">http://designwithsilverlight.com/2008/05/03/silverlight-games-tank-combat/</guid>
		<description><![CDATA[I&#8217;m sure I&#8217;m dating myself a bit here, but back in 1977 or 1978, my parents picked up an early video game console for Christmas. It was a system put out by Telegames and sold through Sears, and it was designed to play a single game - a simple two-player Combat video game. The console [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m sure I&#8217;m dating myself a bit here, but back in 1977 or 1978, my parents picked up an early video game console for Christmas. It was a system put out by Telegames and sold through Sears, and it was designed to play a single game - a simple two-player Combat video game. The console had two handles on each side, allowing each player to control a tank on screen:</p>
<p><img src="http://designwithsilverlight.com/csharp/tankcombat/combatConsole.jpg" alt="Combat Console" /><br />
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br />
The goal was to drive around a maze and shoot the other player&#8217;s tank.</p>
<p>I decided to create a similar game in Silverlight. It gave me an opportunity to manage multiple moving objects on screen, and some practice with collision detection methods described by Adam Kinney in his Silverlight and Dynamic Animations <a href="http://download.microsoft.com/download/9/4/e/94e080c7-d462-4118-b07a-55578d64bc43/Silverlight%202%20Beta%201%20-%20Dynamic%20Animations.zip">hands-on lab</a>.</p>
<p>Adam was also kind enough to provide me with a little more detail on the collision detection which I was able to utilize in the game.</p>
<p><img src="http://designwithsilverlight.com/csharp/tankcombat/tankCombatScreenshot.gif" alt="Tank Combat Screenshot" /></p>
<p>You can play my Silverlight version of the game <a href="http://designwithsilverlight.com/csharp/tankcombat/default.html">here</a>.</p>
<p>If you&#8217;d like to download it and play it on your system offline, a zip archive can be downloaded <a href="http://designwithsilverlight.com/csharp/tankcombat/tankCombat.zip">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://designwithsilverlight.com/2008/05/03/silverlight-games-tank-combat/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Silverlight Games</title>
		<link>http://designwithsilverlight.com/2008/04/16/silverlight-games/</link>
		<comments>http://designwithsilverlight.com/2008/04/16/silverlight-games/#comments</comments>
		<pubDate>Wed, 16 Apr 2008 13:41:59 +0000</pubDate>
		<dc:creator>jeff</dc:creator>
		
		<category><![CDATA[Main]]></category>

		<category><![CDATA[Blend]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[game]]></category>

		<category><![CDATA[Silverlight 2]]></category>

		<category><![CDATA[silverlight bird hunt]]></category>

		<category><![CDATA[silverlight duck hunt]]></category>

		<category><![CDATA[silverlight games]]></category>

		<guid isPermaLink="false">http://designwithsilverlight.com/?p=25</guid>
		<description><![CDATA[I&#8217;ve spent the last week or so working with Ryan Loghry, a good friend of mine that is an illustrator, putting together a Nintendo &#8220;Duck Hunt&#8221;-like game in Silverlight (no, I did not include the dog). I&#8217;m really pleased with the results, and it was a good opportunity to learn more about how Illustrator/Blend/Visual Studio/Silverlight [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve spent the last week or so working with Ryan Loghry, a good friend of mine that is an illustrator, putting together a Nintendo &#8220;Duck Hunt&#8221;-like game in Silverlight (no, I did not include the dog). I&#8217;m really pleased with the results, and it was a good opportunity to learn more about how Illustrator/Blend/Visual Studio/Silverlight all work together. Ryan created the illustrations, and then essentially handed me completed XAML files with which to work. Sound effects were pulled from sound effects CDs, and a couple of them were borrowed from Duke Nuke&#8217;m. The complete package is about 775K in size.</p>
<p>I may take the opportunity to detail some of the challenges in future blog entries as time permits. This was a really fun project to watch come together.</p>
<p>The game can be seen/played here (make sure your speakers are on!):<br />
<a target="_blank" href="http://designwithsilverlight.com/csharp/birdhunt/default.html">http://designwithsilverlight.com/csharp/birdhunt/default.html</a></p>
<p>Also, if you&#8217;re interested in seeing more of Ryan&#8217;s excellent illustration work, you can find him here:<br />
<a target="_blank" href="http://ryanloghry.com/">http://ryanloghry.com/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://designwithsilverlight.com/2008/04/16/silverlight-games/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Silverlight Drumpad v2</title>
		<link>http://designwithsilverlight.com/2008/04/07/silverlight-drumpad-v2/</link>
		<comments>http://designwithsilverlight.com/2008/04/07/silverlight-drumpad-v2/#comments</comments>
		<pubDate>Mon, 07 Apr 2008 13:59:58 +0000</pubDate>
		<dc:creator>jeff</dc:creator>
		
		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[C#]]></category>

		<category><![CDATA[drum]]></category>

		<category><![CDATA[drumpad]]></category>

		<category><![CDATA[Silverlight 2]]></category>

		<category><![CDATA[sound]]></category>

		<guid isPermaLink="false">http://designwithsilverlight.com/?p=24</guid>
		<description><![CDATA[I finally had an opportunity to update my Silverlight drumpad program to be a little more what I had in mind when I started.
There are now 6 different drum kits you can choose from on the fly. This was done by adding the sound bites for the drums to the project as a resource, and [...]]]></description>
			<content:encoded><![CDATA[<p>I finally had an opportunity to update my Silverlight drumpad program to be a little more what I had in mind when I started.</p>
<p>There are now 6 different drum kits you can choose from on the fly. This was done by adding the sound bites for the drums to the project as a resource, and assigning the path of the sound file to a string when a particular kit is selected from the list box. This is done through a case statement, a portion of which is shown here:</p>
<p>case &#8220;Yamaha RX-21&#8243;:<br />
bassDrumSound = &#8220;sounds/YamahaRX21/Bassdrum.wma&#8221;;<br />
snareDrumSound = &#8220;sounds/YamahaRX21/Snaredrum.wma&#8221;;<br />
closedHatDrumSound = &#8220;sounds/YamahaRX21/ClosedHat.wma&#8221;;<br />
openHatDrumSound = &#8220;sounds/YamahaRX21/OpenHat.wma&#8221;;<br />
tomHighDrumSound = &#8220;sounds/YamahaRX21/TomH.wma&#8221;;<br />
tomMedDrumSound = &#8220;sounds/YamahaRX21/TomM.wma&#8221;;<br />
tomLowDrumSound = &#8220;sounds/YamahaRX21/TomL.wma&#8221;;<br />
clapDrumSound = &#8220;sounds/YamahaRX21/Clap.wma&#8221;;<br />
clapPad.msgDrumType.Text = &#8220;Clap&#8221;;<br />
crashDrumSound = &#8220;sounds/YamahaRX21/Crash.wma&#8221;;<br />
break;</p>
<p>As described in my previous drumpad post, due to problems with repeating audio clips, I elected to insert a media element each time a key is pressed. Because of this, it was easy to utilize the string variables defined above to make a quick change to the source property of the media element before inserting it into the application:</p>
<p>_mediaElement.Source = new Uri(snareDrumSound, UriKind.Relative);</p>
<p>In the case of the &#8220;80&#8217;s Drum Kit&#8221;, there is a cowbell sound instead of the clapping sound attached to the drumpad triggered with the &#8220;D&#8221; key. When this kit is selected, the label on the appropriate pad is also updated. You can see the text property being changed in the statement shown above, and when the 80&#8217;s kit is selected, the label is updated right after the new sound file is assigned. Here&#8217;s what that looks like:</p>
<p>clapDrumSound = &#8220;sounds/80s/Cowbell.wma&#8221;;<br />
clapPad.msgDrumType.Text = &#8220;Cowbell&#8221;;</p>
<p>Another big change is the addition of backing tracks to which you can play along. For these, I initially figured I&#8217;d use a loop-based program (Sony ACID Studio 7.0) to create some tracks, but given time constraints, I instead elected to use the software to render out MIDI files I found online. The upside is that it&#8217;s a big time saver, and it&#8217;s very easy to pull out the drum tracks before rendering the file to a .wma for use in the app. The downside is, they don&#8217;t always sound so great.</p>
<p>The drum sound effects are all fairly compact - ranging from 15-40K a piece. There&#8217;s a couple that are bigger, but the majority are small. The backing tracks are fairly heavily compressed, but the songs still average around 1MB a piece. This made the app a little bigger than I had hoped, but I like having the sounds all there &#8220;on demand&#8221;.</p>
<p>The other change that happens under the covers is the cleaning mechanism. As I described previously, the sounds are added to a special container canvas on the fly as keys are pressed. I set a cleaning threshold, then run a method to remove the old media elements from the container when it reaches a certain size. This worked, but it would cause some hesitation in the sounds from time to time, because it would clean out the entire containing canvas, meaning the sound that was playing, too. I changed this so that the threshold is much lower (8 nodes), but the cleaner only pulls out the bottom 4, so it will typically not touch the sound that is currently playing. This turns out to be much smoother and cleaner, as well as doing its job a little more quickly.</p>
<p>The final app can be seen <a target="_new" href="http://designwithsilverlight.com/csharp/drumpad_v2/default.html">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://designwithsilverlight.com/2008/04/07/silverlight-drumpad-v2/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
