This is Part 3 in a series covering how the Xbox Gamercard application was made using Silverlight 2. In this part I will cover how the interface is updated once the data is retrieved.
In the first part of the series I showed a few highlights of how the UI was created. In the second part, I showed the call to the web service and how the results were parsed using LINQ to create a .NET object. In this part, I will show how an instance of the custom XboxInfo class is used as the data source for Data Binding the UI Elements.
Data Binding
Returning to the parsing code from part 2, the web service results are returned as a string which is handed to a parsing method. Within the method an XDocument is created that a LINQ query is run against that returns an XboxInfo class instance. The DataContext is then set to the instance and this is where the Data binding magic begins.
XDocument xDoc = XDocument.Parse(xmlContent);
XboxInfo gamer = ...//LINQ query
this.DataContext = gamer;
In the above code, this is referring to an instance of my XboxGamerCard.Page class which is the UserControl used as the main or RootVisual control of the application. This class is where the main UI is declared in XAML including the main Grid control from Part 1. Rather than writing the familiar manual lnkGamerTag.Text = gamer.GamerTag type code we can use Data Binding to update the UI.
A simple example of the binding is shown below. The Content property of the HyperlinkButton is set to a GamerTag property of the DataContext. Once the DataContext of the UserControl is set, the Bindings are notified and the values are updated. In the case of the Binding below, the DataContext is checked for a GamerTag property. If it exists the value of the HyperlinkButton.Content property is set automatically to the GamerTag value. If the DataContext GamerTag property were to change again, the Content property would be updated as well. The target property and the data source are now connected via the Binding instance.
Another interesting feature of Data Binding is converting values. The screenshot of the Gamercard to the right shows four green lights indicating that the status of this Quemark person is online rather than offline, which is indicated by a single red light.
Using the Binding syntax below, the Canvas.Visibility property is bound to the StatusText property and a custom converter is set. Notice in the syntax, that StatusText is preceded by PresenceInfo. A property of the XboxInfo class, PresenceInfo is a custom class as well with a string property titled StatusText. With the "." notation you can navigate the property chain.
The StatusText property is a string but the Visibility property is an enum of type System.Windows.Visibility. By implementing the IValueConverter the custom converter class can be used to check a string value and return a Visibility enum value. The code is simple to write and looks like the following:
public class StatusVisiblity : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string statusText = (string)value;
if (statusText == "Offline")
{
return Visibility.Collapsed;
}
else
{
return Visibility.Visible;
}
}
}
One other interesting area is RecentGames, a property of the XboxInfo class of type List. In order to show this collection, The RecentGames property is used as the datasource for an ItemsSource property of ItemsControl added to the page. When bound, each item in the collection is shown using the the defined ItemTemplate where Binding are defined using the properties of the XboxUserGameInfo class.
...
...
Databinding can be very useful and is definitely worth looking more into. Not only does it save the developer some lines of code, it can also be useful during design-time due to the Data Binding support within Expression Blend. That sounds like another blog post in the works...
For more information on Data Binding check out Jesse Liberty's Data Binding Tutorial.
Refreshing the Data
The last piece I am going to talk about covers browser integration. The Gamercard Script Builder page (pictured to the right), has a textbox where you enter your Gamertag and when you TAB out of it the embed script is added to the textarea below. In addition the Gamercard application to the right is updated and you see a preview of what your card will look like.
Due to the awesome browser integration available in Silverlight 2 this was very simple to do. The first step is to expose the RequestGamerXml method (explained in Part 2) to JavaScript which is done by adding an attribute to the public method and registering the class instance as a ScriptableObject.
[ScriptableMember]
public void RequestGamerXml(string gamerTag){...}
void Page_Loaded(object sender, RoutedEventArgs e)
{
HtmlPage.RegisterScriptableObject("GamerCard", this);
}
Then in the JavaScript function call into that object and pass a variable to the exposed method. slPlugIn is the id of the object tag used to instantiate the Silverlight application.
And that's it! Now every time the Gamertag entered changes, the RequestGamerXml method is called and the DataContext is reset. Thanks to the Bindings in place the interface Elements are updated to stay in synch with the data source.
For more information on browser integration try the Browser Integration Hands-on Lab from MIX08.
Conclusion
This was a fun project and the ideas keep on coming. Expect to see more in the future from the Xbox Friends Watch Lab.
Other parts in this series are available:
Building the Gamercard Part 1, Composing the UI Building the Gamercard Part 2, Retrieving the Data
silverlight+databinding, silverlight