I've been playing with porting Flotzam to Silverlight 1.0 and have an intial prototype working.  (Emphasis on prototype -- read, not ready for primetime yet.  If anyone wants to help fix some of the bugs listed below let me know.) I figured I'd share it out nonetheless.  You can see it running here and download the source here. 

I'm pretty excited by the prospect of the architecture I've put together.  The crux is that I've created a serverside templating infrastructure that's compliant with WPF's XML Databinding syntax. My goals were to reuse as much of the WPF model as possbile, but on the server.

I initially went down a path of actually instantiating WPF on the server, but pulled back from that for a couple reasons.  First, and most importantly, WPF wants to be in a Single Threaded Apartment (STA).  One can force this to happen by adding the ASPCOMPAT directive to your .aspx pages, but the scalability implications are severe.  These scalability problems might be avoided by doing some multithreading, which I started to explore, but then ran out of energy. I also had some trickiness in getting the ContentPresenter to behave, which sidelined that approach as well.  (You can see my initial explorations of the architecture in the xaml.aspx file.) 

I then went down a different path, inspired by Laurence Moroney and Joshua Allen. Laurence started me off thinking about templating based on his MSDN sample that does some clever things with server side generation of XAML based on an RSS feed.  I liked where Laurence was going as did Joshua, who took this idea to the next level in a prototype he wrote that uses XMLReader and XMLWriter for doing templating. (For some reason, he never blogged about this but he hooked me up with his code, nonetheless.  Being an ex-Web data PM, he knows how to sling infosets around, which came in real handy.)  I took his code, which is a more generic templating model as opposed to Laurence's custom sample and extended it to support the WPF databinding syntax (aka {Binding XPath=/foo}), as opposed to the custom databinding syntax Joshua had come up with. 

Note on the code Joshua wrote: he has this class called MiniCache, which he uses to store elements and attribute values in a dictionary, because he was working under the constraint of SL 1.1 not having an XMLDocument or XPathNavigator.  However, as I'm running this on the server, I don't have this constraint.  A big TODO for this code is to replace his dictionary implementation with one that uses XMLNode and XPath.

Using Joshua's code with a few modifications, I was able to reuse my WPF datatemplate within Silverlight 1.0!

Here's the basic architecture:

The action begins in my global.asax, which populates the ASP.NET Application object with an initial set of content.  In datamodel.Fetch(), I grab the latest Twitter timeline and use it to generate my flotzams.

public void Fetch() { WebClient client = new WebClient(); Stream data = client.OpenRead("http://www.twitter.com/statuses/public_timeline.xml";); XmlReader twitterItems = XmlReader.Create(data); int idx = 0; while (twitterItems.ReadToFollowing("status")) { MiniCache twitterItem = new MiniCache(twitterItems.ReadSubtree()); XmlReader template = XmlReader.Create(server.MapPath("temp4.xaml")); string XamlContent = twitterItem.ProcessTemplate(template, idx.ToString()); if (null  application.Get(idx.ToString())) application.Add(idx.ToString(), XamlContent); else { application.Lock(); application[idx.ToString()] = XamlContent; application.UnLock(); } template.Close(); idx++; } twitterItems.Close(); client.Dispose(); }

The code in Fetch() is pretty darned straight forward, which is what I like about the architecture.  I'm basically just walking the nodes from the Twitter feed, merging them with my template (temp4.xaml), which came from Blend. Once I have the resulting XAML, I stick it in the Application object.

I'm not going to go into the code of the MiniCache, because the idea is that is encapsulated sufficiently so as to be black box.  However, I did do some things that customized it. In particular, I created my own syntax to pull of the equivalent of databinding functions.  You can dig into the code to see what I did.

With my application object filled with generated XAML content, I'm now ready to display it.  I do this from default.aspx, which instantiates Silverlight.  In the javascript PageLoad function I start up a timer, which makes an AJAX GET call to default2.aspx, which is where my dynamic XAML is served from:

function displayTimer(){ var webRequest = new Sys.Net.WebRequest(); webRequest.set_url("default2.aspx?tweet=" + i); webRequest.set_httpVerb("GET"); webRequest.add_completed(completedHandler); webRequest.invoke(); i = i + 1; if (i  19) i = 0; setTimeout("displayTimer()",4000) } function completedHandler(result, eventargs) { if (result.get_responseAvailable()) { var host = document.getElementById("SilverlightPlugIn"); var xaml = host.content.createFromXAML(result.get_responseData(),true); var rootElement = host.content.findName("rootElement"); rootElement.children.add(xaml); } }

When the call completes, I use the createFromXAML method to create my Canvas object, which is then inserted at the root.  Note how I pass true to the createFromXAML method so I don't have naming collisions.

The code is default2.aspx is pretty darned straight forward.  It just picks out the querystring and returns the XAML, extracting it from the application object.  And there you have it: a databinding infrastructure for Silverlight 1.0 based on WPF.

The bugs I'm still reckoning with:

--Firefox issues. It was working in Firefox and then at some point it broke.  It seems to hang on fetching the images for the Twitter avatars from http://s3.amazonaws.com.  Not sure what's going on there.  I think Firefox stopped working when I added some error handling on image retrieval.

--Refresh issues.  I can't figure out why my cache is not being updated.  I try to update it after displaying all 20 twitters, but it seems to hang to the original 20.

--TranslateTransform and RenderTransformOrigin.  I'm randomly adding these values to the Canvas, but they don't seem to be getting acknowledged by Silverlight, thus flotzams always coming in from the right to left and often landing in the same place.

The things I'd like to do:

--Pass credentials so that the data is personalized

--Add Digg, Flickr, Facebook, RSS

--Improve the MiniCache

--Show how Blend fits into this workflow