It might be a surprise to see me (The Fattest) writing about Silverlight, but I have had some fun playing around with it recently. So I decided I would write up a quick tutorial on how to build a Silverlight widget that shows the last five tweets (messages) from twitter. Now be forewarned I am not a C# expert, two other people at SOTC are, nor am I a Silverlight expert. I do however really enjoy playing around on twitter (The Fattest's Twitter Account) and with RIAs so I think I am qualified enough. :)
The widget is over on the left to check out. There really isn't much to it as Twitter is pretty simple at its core. If you can't see it you need to install Silverlight - and fyi, there have been some problems with the Silverlight 2 beta and the Firefox 3 betas/release candidates, so consider yourself forewarned. Couple items to note, when pulling in the messages I use xml and only used the text of the message and the date. The interface is very simple, I used a simple text block and list to display the messages.
Before continuing on I think I should talk about one of the issues I had when creating this little application. It is something I should have thought about more having some knowledge of Flash, but Silverlight has a particular way it allows cross-domain access - not unlike the Flash player. Anyway I really got stuck on this because Twitter doesn't have a free for all cross-domain access file. I found the solution, however, on the web when I ran across using Yahoo Pipes (which is almost a proxy). Check out Jonas's piece in the References and Resources section for more details. Also note that when using Yahoo Pipes as a proxy for cross-domain talk you have to use pipes.yahooapis.com instead of the typical pipes.yahoo.com because yahooapis.com has the crossdomain.xml file setup. I will, however, tip my hat to Silverlight for being able to use Flash's crossdomain.xml file along with its own.
I am not going to go into super depth on any of the particulars of the code, but I am open to questions on any specific pieces so feel free to speak up if you are having any issues. After creating the application in Visual Studio 08, I opened up the page.xaml and started working from there, leaving app.xaml and app.xaml.cs alone. The first piece of code we are going to look at is the XAML code for the interface. Take a look at the code below.
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="200" Height="350" Loaded="UserControl_Loaded">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Zwigby's Tweets" Margin="10,2,0,0" />
<ListBox x:Name="TweetList" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock FontSize="11" Text="{Binding Message}"
Width="185" Margin="5,0,0,0" TextWrapping="Wrap" />
<TextBlock FontSize="9" Text="{Binding Time}" Margin="5,0,0,0" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
Starting from the top you will see that there is a normal UserControl tag, I have however hooked into the Loaded event - which will be handled in the page.xaml.cs code file. Next up is the default Grid, which I add a couple of rows to. The first RowDefinition I add has a height of 25 and the second has a height of "*" - meaning fill the rest of the vertical space. All this is pretty standard XAML.
The next two items are actual controls that I have added. The first is a simple TextBlock. This just has some margin set and the text set. The second control is a ListBox which is going to hold the tweets. I am going to ignore the ItemTemplate for now but we will come back to it.
Let's now take a look at the code behind for this XAML, page.xaml.cs. Here is where we are going to get our data, parse it, and add it to the list box. First thing up is setting up the UserControl_Loaded method which handles the Loaded event mentioned earlier. This method is going to use a WebClient to make an asynchronous web request to yahoo pipes for my twitter feed. In order to handle the response I need to add an event handler to the DownloadStringCompleted event on the WebClient. The code for the method follows.
{
string twitterUrl = @"http://pipes.yahooapis.com/......";
WebClient twitterService = new WebClient();
twitterService.DownloadStringCompleted +=
new DownloadStringCompletedEventHandler(twitter_response);
twitterService.DownloadStringAsync(new Uri(twitterUrl));
}
From here I need to handle the response in the method twitter_response. I don't do a lot in the method but I do check to make sure there wasn't an error in the request and then if not I call another method that will parse the feed and set the source of the list.
DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
displayTweets(e.Result);
}
}
On to displayTweets which does all the fun stuff. Below is code for the method. It uses LINQ for retrieving the tweets from the feed, you can learn more on LINQ from our Intro to LINQ Tutorial. I also had to do some date parsing mojo to get it to parse the feed publish dates correctly - it seems that DateTime.ParseExact did not really want to parse the rfc1123 date spec exactly.
{
XDocument xmlTweets = XDocument.Parse(xmlContent);
var tweets =
from tweet in xmlTweets.Descendants("item")
select new Tweet
{
//Cutting off "Zwigby:" with Substring
Message =
((string)tweet.Element("description")).Substring(8),
//Parsing the publish date
Time =
DateTime.ParseExact(
((string)tweet.Element("pubDate")),
"ddd, dd MMM yyyy HH:mm:ss PDT",
null)
};
TweetList.ItemsSource = tweets;
}
You will notice after grabbing the item descendants from the feed I create a new Tweet using a couple of elements from the feed. The Tweet class can be seen below and simply has two properties for the message: text and time. I used automatic properties to reduce the code needed in the class. The final thing done is setting the ItemsSource of the list box to the tweets built from the feed.
{
public class Tweet
{
public string Message { get; set; }
public DateTime Time { get; set; }
}
}
The final thing we need to do is take a look at the XAML ItemTemplate for the list box. The item template holds a DataTemplate for describing how the items should look in the list. My template is very simple having a StackPanel to line up two TextBlocks vertically. The first text block has a few properties set to make it look nice and also has the Text property bound the Message property of the item being shown. The second block has much of the same except that the text is bound to the Time property of the current Tweet. I think that sums up all the code. You can grab all the source code and VS2008 projects - one project for the silverlight application and one for the web app to test/debug it.
I would also like to point out that Silverlight 2 is much easier to deploy than Silverlight 1 with the added ability of only needing to use an <object> html tag to embed the application. I remember that The Reddest had to run through an huge rigmarole to get an application to even show up in the browser for the previous version of Silverlight.
Well, that's it for this installment of "Tutorials from The Fattest", I hope everyone learned something from this tutorial. If you are interested in learning some more in depth Silverlight stuff check out some of the references and resources below. As always feel free to leave a question, praise, or criticism below.
07/05/2008 - 01:03
I am getting an error of xamlReader.Load() doesnot support for x:Class
Add Comment
[language] [/language]
Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]
See here for supported languages.
Javascript must be enabled to submit anonymous comments - or you can login.