Silverlight SDK for Microsoft Bing
How To Implement Paging

While paging is often an optional consideration in many applications, it is absolutely essential for consuming the Bing API. The SearchEnvironment singleton provides properties and behavior for implementing paging in your Silverlight applications which make data binding, and page navigation much easier.

To Implement Paging in a Silverlight User Interface
  1. Implement a pager in the user interface

    This example draws the Xaml directly from the Bing SDK sample User Control (Page.xaml). It uses the Toolbar control from the System.Windows.Controls.Views.Toolkit framework. Notice that there is a button for paging to the first page, and for paging to the previous page, but only a button for paging to the next page - there is no page to the last page button. This is due to the fact that page counts will be approximations more often than not, and as such no accurate last page can be calculated.

    In between each of the page navigation buttons are buttons for navigation to numeric pages. These will have their numeral display dynamically set as a TextBlock, and will rotate as a moving window of page numbers as trhe user pages through the search results.

    Example
    CopyC#
    <views:Toolbar x:Name="Pager" Width="Auto" HorizontalAlignment="Center" Background="Transparent" BorderBrush="Transparent" Grid.Column="1" Visibility="Collapsed" CornerRadius="4,4,0,0">
        <views:ToolbarButton x:Name="PageFirst" Value="First"/>
        <views:ToolbarButton x:Name="PageBack" Value="Back"/>
        <views:ToolbarButton x:Name="Page1" GroupName="Page"/>
        <views:ToolbarButton x:Name="Page2" GroupName="Page"/>
        <views:ToolbarButton x:Name="Page3" GroupName="Page"/>
        <views:ToolbarButton x:Name="Page4" GroupName="Page"/>
        <views:ToolbarButton x:Name="Page5" GroupName="Page"/>
        <views:ToolbarButton x:Name="PageNext" Value="Next"/>
    </views:Toolbar>
  2. Bind the Paging State when a Search Completes

    Back in our user control implementation file (Page.xaml.cs), we had bound to the SearchEnvironment event called SearchCompleted. This event fires when a search completes successfully. Note that the Pager control shown above was set to be invisible by default. Now, let's examine the event handler for SearchCompleted:

    Here we are setting the text and visibility of a TextBlock which displays the result count, and the page counts respectively.

    Then we enter a loop wherein the dynamic page numerals are set as string literals, based on a range of possible page index values. Each button is also hidden or shown based on whether its assigned page index is within the valid page range.

    Example
    CopyC#
      //The method we are interested in showing is the call to SetPagingState...
    protected virtual void OnSearchCompleted(object sender, SearchResponseEventArgs e)
    {
        SetPagingState();
        ViewHost.ShowProgress(false);
    }
    
    //Here is the implementation of SetPagingState...
    protected virtual void SetPagingState()
    {
        ResultCountLabel.Text = String.Format(SystemResources.FMT_SEARCH_RESULT_COUNT, SearchEnvironment.Default.ResultCount, SearchEnvironment.Default.QueryTimeElapsed.Seconds, SearchEnvironment.Default.QueryTimeElapsed.Milliseconds);
        PageCountLabel.Text = String.Format(SystemResources.FMT_SEARCH_PAGE_COUNT, SearchEnvironment.Default.CurrentPage, SearchEnvironment.Default.PageCount);
        PageCountLabel.Visibility = ResultCountLabel.Visibility = Pager.Visibility = (SearchEnvironment.Default.ResultCount > 0 ? Visibility.Visible : Visibility.Collapsed);
        NoResultsLabel.Visibility = (SearchEnvironment.Default.ResultCount == 0 ? Visibility.Visible : Visibility.Collapsed);
    
        for (int index = 0; index < pageButtons.Count; index++)
        {
            long pageIndex = index + SearchEnvironment.Default.CurrentPage;
            pageButtons[index].Visibility = (pageIndex <= SearchEnvironment.Default.PageCount ? Visibility.Visible : Visibility.Collapsed);
            pageButtons[index].Content = pageIndex.ToString();
            pageButtons[index].Value = pageIndex;
            pageButtons[index].IsPressed = (SearchEnvironment.Default.CurrentPage == pageIndex);
        }
    }
  3. Navigating to a Given Page

    Now, all that is lacking is to navigate to a given page based on the user clicking the paging buttons.

    Example
    CopyC#
      //In the constructor for the Page class, we have the following event binding for the Pager toolbar...
      Pager.ButtonClicked += new EventHandler<ToolbarButtonEventArgs>(OnPagerButtonClicked);
    
    //Here is the implementation of the event handler, OnPagerButtonClicked...
    //Notice that SearchEnvironment provides all the methods you need to page with a single method call.
    void OnPagerButtonClicked(object sender, ToolbarButtonEventArgs e)
    {
        if (e.Button != null)
        {
            if (e.Button.Value != null && String.Compare(e.Button.Value.ToString(), "First") == 0)
            {
                SearchEnvironment.Default.PageFirst();
            }
            else if (e.Button.Value != null && String.Compare(e.Button.Value.ToString(), "Back") == 0)
            {
                SearchEnvironment.Default.PageBack();
            }
            else if (e.Button.Value != null && String.Compare(e.Button.Value.ToString(), "Next") == 0)
            {
                SearchEnvironment.Default.PageNext();
            }
            else if (e.Button.Value is long)
            {
                long pageIndex = (long)e.Button.Value;
                SearchEnvironment.Default.PageTo((uint)pageIndex);
            }
        }
    }