Windows Phone From Scratch #27
My first posting about Reactive Programming for Windows Phone generated some terrific comments… many of which asked (and others answered) “what is the benefit of this?”
In this second posting on the topic I’ll tackle a bit of asynchronous programming that may help to illustrate how the implementation of the observer pattern by the Reactive Programming framework can greatly simplify Windows Phone programming.
The goal of the program we’re going to write is to search for a term in Wikipedia and to display the article. To create this, open Visual Studio and create a new application called WikiSearch. Set the application and page titles, and then add a the following controls, one on top of the other:
Control | Name | Text | Width |
TextBox | Search | <blank> | Full width |
TextBlock | lblSearch | Searching for… | Full width |
TextBlock | lblProgress | Loading… | Auto |
WebBrowser | webBrowser1 | Full Width |
Set the WebBrowser to be as wide as the page, and to be as tall as possible below the TextBlocks. Set the lblProgress TextBlock’s visibility to collapsed.
The Code Behind
Before you can start writing code you need to include the two dll’s required for reactive programming in Windows Phone
- Microsoft.Phone.Reactive
- System.Observable
- Open MainPage.xaml.cs and add a using statement,
using Microsoft.Phone.Reactive;
Setting The Keys as the Observable Data Source
The premise of Reactive Programming is the Observer pattern. This involves a subject and an observer that observes the subject. In this case, we want the keyboard entries in the TextBox to serve as the subject. We do not want to react to that subject, however, until the user pauses (or stops) typing. We can do that by converting the keydown event into an an observable, and by using the Throttle extension to tell Rx.Net that you’re not interested in the data until the user takes more than half a second to enter the next key,
var keys = Observable.FromEvent<KeyEventArgs>( Search, "KeyUp" ). Throttle( TimeSpan.FromSeconds( .5 ) );
We now want to set up on Observer Subscription but we need to do that on the UI thread. When the data is usable we’ll ask the web browser to navigate to the target page.
keys.ObserveOn( Deployment.Current.Dispatcher ).Subscribe( evt => { lblSearch.Text = "Searching for ..." + Search.Text; lblProgress.Visibility = System.Windows.Visibility.Visible; webBrowser1.Navigate( new Uri( "http://en.wikipedia.org/wiki/" + Search.Text ) ); } );
Once the page is loaded we’ll turn off the progress label,
var browser = Observable.FromEvent<System.Windows.Navigation.NavigationEventArgs>( webBrowser1, "Navigated" ); browser.ObserveOn( Deployment.Current.Dispatcher ).Subscribe( evt => lblProgress.Visibility = System.Windows.Visibility.Collapsed );
The three key points to walk away with are
- Reactive Programming is a Push model rather than an “ask for” model
- Reactive Programming follows the Observer Pattern
- Reactive Programming shows its true value with asynchronous event handling
Here is the complete code-behind (for context):
using System; using System.Windows; using System.Windows.Input; using Microsoft.Phone.Controls; using Microsoft.Phone.Reactive; namespace WikiSearch { public partial class MainPage : PhoneApplicationPage { public MainPage() { InitializeComponent(); var keys = Observable.FromEvent<KeyEventArgs>( Search, "KeyUp" ).Throttle( TimeSpan.FromSeconds( .5 ) ); keys.ObserveOn( Deployment.Current.Dispatcher ).Subscribe( evt => { lblSearch.Text = "Searching for ..." + Search.Text; lblProgress.Visibility = System.Windows.Visibility.Visible; webBrowser1.Navigate( new Uri( "http://en.wikipedia.org/wiki/" + Search.Text ) ); } ); var browser = Observable.FromEvent<System.Windows.Navigation.NavigationEventArgs>( webBrowser1, "Navigated" ); browser.ObserveOn( Deployment.Current.Dispatcher ).Subscribe( evt => lblProgress.Visibility = System.Windows.Visibility.Collapsed ); } } }
5 Responses to Rx–Reactive Programming for Windows Phone